diff --git a/.github/guides/HARDDELETES.md b/.github/guides/HARDDELETES.md index cc7bf301d7d..cb23500a84e 100644 --- a/.github/guides/HARDDELETES.md +++ b/.github/guides/HARDDELETES.md @@ -98,6 +98,7 @@ The BYOND reference has a list [Here](https://secure.byond.com/docs/ref/#/DM/gar - Is on the map (always true for turfs) - Inside another atom's contents - Inside an atom's vis_contents +- Has its overlays/underlays/vis_contents/vis_locs/contents list held by something - A temporary value in a still-running proc - Is a mob with a key - Is an image object attached to an atom diff --git a/.github/workflows/auto_changelog.yml b/.github/workflows/auto_changelog.yml index 4a1df80d505..d8b18e06747 100644 --- a/.github/workflows/auto_changelog.yml +++ b/.github/workflows/auto_changelog.yml @@ -18,7 +18,7 @@ jobs: - name: Generate App Token id: app-token-generation - uses: actions/create-github-app-token@v3.1.1 + uses: actions/create-github-app-token@v3.2.0 if: env.APP_PRIVATE_KEY != '' && env.APP_ID != '' with: client-id: ${{ secrets.APP_ID }} diff --git a/.github/workflows/compile_changelogs.yml b/.github/workflows/compile_changelogs.yml index abc8d75eba5..bc27995e7c5 100644 --- a/.github/workflows/compile_changelogs.yml +++ b/.github/workflows/compile_changelogs.yml @@ -56,7 +56,7 @@ jobs: - name: Generate App Token id: app-token-generation - uses: actions/create-github-app-token@v3.1.1 + uses: actions/create-github-app-token@v3.2.0 if: env.APP_PRIVATE_KEY != '' && env.APP_ID != '' with: client-id: ${{ secrets.APP_ID }} diff --git a/.github/workflows/discord_discussions.yml b/.github/workflows/discord_discussions.yml index ec1b243d161..2d7a02dd587 100644 --- a/.github/workflows/discord_discussions.yml +++ b/.github/workflows/discord_discussions.yml @@ -41,7 +41,7 @@ jobs: - name: Generate App Token id: app-token-generation - uses: actions/create-github-app-token@v3.1.1 + uses: actions/create-github-app-token@v3.2.0 if: env.APP_PRIVATE_KEY != '' && env.APP_ID != '' with: client-id: ${{ secrets.APP_ID }} diff --git a/.github/workflows/discord_pr_announce.yml b/.github/workflows/discord_pr_announce.yml index ebaaa85d560..a24f8bb2b77 100644 --- a/.github/workflows/discord_pr_announce.yml +++ b/.github/workflows/discord_pr_announce.yml @@ -16,7 +16,7 @@ jobs: if [ -n "$ENABLER_SECRET" ]; then SECRET_EXISTS=true ; fi echo "SECRETS_ENABLED=$SECRET_EXISTS" >> $GITHUB_OUTPUT - name: Send Discord notification - uses: tgstation/discord-notify@v3 + uses: tgstation/discord-notify@main if: > steps.secrets_set.outputs.SECRETS_ENABLED && (github.event.pull_request.merged == true || github.event.action == 'opened') && diff --git a/.github/workflows/generate_client_storage.yml b/.github/workflows/generate_client_storage.yml index 141cf217093..18129481066 100644 --- a/.github/workflows/generate_client_storage.yml +++ b/.github/workflows/generate_client_storage.yml @@ -14,7 +14,7 @@ jobs: steps: - name: Generate App Token id: app-token-generation - uses: actions/create-github-app-token@v3.1.1 + uses: actions/create-github-app-token@v3.2.0 if: env.APP_PRIVATE_KEY != '' && env.APP_ID != '' with: client-id: ${{ secrets.APP_ID }} diff --git a/.github/workflows/run_linters.yml b/.github/workflows/run_linters.yml index 622239883bd..7fc32f695e1 100644 --- a/.github/workflows/run_linters.yml +++ b/.github/workflows/run_linters.yml @@ -43,7 +43,7 @@ jobs: with: dotnet-version: 9.x - name: Install OpenDream - uses: robinraju/release-downloader@616444d935c04e4269e694a274bd94383479ecde + uses: robinraju/release-downloader@v1.13 with: repository: "OpenDreamProject/OpenDream" tag: "latest" diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 7e7151a6297..f4878ea941c 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -35,9 +35,11 @@ jobs: - name: Filter staled pull requests for announcement id: filter-prs uses: actions/github-script@v9 + env: + input: ${{steps.stale.outputs.staled-issues-prs}} with: script: | - return JSON.parse(`${{steps.stale.outputs.staled-issues-prs}}`) + return JSON.parse(process.env.input) .filter(issue => !!issue.pull_request) .map(pr => ({ title: pr.title, @@ -62,7 +64,7 @@ jobs: if [ -n "$ENABLER_SECRET" ]; then SECRET_EXISTS=true ; fi echo "SECRETS_ENABLED=$SECRET_EXISTS" >> $GITHUB_OUTPUT - name: Send Discord notification - uses: tgstation/discord-notify@v3 + uses: tgstation/discord-notify@main if: > steps.secrets_set.outputs.SECRETS_ENABLED with: diff --git a/.github/workflows/update_tgs_dmapi.yml b/.github/workflows/update_tgs_dmapi.yml index 5ee9fed6acf..f5e444634bb 100644 --- a/.github/workflows/update_tgs_dmapi.yml +++ b/.github/workflows/update_tgs_dmapi.yml @@ -40,7 +40,7 @@ jobs: - name: Generate App Token id: app-token-generation - uses: actions/create-github-app-token@v3.1.1 + uses: actions/create-github-app-token@v3.2.0 if: env.APP_PRIVATE_KEY != '' && env.APP_ID != '' with: client-id: ${{ secrets.APP_ID }} diff --git a/_maps/RandomRuins/AnywhereRuins/shoe_factory.dmm b/_maps/RandomRuins/AnywhereRuins/shoe_factory.dmm new file mode 100644 index 00000000000..6bc24120e0b --- /dev/null +++ b/_maps/RandomRuins/AnywhereRuins/shoe_factory.dmm @@ -0,0 +1,1465 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"af" = ( +/obj/structure/disposalpipe/trunk{ + dir = 2 + }, +/obj/structure/disposaloutlet{ + dir = 1 + }, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"aW" = ( +/obj/structure/sign/poster/official/safety_eye_protection/directional/south, +/turf/open/floor/plating/rust, +/area/ruin/shoe_factory) +"bl" = ( +/obj/effect/spawner/random/vending/colavend, +/turf/open/floor/wood, +/area/ruin/shoe_factory) +"bQ" = ( +/obj/machinery/conveyor{ + dir = 4; + id = "shoe_factory" + }, +/obj/structure/plasticflaps/opaque, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"bV" = ( +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"cf" = ( +/obj/effect/turf_decal/loading_area{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"cg" = ( +/obj/structure/table, +/obj/effect/spawner/random/decoration/ornament, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"ck" = ( +/obj/effect/spawner/random/vending/snackvend, +/turf/open/floor/wood, +/area/ruin/shoe_factory) +"cq" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/spawner/random/trash/graffiti{ + spawn_loot_chance = 50 + }, +/turf/open/floor/wood, +/area/ruin/shoe_factory) +"cL" = ( +/obj/structure/girder, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"da" = ( +/turf/open/floor/plating/rust, +/area/ruin/shoe_factory) +"dj" = ( +/obj/machinery/conveyor{ + dir = 5; + id = "shoe_factory" + }, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"dt" = ( +/obj/machinery/conveyor/inverted{ + dir = 9; + id = "shoe_factory" + }, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"dx" = ( +/turf/closed/wall, +/area/ruin/shoe_factory) +"dy" = ( +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"dz" = ( +/obj/effect/spawner/random/trash/garbage{ + spawn_loot_count = 3; + spawn_scatter_radius = 1 + }, +/obj/structure/cable, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"dE" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"dF" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 4 + }, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"dX" = ( +/obj/structure/closet/crate, +/obj/item/stack/sheet/hairlesshide, +/obj/item/stack/sheet/hairlesshide, +/obj/item/stack/sheet/hairlesshide, +/obj/item/stack/sheet/leather/five, +/obj/item/stack/sheet/leather/five, +/obj/item/stack/sheet/leather/five, +/obj/machinery/light/small/burned/directional/north, +/turf/open/floor/plating/rust, +/area/ruin/shoe_factory) +"fh" = ( +/obj/structure/girder, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"gm" = ( +/obj/machinery/light/small/dim/directional/east, +/obj/item/stack/sheet/cardboard/fifty, +/obj/structure/rack, +/obj/item/stack/package_wrap, +/turf/open/floor/plating/rust, +/area/ruin/shoe_factory) +"gn" = ( +/obj/machinery/door/airlock/external/ruin, +/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{ + cycle_id = "shoe_factory_entrance" + }, +/obj/structure/barricade/wooden/crude, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"iT" = ( +/obj/effect/spawner/random/trash/graffiti{ + pixel_x = -32; + spawn_loot_chance = 50 + }, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"jf" = ( +/obj/structure/closet/cardboard, +/obj/effect/turf_decal/delivery, +/obj/effect/spawner/random/mining_loot/shoe_factory{ + spawn_loot_count = 1; + spawn_scatter_radius = 0; + spawn_random_offset = 0 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/plating/rust, +/area/ruin/shoe_factory) +"jF" = ( +/obj/machinery/space_heater, +/obj/machinery/light/small/dim/directional/north, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"jI" = ( +/obj/item/chair, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"jQ" = ( +/obj/structure/sign/warning, +/turf/closed/wall, +/area/ruin/shoe_factory) +"jS" = ( +/obj/machinery/portable_atmospherics/canister/air, +/turf/open/floor/plating/rust, +/area/ruin/shoe_factory) +"kJ" = ( +/obj/machinery/light/small/dim/directional/north, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"ld" = ( +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/obj/structure/railing{ + dir = 1 + }, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"le" = ( +/obj/structure/table, +/obj/item/paper_bin, +/obj/item/pen, +/obj/structure/noticeboard/directional/east, +/obj/item/paper/fluff/ruins/shoe_factory/osha_shutdown, +/turf/open/floor/iron, +/area/ruin/shoe_factory) +"lk" = ( +/obj/structure/railing{ + dir = 8 + }, +/turf/open/floor/plating/rust, +/area/ruin/shoe_factory) +"mu" = ( +/obj/machinery/power/port_gen/pacman, +/obj/item/wrench, +/obj/item/stack/sheet/mineral/plasma/thirty, +/obj/machinery/power/apc/auto_name/directional/north, +/obj/structure/cable, +/obj/effect/mapping_helpers/apc/unlocked, +/obj/effect/mapping_helpers/apc/no_charge, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"mM" = ( +/obj/machinery/button/door/directional/south{ + id = "shoe_warehouse"; + name = "Warehouse Shutters Control" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"ny" = ( +/obj/structure/table, +/obj/item/storage/toolbox/mechanical{ + pixel_x = -2; + pixel_y = 8 + }, +/obj/effect/spawner/random/engineering/flashlight, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"nH" = ( +/obj/structure/loom, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"nJ" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 4 + }, +/obj/effect/spawner/random/trash/graffiti{ + spawn_loot_chance = 50 + }, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"ot" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"oU" = ( +/obj/machinery/door/airlock/external/ruin, +/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{ + cycle_id = "shoe_factory_entrance" + }, +/obj/effect/mapping_helpers/airlock_note_placer, +/obj/item/paper/fluff/ruins/shoe_factory/osha_shutdown, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"pT" = ( +/turf/closed/wall{ + baseturfs = /turf/open/floor/plating/lavaland_baseturf + }, +/area/ruin/shoe_factory) +"qe" = ( +/obj/structure/table, +/obj/item/plate/large, +/obj/item/kitchen/fork, +/obj/machinery/computer/security/telescreen/entertainment/directional/north, +/turf/open/floor/wood, +/area/ruin/shoe_factory) +"qm" = ( +/obj/effect/mapping_helpers/broken_floor, +/obj/item/chair, +/turf/open/floor/wood, +/area/ruin/shoe_factory) +"qA" = ( +/obj/structure/kitchenspike, +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"ra" = ( +/obj/machinery/airalarm/directional/west, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating/rust, +/area/ruin/shoe_factory) +"rt" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 1 + }, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"rW" = ( +/obj/effect/mapping_helpers/burnt_floor, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"sT" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"tf" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/siding/white{ + dir = 8 + }, +/obj/machinery/door/airlock{ + name = "Restroom" + }, +/turf/open/floor/iron/freezer, +/area/ruin/shoe_factory) +"tk" = ( +/obj/effect/decal/cleanable/dirt, +/obj/item/light/bulb/broken, +/obj/machinery/light/small/empty/directional/south, +/turf/open/floor/plating/rust, +/area/ruin/shoe_factory) +"tz" = ( +/obj/structure/closet/crate/bin, +/obj/effect/spawner/random/trash/garbage, +/obj/effect/spawner/random/trash/garbage, +/turf/open/floor/wood, +/area/ruin/shoe_factory) +"ur" = ( +/turf/open/floor/wood, +/area/ruin/shoe_factory) +"uC" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/sign/poster/official/cleanliness/directional/east, +/obj/structure/sink/kitchen/directional/west, +/obj/machinery/light/small/directional/south, +/obj/effect/spawner/random/trash/graffiti{ + pixel_y = -32; + spawn_loot_chance = 50 + }, +/turf/open/floor/iron/freezer, +/area/ruin/shoe_factory) +"uV" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/barricade/wooden/crude, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"vO" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/spawner/random/trash/graffiti{ + pixel_x = -32; + spawn_loot_chance = 50 + }, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"wv" = ( +/obj/structure/closet/cardboard, +/obj/effect/turf_decal/delivery, +/obj/effect/spawner/random/mining_loot/shoe_factory{ + spawn_loot_count = 1; + spawn_scatter_radius = 0; + spawn_random_offset = 0 + }, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"wQ" = ( +/obj/effect/spawner/random/trash/garbage{ + spawn_scatter_radius = 1 + }, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"xd" = ( +/obj/structure/closet/crate/wooden, +/obj/item/stack/sheet/cotton/durathread{ + amount = 50 + }, +/obj/item/stack/sheet/cotton{ + amount = 50 + }, +/obj/item/stack/sheet/cotton/wool{ + amount = 50 + }, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"xt" = ( +/obj/machinery/door/airlock/glass{ + name = "Break Room" + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"xM" = ( +/obj/effect/turf_decal/trimline/brown/filled/corner, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"xW" = ( +/obj/structure/closet/crate/cardboard, +/obj/effect/turf_decal/delivery, +/obj/effect/decal/cleanable/dirt, +/obj/effect/spawner/random/mining_loot/shoe_factory{ + spawn_loot_count = 1; + spawn_scatter_radius = 0; + spawn_random_offset = 0 + }, +/turf/open/floor/plating/rust, +/area/ruin/shoe_factory) +"xZ" = ( +/obj/machinery/button/door/directional/south{ + id = "shoe_warehouse"; + name = "Warehouse Shutters Control" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/spawner/random/trash/graffiti{ + spawn_loot_chance = 50 + }, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"yO" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/sign/poster/official/safety_eye_protection/directional/north, +/turf/open/floor/plating/rust, +/area/ruin/shoe_factory) +"yZ" = ( +/obj/structure/filingcabinet, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"zg" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"zs" = ( +/obj/machinery/smartfridge/drying/rack, +/turf/open/floor/plating/rust, +/area/ruin/shoe_factory) +"zw" = ( +/obj/structure/grille/broken, +/turf/open/floor/plating/rust, +/area/ruin/shoe_factory) +"zx" = ( +/obj/effect/turf_decal/trimline/brown/filled/line, +/obj/effect/decal/cleanable/dirt, +/obj/effect/spawner/random/trash/graffiti{ + pixel_y = -32; + spawn_loot_chance = 50 + }, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"zE" = ( +/obj/structure/closet/crate/freezer, +/obj/item/stack/sheet/animalhide/corgi, +/obj/item/stack/sheet/animalhide/cat, +/obj/item/stack/sheet/animalhide/carbon/monkey, +/obj/item/stack/sheet/animalhide/carbon/lizard, +/obj/item/stack/sheet/animalhide/carbon/human, +/obj/item/stack/sheet/animalhide/bear, +/turf/open/floor/plating/rust, +/area/ruin/shoe_factory) +"zF" = ( +/obj/effect/turf_decal/trimline/brown/filled/line, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"zS" = ( +/obj/effect/spawner/random/trash/graffiti{ + spawn_loot_chance = 50 + }, +/turf/closed/wall/rust, +/area/ruin/shoe_factory) +"Ad" = ( +/obj/effect/turf_decal/trimline/brown/filled/line, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"AC" = ( +/obj/machinery/smartfridge/drying/rack, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"AM" = ( +/mob/living/basic/mouse, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"AS" = ( +/obj/item/reagent_containers/cup/bucket, +/obj/item/mop, +/obj/structure/mop_bucket, +/obj/effect/decal/cleanable/dirt, +/obj/item/storage/box/lights/mixed, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"Bj" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/spawner/random/trash/graffiti{ + pixel_y = -32; + spawn_loot_chance = 50 + }, +/turf/open/floor/plating/rust, +/area/ruin/shoe_factory) +"Bo" = ( +/mob/living/basic/mouse, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"Bq" = ( +/obj/effect/spawner/random/trash/graffiti{ + spawn_loot_chance = 50 + }, +/turf/closed/wall, +/area/ruin/shoe_factory) +"BL" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/small/broken/directional/east, +/obj/item/light/bulb/broken, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"BM" = ( +/obj/structure/rack, +/obj/item/clothing/shoes/sneakers/random, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"BW" = ( +/obj/structure/railing/corner/end, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"DI" = ( +/turf/template_noop, +/area/template_noop) +"DP" = ( +/obj/effect/spawner/structure/window, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"Es" = ( +/obj/effect/turf_decal/loading_area{ + dir = 4 + }, +/turf/open/floor/plating/rust, +/area/ruin/shoe_factory) +"EC" = ( +/obj/structure/girder, +/turf/open/floor/plating/rust, +/area/ruin/shoe_factory) +"EL" = ( +/obj/machinery/light/directional/west, +/obj/structure/extinguisher_cabinet/directional/west, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"ES" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating/rust, +/area/ruin/shoe_factory) +"Fd" = ( +/obj/structure/table, +/obj/item/clipboard, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"FS" = ( +/obj/structure/kitchenspike, +/turf/open/floor/plating/rust, +/area/ruin/shoe_factory) +"Gp" = ( +/obj/effect/turf_decal/trimline/brown/filled/line, +/obj/effect/spawner/random/trash/graffiti{ + spawn_loot_chance = 50 + }, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"Gz" = ( +/obj/machinery/door/airlock/maintenance, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"GH" = ( +/obj/machinery/door/poddoor/shutters{ + name = "Warehouse Shutters"; + id = "shoe_warehouse" + }, +/obj/effect/turf_decal/caution, +/turf/open/floor/plating/rust, +/area/ruin/shoe_factory) +"GV" = ( +/obj/structure/extinguisher_cabinet/directional/south, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"GX" = ( +/obj/structure/chair{ + pixel_y = -2 + }, +/turf/open/floor/plating/rust, +/area/ruin/shoe_factory) +"HK" = ( +/obj/machinery/digital_clock/directional/north, +/obj/item/kirbyplants/random, +/turf/open/floor/wood, +/area/ruin/shoe_factory) +"HL" = ( +/obj/effect/turf_decal/trimline/brown/filled/corner{ + dir = 4 + }, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"HV" = ( +/obj/item/hand_labeler, +/obj/item/hand_labeler_refill, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/plating/rust, +/area/ruin/shoe_factory) +"Id" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/small/dim/directional/east, +/turf/open/floor/plating/rust, +/area/ruin/shoe_factory) +"IG" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"JW" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"Kk" = ( +/obj/structure/closet/crate/cardboard, +/obj/effect/turf_decal/delivery, +/obj/effect/spawner/random/mining_loot/shoe_factory{ + spawn_loot_count = 1; + spawn_scatter_radius = 0; + spawn_random_offset = 0 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"Kq" = ( +/obj/structure/girder/displaced, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"LA" = ( +/obj/structure/sign/poster/official/work_for_a_future/directional/south, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/broken/directional/south, +/obj/item/light/tube/broken, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"LF" = ( +/obj/item/stack/sheet/cardboard/fifty, +/obj/structure/rack, +/obj/item/stack/package_wrap, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"LS" = ( +/obj/machinery/conveyor/inverted{ + dir = 10; + id = "shoe_factory" + }, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"Mj" = ( +/obj/structure/chair/office, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"MH" = ( +/obj/structure/grille, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"Nq" = ( +/obj/item/knife, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"Nr" = ( +/obj/structure/railing/corner/end{ + dir = 8 + }, +/turf/open/floor/plating/rust, +/area/ruin/shoe_factory) +"ND" = ( +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"Ob" = ( +/obj/structure/railing{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"Op" = ( +/obj/machinery/conveyor{ + dir = 6; + id = "shoe_factory" + }, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"OI" = ( +/obj/machinery/conveyor{ + id = "shoe_factory" + }, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"OR" = ( +/obj/structure/table, +/obj/machinery/coffeemaker{ + pixel_y = 5 + }, +/obj/effect/decal/cleanable/cobweb, +/turf/open/floor/wood, +/area/ruin/shoe_factory) +"PK" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plating/rust, +/area/ruin/shoe_factory) +"Re" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/spawner/random/trash/graffiti{ + pixel_y = -32; + spawn_loot_chance = 50 + }, +/obj/structure/toilet{ + pixel_y = 8; + dir = 4 + }, +/turf/open/floor/iron/freezer, +/area/ruin/shoe_factory) +"Rl" = ( +/obj/structure/sign/poster/official/do_not_question/directional/west, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating/rust, +/area/ruin/shoe_factory) +"RO" = ( +/obj/structure/sign/warning, +/turf/closed/wall/rust, +/area/ruin/shoe_factory) +"RU" = ( +/obj/structure/table, +/obj/item/reagent_containers/condiment/saltshaker{ + pixel_x = 7; + pixel_y = 9 + }, +/obj/item/reagent_containers/condiment/peppermill{ + pixel_x = 7; + pixel_y = 5 + }, +/obj/effect/spawner/random/entertainment/deck{ + pixel_x = -6 + }, +/obj/machinery/light/small/directional/north, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/wood, +/area/ruin/shoe_factory) +"SX" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 1 + }, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"Tw" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{ + cycle_id = "shoe_factory_entrance" + }, +/obj/machinery/door/airlock/external/ruin, +/obj/effect/mapping_helpers/airlock_note_placer, +/obj/item/paper/fluff/ruins/shoe_factory/osha_shutdown, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"Uk" = ( +/obj/machinery/conveyor{ + dir = 1; + id = "shoe_factory" + }, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"UL" = ( +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 1 + }, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"UV" = ( +/obj/structure/table, +/obj/machinery/microwave, +/obj/effect/spawner/random/trash/graffiti{ + pixel_x = -32; + spawn_loot_chance = 50 + }, +/turf/open/floor/wood, +/area/ruin/shoe_factory) +"Vj" = ( +/obj/structure/table, +/obj/effect/spawner/random/food_or_drink/donkpockets, +/obj/item/coffee_cartridge, +/obj/structure/sign/poster/contraband/eat/directional/west, +/turf/open/floor/wood, +/area/ruin/shoe_factory) +"VY" = ( +/obj/machinery/conveyor_switch/oneway{ + id = "shoe_factory"; + conveyor_speed = 5 + }, +/obj/effect/turf_decal/loading_area{ + dir = 4 + }, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"Wf" = ( +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"Wo" = ( +/obj/structure/railing{ + dir = 8 + }, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"Wx" = ( +/obj/machinery/disposal/delivery_chute{ + dir = 1 + }, +/obj/structure/disposalpipe/trunk{ + dir = 2 + }, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"WA" = ( +/obj/structure/railing, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"WC" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"WO" = ( +/obj/effect/mapping_helpers/broken_floor, +/turf/open/floor/wood, +/area/ruin/shoe_factory) +"Xv" = ( +/obj/effect/spawner/random/trash/graffiti{ + spawn_loot_chance = 50 + }, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"Xy" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"XN" = ( +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/spawner/random/trash/graffiti{ + pixel_y = -32; + spawn_loot_chance = 50 + }, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"XW" = ( +/obj/item/light/tube/broken, +/obj/machinery/light/empty/directional/north, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"Yr" = ( +/obj/machinery/door/poddoor/shutters{ + name = "Warehouse Shutters"; + id = "shoe_warehouse" + }, +/obj/effect/turf_decal/caution, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/iron{ + baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface + }, +/area/ruin/shoe_factory) +"YM" = ( +/turf/closed/wall/rust, +/area/ruin/shoe_factory) +"YX" = ( +/obj/effect/spawner/random/mining_loot/shoe_factory, +/obj/machinery/conveyor{ + dir = 1; + id = "shoe_factory" + }, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"YY" = ( +/obj/effect/spawner/random/mining_loot/shoe_factory, +/obj/machinery/conveyor{ + id = "shoe_factory" + }, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"Zl" = ( +/obj/structure/grille, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/ruin/shoe_factory) +"Zo" = ( +/obj/structure/chair{ + dir = 1 + }, +/turf/open/floor/wood, +/area/ruin/shoe_factory) + +(1,1,1) = {" +DI +DI +DI +DI +DI +DI +DI +DI +DI +DI +DI +DI +DI +DI +DI +DI +DI +DI +DI +"} +(2,1,1) = {" +DI +DI +DI +DI +DI +DI +DI +DI +DI +DI +DI +DI +DI +DI +DI +DI +DI +DI +DI +"} +(3,1,1) = {" +DI +DI +DI +DI +DI +DI +DI +DI +DI +DI +DI +DI +DI +YM +gn +gn +pT +DI +DI +"} +(4,1,1) = {" +DI +DI +DI +DI +DI +dx +uV +uV +Xy +YM +DI +DI +DI +pT +kJ +XN +pT +DI +DI +"} +(5,1,1) = {" +DI +DI +DI +DI +YM +dx +GX +ny +jI +dx +dx +dx +YM +EC +Tw +oU +dx +DI +DI +"} +(6,1,1) = {" +dx +YM +dx +dx +EC +Rl +Wf +sT +Wf +iT +EL +vO +da +Wf +dy +Wf +YM +dx +DI +"} +(7,1,1) = {" +dx +OR +Vj +UV +YM +Xv +xM +JW +nJ +da +dy +dF +JW +nJ +HL +ES +BM +uV +DI +"} +(8,1,1) = {" +dx +qe +qm +ur +xt +sT +zF +jQ +YM +DP +MH +DP +Kq +RO +WC +sT +BM +uV +DI +"} +(9,1,1) = {" +YM +RU +Zo +cq +dx +da +ES +YM +dj +Uk +YX +Uk +Uk +af +UL +Bo +BM +uV +DI +"} +(10,1,1) = {" +YM +HK +rW +WO +dx +XW +Bj +YM +bQ +DP +DP +DP +YM +dx +SX +LA +YM +YM +YM +"} +(11,1,1) = {" +dx +bl +tz +ck +zS +Wf +zx +dx +Op +OI +YY +OI +dt +Bq +SX +Wf +dx +Re +YM +"} +(12,1,1) = {" +dx +dx +EC +dx +YM +ES +Ad +Kq +fh +Zl +DP +DP +bQ +YM +PK +Wf +tf +uC +YM +"} +(13,1,1) = {" +DI +YM +jF +ra +Gz +sT +Gp +YM +dj +Uk +YX +Uk +LS +Bq +rt +xZ +dx +dx +dx +"} +(14,1,1) = {" +DI +dx +mu +dz +YM +YM +cL +dx +bQ +dx +YM +YM +cL +dx +Yr +GH +YM +DI +DI +"} +(15,1,1) = {" +DI +dx +jS +AS +dx +zE +ND +fh +Op +OI +YY +OI +dt +YM +ot +mM +dx +DI +DI +"} +(16,1,1) = {" +DI +dx +YM +YM +dx +dX +dE +dx +YM +DP +DP +DP +bQ +YM +IG +tk +YM +DI +DI +"} +(17,1,1) = {" +DI +DI +DI +DI +dx +xd +ND +YM +dj +Uk +YX +Uk +LS +Kq +zg +ND +YM +DI +DI +"} +(18,1,1) = {" +DI +DI +dx +dx +cL +nH +aW +dx +bQ +DP +DP +zw +dx +YM +yO +dy +dx +DI +DI +"} +(19,1,1) = {" +DI +DI +YM +zs +ND +ND +ND +WA +Op +OI +OI +OI +OI +Wx +ld +GV +dx +dx +YM +"} +(20,1,1) = {" +DI +DI +dx +FS +bV +da +da +BW +lk +cf +VY +Es +Wo +Ob +Nr +wQ +HV +yZ +YM +"} +(21,1,1) = {" +DI +DI +YM +qA +Nq +ND +wQ +ND +da +dy +AM +ND +dE +dy +dy +dE +Mj +cg +dx +"} +(22,1,1) = {" +DI +DI +dx +AC +da +BL +ND +dE +Kk +jf +gm +LF +wv +xW +da +Id +le +Fd +YM +"} +(23,1,1) = {" +DI +DI +YM +dx +YM +YM +YM +dx +dx +dx +dx +YM +dx +dx +dx +YM +dx +YM +dx +"} diff --git a/_maps/RandomRuins/IceRuins/icemoon_underground_syndidome.dmm b/_maps/RandomRuins/IceRuins/icemoon_underground_syndidome.dmm index 07e7273ca21..e520d14def6 100644 --- a/_maps/RandomRuins/IceRuins/icemoon_underground_syndidome.dmm +++ b/_maps/RandomRuins/IceRuins/icemoon_underground_syndidome.dmm @@ -1333,10 +1333,6 @@ }, /turf/open/floor/mineral/plastitanium/red, /area/ruin/syndibiodome) -"qJ" = ( -/obj/effect/turf_decal/trimline/tram/filled, -/turf/closed/indestructible/syndicate, -/area/ruin/syndibiodome) "qN" = ( /turf/closed/indestructible/syndicate, /area/ruin/syndibiodome) @@ -5086,7 +5082,7 @@ qN mW qN qN -qJ +qN qN xf oH diff --git a/_maps/RandomRuins/LavaRuins/lavaland_battle_site.dmm b/_maps/RandomRuins/LavaRuins/lavaland_battle_site.dmm index ea41e728846..d1da6074b99 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_battle_site.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_battle_site.dmm @@ -10,7 +10,7 @@ desc = "A crown that was fit for a king, looks like it didn't get them very far."; name = "dented crown" }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "g" = ( /obj/structure/water_source/puddle, @@ -19,18 +19,18 @@ "h" = ( /obj/effect/mob_spawn/corpse/human/skeleton, /obj/item/shield/buckler, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "j" = ( /turf/template_noop, /area/template_noop) "m" = ( /obj/effect/decal/cleanable/shreds, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "n" = ( /obj/structure/stone_tile/block/burnt, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "o" = ( /obj/structure/stone_tile/burnt{ @@ -41,39 +41,39 @@ }, /obj/effect/decal/cleanable/blood/drip, /mob/living/basic/mining/goliath, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "p" = ( /obj/item/stack/rods{ pixel_x = 10 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "q" = ( /obj/structure/flora/rock, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "s" = ( /mob/living/basic/mining/goliath, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "t" = ( /obj/effect/decal/cleanable/blood/gibs/old, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "u" = ( /obj/effect/decal/cleanable/blood/old, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "x" = ( /obj/effect/decal/cleanable/blood/drip, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "D" = ( /obj/structure/statue/bone/rib{ name = "colossal tailbone" }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "F" = ( /obj/effect/decal/cleanable/blood/drip, @@ -81,33 +81,33 @@ dir = 1 }, /obj/structure/statue/bone/rib, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "G" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "H" = ( /obj/structure/firepit, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "I" = ( /obj/structure/closet/crate/wooden, /obj/item/stack/sheet/animalhide/goliath_hide, /obj/item/flashlight/flare/torch, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "J" = ( /obj/structure/flora/ash/cap_shroom, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "K" = ( /obj/structure/closet/crate/wooden, /obj/item/stack/sheet/sinew, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "M" = ( /obj/structure/statue/bone/skull, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "O" = ( /obj/structure/statue/bone/rib{ @@ -116,18 +116,18 @@ /obj/structure/stone_tile/cracked{ dir = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "P" = ( /obj/effect/mob_spawn/corpse/human/skeleton, /obj/item/shovel/spade, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "S" = ( /obj/structure/chair/wood/wings{ color = "#ffff00" }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "T" = ( /obj/effect/mob_spawn/corpse/human/skeleton, @@ -135,14 +135,14 @@ pixel_x = 13; pixel_y = 12 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "U" = ( /obj/structure/statue/bone/rib, /obj/structure/stone_tile/cracked{ dir = 1 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "V" = ( /obj/effect/mob_spawn/corpse/human/skeleton, @@ -150,14 +150,14 @@ pixel_x = -1; pixel_y = -7 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "X" = ( /obj/structure/stone_tile/burnt, /obj/structure/stone_tile/burnt{ dir = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Y" = ( /obj/effect/mob_spawn/corpse/human/skeleton, @@ -165,7 +165,7 @@ pixel_y = -12; pixel_x = 2 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) (1,1,1) = {" diff --git a/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm b/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm index caf994011d8..494d435575e 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_biodome_beach.dmm @@ -260,7 +260,7 @@ /area/ruin/powered/beach) "gX" = ( /obj/machinery/atmospherics/components/unary/passive_vent/layer4, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors/explored) "hj" = ( /obj/structure/flora/tree/palm, @@ -630,7 +630,7 @@ /turf/closed/wall/mineral/wood/nonmetal, /area/ruin/powered/beach) "wL" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors/explored) "wY" = ( /turf/open/floor/pod/light, @@ -769,9 +769,6 @@ "Bn" = ( /turf/open/floor/carpet/blue, /area/ruin/powered/beach) -"Bp" = ( -/turf/closed/mineral/random/volcanic, -/area/lavaland/surface/outdoors/explored) "Bv" = ( /obj/effect/turf_decal/sand, /obj/machinery/light/directional/east, @@ -793,6 +790,10 @@ }, /turf/closed/wall/mineral/sandstone, /area/ruin/powered/beach) +"Cl" = ( +/obj/effect/spawner/random/entertainment/slot_machine, +/turf/open/floor/wood, +/area/ruin/powered/beach) "Cq" = ( /obj/structure/sign/departments/restroom/directional/east, /turf/open/floor/wood, @@ -832,6 +833,9 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer4, /turf/open/floor/wood, /area/ruin/powered/beach) +"Dh" = ( +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, +/area/lavaland/surface/outdoors/explored) "Ds" = ( /obj/structure/closet/secure_closet/freezer/kitchen/all_access, /turf/open/floor/wood, @@ -981,6 +985,9 @@ dir = 8 }, /area/ruin/powered/beach) +"Jj" = ( +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, +/area/template_noop) "Jr" = ( /turf/open/floor/carpet/purple, /area/ruin/powered/beach) @@ -1074,10 +1081,6 @@ }, /turf/closed/wall/mineral/sandstone, /area/ruin/powered/beach) -"NJ" = ( -/obj/effect/spawner/random/entertainment/slot_machine, -/turf/open/floor/wood, -/area/ruin/powered/beach) "NK" = ( /obj/machinery/grill, /turf/open/floor/wood, @@ -1409,23 +1412,20 @@ /obj/structure/curtain, /turf/open/floor/plating, /area/ruin/powered/beach) -"ZS" = ( -/turf/closed/mineral/random/volcanic, -/area/template_noop) (1,1,1) = {" aa aa aa aa -Bp -Bp -Bp -Bp +Dh +Dh +Dh +Dh wL wL wL -Bp +Dh aa aa aa @@ -1442,8 +1442,8 @@ BE BE BE yc -Bp -Bp +Dh +aa "} (2,1,1) = {" aa @@ -1451,8 +1451,8 @@ aa aa aa aa -aa -aa +Dh +Dh aj gs gs @@ -1475,16 +1475,16 @@ Df aF Fr yc -Bp +aa "} (3,1,1) = {" aa aa aa -aa -aa -aa -aa +Dh +Dh +Dh +Dh aj cg Cs @@ -1507,7 +1507,7 @@ kh aC hS cd -Bp +aa "} (4,1,1) = {" aa @@ -1539,12 +1539,12 @@ CK IJ mE CU -Bp +aa "} (5,1,1) = {" aa aj -NJ +Cl Fa xg aC @@ -1571,12 +1571,12 @@ aP Wd aj MZ -Bp +Dh "} (6,1,1) = {" aa aj -NJ +Cl Bg Ti Fa @@ -1603,7 +1603,7 @@ cE cE gF MZ -Bp +Dh "} (7,1,1) = {" aa @@ -1635,7 +1635,7 @@ uz uz lq MZ -Bp +Dh "} (8,1,1) = {" aa @@ -1667,7 +1667,7 @@ uz uz PN MZ -Bp +Dh "} (9,1,1) = {" aa @@ -1699,7 +1699,7 @@ uz uz lq MZ -Bp +Dh "} (10,1,1) = {" aa @@ -1766,7 +1766,7 @@ IP MZ "} (12,1,1) = {" -aa +Dh MZ VI VI @@ -1798,7 +1798,7 @@ Ro MZ "} (13,1,1) = {" -Bp +Dh Fr yc VI @@ -1830,7 +1830,7 @@ Ro MZ "} (14,1,1) = {" -Bp +Dh wL MZ SC @@ -1862,7 +1862,7 @@ Ro MZ "} (15,1,1) = {" -Bp +Dh gX cd VI @@ -1894,7 +1894,7 @@ EL MZ "} (16,1,1) = {" -Bp +Dh wL MZ dj @@ -1926,7 +1926,7 @@ Ro MZ "} (17,1,1) = {" -Bp +Dh wL MZ VY @@ -1958,7 +1958,7 @@ Ro MZ "} (18,1,1) = {" -Bp +Dh Zi Mf UT @@ -2114,8 +2114,8 @@ AE eA qf MZ -Bp -Bp +Dh +aa "} (23,1,1) = {" aa @@ -2147,7 +2147,7 @@ gC rO Fr yc -Bp +Dh "} (24,1,1) = {" aa @@ -2339,7 +2339,7 @@ BE CU BE Mf -Bp +aa "} (30,1,1) = {" aa @@ -2349,7 +2349,7 @@ BE BE BE Mf -ZS +Jj Fr BE BE @@ -2364,12 +2364,12 @@ Mf aj aj aj -Bp -Bp -Bp -Bp -Bp -Bp -Bp -Bp +Dh +Dh +aa +aa +aa +aa +aa +aa "} diff --git a/_maps/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm b/_maps/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm index 8b4dd1bc5d0..41e568324dc 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm @@ -441,7 +441,7 @@ name = "stealth banana peel" }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors/explored) "jw" = ( /obj/structure/disposalpipe/segment{ @@ -533,6 +533,11 @@ /obj/effect/turf_decal/tile/yellow/fourcorners, /turf/open/indestructible/permalube, /area/ruin/powered/clownplanet) +"qO" = ( +/obj/machinery/light/directional/west, +/obj/effect/mapping_helpers/no_lava, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, +/area/ruin/powered/clownplanet) "rP" = ( /obj/structure/disposalpipe/segment{ dir = 4; @@ -563,6 +568,10 @@ "ye" = ( /turf/open/lava/smooth, /area/ruin/powered/clownplanet) +"Am" = ( +/obj/effect/mapping_helpers/no_lava, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, +/area/lavaland/surface/outdoors/explored) "BO" = ( /obj/structure/disposalpipe/segment{ dir = 4; @@ -615,6 +624,11 @@ /obj/effect/turf_decal/tile/yellow/fourcorners, /turf/open/indestructible/permalube, /area/ruin/powered/clownplanet) +"Ig" = ( +/obj/machinery/light/directional/east, +/obj/effect/mapping_helpers/no_lava, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, +/area/ruin/powered/clownplanet) "JU" = ( /obj/item/bikehorn, /obj/structure/disposalpipe/segment{ @@ -739,11 +753,11 @@ aa aa aa aa -QT -QT -QT -QT -QT +Am +Am +Am +Am +Am aa aa aa @@ -772,11 +786,11 @@ cc cc cc cc -Or -QT +Ig +Am gX -QT -QT +Am +Am gX Or cc @@ -1724,11 +1738,11 @@ cc cc cc cc -Zg -QT +qO +Am gX -QT -QT +Am +Am gX Zg cc @@ -1759,11 +1773,11 @@ aa aa aa aa -QT -QT -QT -QT -QT +Am +Am +Am +Am +Am aa aa aa diff --git a/_maps/RandomRuins/LavaRuins/lavaland_strong_rock.dmm b/_maps/RandomRuins/LavaRuins/lavaland_strong_rock.dmm index ad90df10167..6956c444f01 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_strong_rock.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_strong_rock.dmm @@ -1,6 +1,7 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "a" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/obj/effect/mapping_helpers/no_lava, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/template_noop) "b" = ( /turf/closed/mineral/strong, diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm index 6bf42240c85..3d57df9235b 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm @@ -6,13 +6,13 @@ /obj/structure/stone_tile/surrounding_tile{ dir = 4 }, -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "ac" = ( /obj/structure/stone_tile/block{ dir = 1 }, -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "ad" = ( /obj/structure/stone_tile/block{ @@ -21,13 +21,13 @@ /obj/structure/stone_tile/cracked{ dir = 8 }, -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "ae" = ( /obj/structure/stone_tile/block/cracked{ dir = 1 }, -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "af" = ( /obj/structure/stone_tile/block{ @@ -36,37 +36,30 @@ /obj/structure/stone_tile{ dir = 8 }, -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "ag" = ( /obj/structure/stone_tile/surrounding_tile/cracked{ dir = 1 }, -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "ah" = ( -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "ai" = ( /obj/structure/stone_tile/surrounding_tile/cracked{ dir = 4 }, -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "aj" = ( /obj/structure/stone_tile/slab, -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "ak" = ( /turf/closed/indestructible/riveted/boss, /area/ruin/unpowered/ash_walkers) -"al" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/structure/railing/wooden_fence{ - dir = 1 - }, -/turf/open/misc/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) "aq" = ( /obj/structure/stone_tile/block/cracked{ dir = 8 @@ -74,27 +67,11 @@ /obj/structure/stone_tile/surrounding_tile/cracked{ dir = 1 }, -/turf/closed/mineral/volcanic/lava_land_surface, -/area/lavaland/surface/outdoors) -"ar" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/structure/railing/wooden_fence{ - dir = 9 - }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "as" = ( /turf/closed/wall/mineral/wood, /area/ruin/unpowered/ash_walkers) -"at" = ( -/obj/structure/stone_tile/block{ - dir = 8 - }, -/obj/structure/stone_tile/block{ - dir = 4 - }, -/turf/closed/mineral/volcanic/lava_land_surface, -/area/lavaland/surface/outdoors) "au" = ( /obj/structure/stone_tile, /obj/structure/stone_tile{ @@ -154,12 +131,6 @@ /obj/item/flashlight/flare/torch, /turf/open/indestructible/boss, /area/ruin/unpowered/ash_walkers) -"aF" = ( -/obj/structure/stone_tile/block{ - dir = 8 - }, -/turf/closed/mineral/volcanic/lava_land_surface, -/area/lavaland/surface/outdoors) "aG" = ( /obj/structure/stone_tile/block/cracked{ dir = 4 @@ -210,13 +181,7 @@ /turf/open/indestructible/boss, /area/ruin/unpowered/ash_walkers) "aR" = ( -/obj/structure/stone_tile/block{ - dir = 8 - }, -/obj/structure/stone_tile/block/cracked{ - dir = 4 - }, -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/indestructible/riveted/boss, /area/lavaland/surface/outdoors) "aS" = ( /obj/structure/stone_tile/block{ @@ -323,18 +288,11 @@ /obj/structure/stone_tile, /turf/open/indestructible/boss, /area/ruin/unpowered/ash_walkers) -"bh" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/structure/railing/wooden_fence{ - dir = 5 - }, -/turf/open/misc/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) "bi" = ( /obj/structure/stone_tile/block/cracked{ dir = 8 }, -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "bj" = ( /obj/structure/stone_tile/block/cracked{ @@ -447,7 +405,7 @@ "bx" = ( /obj/structure/stone_tile/slab/cracked, /obj/effect/decal/cleanable/blood, -/turf/open/indestructible/boss, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ash_walkers) "by" = ( /obj/structure/closet/crate, @@ -489,7 +447,7 @@ /obj/structure/stone_tile/block/cracked{ dir = 4 }, -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "bG" = ( /turf/closed/indestructible/riveted/boss/see_through, @@ -513,14 +471,14 @@ "bJ" = ( /obj/effect/mapping_helpers/no_lava, /mob/living/basic/mining/gutlunch/milk, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "cp" = ( /obj/effect/mapping_helpers/no_lava, /obj/structure/railing/wooden_fence{ dir = 8 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "cF" = ( /obj/structure/stone_tile/block{ @@ -583,39 +541,39 @@ /obj/structure/stone_tile/surrounding_tile/cracked{ dir = 8 }, -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "cP" = ( /obj/structure/stone_tile/block, -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "cQ" = ( /obj/structure/stone_tile/block/cracked, -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "cR" = ( /obj/structure/stone_tile/surrounding_tile/cracked, -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "cT" = ( /obj/structure/stone_tile, /obj/structure/stone_tile/block{ dir = 1 }, -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "du" = ( /obj/structure/stone_tile/cracked{ dir = 1 }, -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "dz" = ( /obj/structure/stone_tile/cracked{ dir = 1 }, /obj/structure/stone_tile/cracked, -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "dB" = ( /obj/structure/stone_tile/surrounding_tile/cracked{ @@ -628,35 +586,35 @@ dir = 8 }, /obj/structure/stone_tile/center/cracked, -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "dC" = ( /obj/structure/stone_tile, -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "dD" = ( /obj/structure/stone_tile/cracked{ dir = 8 }, -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "dE" = ( /obj/structure/stone_tile, /obj/structure/stone_tile/cracked{ dir = 8 }, -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "dP" = ( /obj/structure/stone_tile/block{ dir = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ash_walkers) "eu" = ( /obj/structure/stone_tile, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "eC" = ( /obj/structure/stone_tile/block{ @@ -664,7 +622,7 @@ }, /obj/item/pickaxe, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "eG" = ( /obj/structure/closet/crate/radiation, @@ -677,27 +635,27 @@ /obj/item/flashlight/flare/torch, /obj/item/flashlight/flare/torch, /obj/item/flashlight/flare/torch, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ash_walkers) "fM" = ( /obj/effect/mapping_helpers/no_lava, /mob/living/basic/mining/gutlunch/warrior, /obj/item/flashlight/lantern, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "gi" = ( /obj/structure/table/optable, /obj/structure/stone_tile{ dir = 1 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ash_walkers) "hF" = ( /obj/structure/stone_tile/block/cracked{ dir = 8 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "id" = ( /obj/structure/stone_tile{ @@ -706,7 +664,7 @@ /obj/structure/stone_tile/cracked, /obj/effect/decal/cleanable/blood, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "ie" = ( /obj/machinery/hydroponics/soil, @@ -725,7 +683,7 @@ dir = 4 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "iW" = ( /obj/structure/stone_tile/block, @@ -733,14 +691,14 @@ dir = 1 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "kX" = ( /obj/structure/stone_tile/block/cracked{ dir = 4 }, /obj/item/flashlight/flare/torch, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ash_walkers) "mm" = ( /obj/structure/stone_tile, @@ -755,22 +713,22 @@ }, /obj/effect/decal/cleanable/blood, /obj/item/crusher_trophy/retool_kit/ashenskull, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ash_walkers) "mo" = ( /obj/structure/stone_tile/block, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "mp" = ( /obj/structure/stone_tile/surrounding/cracked, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ash_walkers) "mB" = ( /obj/structure/stone_tile/surrounding/cracked{ dir = 1 }, /obj/item/flashlight/lantern, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ash_walkers) "mL" = ( /obj/effect/mob_spawn/corpse/human/damaged, @@ -778,7 +736,7 @@ /obj/structure/stone_tile/cracked{ dir = 1 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "nB" = ( /obj/effect/decal/cleanable/blood, @@ -790,14 +748,14 @@ dir = 1 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "oI" = ( /obj/structure/stone_tile{ dir = 8 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "pT" = ( /obj/structure/stone_tile/surrounding_tile/cracked, @@ -809,7 +767,7 @@ }, /obj/structure/stone_tile/center, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "qm" = ( /obj/effect/mapping_helpers/no_lava, @@ -819,25 +777,25 @@ /obj/structure/stone_tile/block/cracked{ dir = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "qn" = ( /obj/item/storage/box/rxglasses, /obj/structure/stone_tile{ dir = 1 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ash_walkers) "qw" = ( /obj/structure/stone_tile/slab, /obj/effect/decal/cleanable/blood, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "qH" = ( /obj/effect/mapping_helpers/no_lava, /obj/structure/railing/wooden_fence, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "qV" = ( /obj/structure/stone_tile/surrounding_tile{ @@ -849,7 +807,7 @@ dir = 4 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "qZ" = ( /obj/structure/stone_tile/block{ @@ -859,7 +817,7 @@ dir = 8 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "rs" = ( /obj/structure/stone_tile/surrounding_tile/cracked{ @@ -872,18 +830,18 @@ /obj/structure/stone_tile/center, /obj/item/hatchet/wooden, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "ry" = ( /obj/structure/stone_tile/block, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "rZ" = ( /obj/structure/stone_tile/slab/cracked{ dir = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ash_walkers) "sd" = ( /obj/structure/stone_tile/surrounding_tile{ @@ -898,24 +856,24 @@ /obj/structure/stone_tile/center, /obj/effect/decal/cleanable/blood, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "sz" = ( /obj/effect/mapping_helpers/no_lava, /obj/structure/stone_tile/block/cracked{ dir = 8 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "ty" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "tY" = ( /obj/structure/stone_tile/block/cracked{ dir = 1 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "ua" = ( /obj/structure/stone_tile{ @@ -926,7 +884,7 @@ }, /obj/item/spear, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "uv" = ( /obj/structure/stone_tile/surrounding_tile{ @@ -936,11 +894,11 @@ dir = 4 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "vk" = ( /obj/structure/stone_tile, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ash_walkers) "vw" = ( /obj/structure/stone_tile/cracked{ @@ -950,15 +908,8 @@ /obj/item/flashlight/flare/torch, /obj/item/flashlight/flare/torch, /obj/item/flashlight/flare/torch, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ash_walkers) -"vV" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/structure/railing/wooden_fence{ - dir = 4 - }, -/turf/open/misc/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) "wB" = ( /obj/structure/stone_tile/block, /obj/structure/stone_tile{ @@ -968,7 +919,7 @@ dir = 1 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "wQ" = ( /obj/structure/stone_tile/cracked{ @@ -977,12 +928,12 @@ /obj/structure/stone_tile{ dir = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ash_walkers) "xd" = ( /obj/structure/stone_tile/block/cracked, /obj/item/storage/toolbox/syndicate, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ash_walkers) "xo" = ( /obj/structure/stone_tile/cracked{ @@ -993,7 +944,7 @@ /obj/structure/stone_tile/cracked{ dir = 1 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "xH" = ( /obj/item/spear, @@ -1001,7 +952,7 @@ dir = 4 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "zD" = ( /obj/item/stack/sheet/mineral/wood, @@ -1009,7 +960,7 @@ dir = 4 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "zR" = ( /obj/structure/stone_tile/surrounding_tile, @@ -1021,14 +972,14 @@ }, /obj/structure/stone_tile/center, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Aj" = ( /obj/structure/stone_tile/cracked{ dir = 1 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "AV" = ( /obj/item/pickaxe, @@ -1036,7 +987,7 @@ dir = 1 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Bc" = ( /obj/item/shovel, @@ -1044,7 +995,7 @@ dir = 8 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Bl" = ( /obj/structure/stone_tile/surrounding_tile, @@ -1056,20 +1007,20 @@ dir = 8 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Bq" = ( /obj/structure/stone_tile/cracked{ dir = 4 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Cg" = ( /obj/structure/stone_tile/block/cracked{ dir = 8 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ash_walkers) "Dx" = ( /obj/effect/decal/cleanable/blood, @@ -1080,7 +1031,7 @@ dir = 4 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Dz" = ( /obj/effect/mapping_helpers/no_lava, @@ -1088,7 +1039,7 @@ dir = 8 }, /obj/structure/stone_tile, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Ee" = ( /obj/structure/stone_tile/block/cracked, @@ -1099,14 +1050,14 @@ dir = 4 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Fa" = ( /obj/structure/stone_tile/block{ dir = 4 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Fg" = ( /obj/structure/stone_tile, @@ -1117,19 +1068,19 @@ dir = 1 }, /obj/item/spear, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ash_walkers) "Fp" = ( /obj/structure/stone_tile/slab, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "FJ" = ( /obj/structure/stone_tile{ dir = 1 }, /obj/item/weldingtool/experimental, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ash_walkers) "Go" = ( /obj/structure/stone_tile/cracked{ @@ -1139,11 +1090,11 @@ dir = 1 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Gv" = ( /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Gx" = ( /obj/structure/stone_tile/block/cracked, @@ -1159,7 +1110,7 @@ /obj/item/seeds/tower, /obj/item/seeds/bamboo, /obj/item/seeds/bamboo, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ash_walkers) "GW" = ( /obj/structure/stone_tile/cracked{ @@ -1173,14 +1124,14 @@ /obj/item/pickaxe, /obj/item/pickaxe, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "HU" = ( /obj/structure/stone_tile/block{ dir = 8 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Ic" = ( /obj/machinery/hydroponics/soil, @@ -1193,7 +1144,7 @@ }, /obj/structure/stone_tile/center, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Ie" = ( /obj/structure/stone_tile/cracked{ @@ -1206,38 +1157,31 @@ dir = 8 }, /obj/effect/decal/cleanable/blood, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ash_walkers) "If" = ( /obj/structure/stone_tile/cracked{ dir = 8 }, /obj/item/malf_upgrade, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ash_walkers) "Iy" = ( /obj/structure/stone_tile/center, /obj/effect/mapping_helpers/no_lava, /obj/item/flashlight/flare/torch, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "IS" = ( /obj/structure/stone_tile/block, /obj/item/spear, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "JD" = ( /obj/effect/mapping_helpers/no_lava, /obj/structure/ore_container/food_trough/gutlunch_trough, -/turf/open/misc/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"Kg" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/structure/railing/wooden_fence{ - dir = 10 - }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Kt" = ( /obj/structure/water_source/puddle{ @@ -1251,18 +1195,18 @@ /obj/effect/mapping_helpers/no_lava, /obj/structure/table/wood, /obj/item/reagent_containers/cup/bucket/wooden, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "KR" = ( /obj/structure/stone_tile/block/cracked, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Lb" = ( /obj/structure/stone_tile/cracked{ dir = 1 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ash_walkers) "LH" = ( /obj/structure/stone_tile, @@ -1270,7 +1214,7 @@ dir = 8 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "LN" = ( /obj/structure/stone_tile/surrounding_tile{ @@ -1282,7 +1226,7 @@ dir = 1 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "MD" = ( /obj/structure/stone_tile/block/cracked{ @@ -1292,13 +1236,13 @@ dir = 8 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "MY" = ( /obj/structure/stone_tile/cracked{ dir = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ash_walkers) "Nv" = ( /obj/structure/stone_tile/block/cracked, @@ -1306,49 +1250,42 @@ dir = 1 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "NV" = ( /obj/structure/stone_tile{ dir = 1 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Oe" = ( /obj/effect/mapping_helpers/no_lava, /obj/structure/stone_tile{ dir = 8 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "OY" = ( /obj/structure/stone_tile/surrounding_tile/cracked, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Pk" = ( /obj/effect/mapping_helpers/no_lava, /obj/structure/railing/corner/end/wooden_fence, /obj/structure/railing/corner/end/flip/wooden_fence, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "PA" = ( /obj/effect/mapping_helpers/no_lava, /mob/living/basic/mining/gutlunch/warrior, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "PK" = ( /obj/effect/mapping_helpers/no_lava, /obj/structure/stone_tile, -/turf/open/misc/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"Rq" = ( -/obj/effect/mapping_helpers/no_lava, -/obj/structure/railing/wooden_fence{ - dir = 6 - }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "RE" = ( /obj/structure/stone_tile/block/cracked{ @@ -1356,14 +1293,14 @@ }, /obj/structure/stone_tile/block, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "RH" = ( /obj/structure/stone_tile{ dir = 4 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Sf" = ( /obj/structure/stone_tile/block/cracked{ @@ -1371,7 +1308,7 @@ }, /obj/item/reagent_containers/cup/bucket/wooden, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Sq" = ( /obj/structure/stone_tile/cracked{ @@ -1381,7 +1318,7 @@ dir = 8 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Th" = ( /obj/structure/stone_tile/block/cracked{ @@ -1392,13 +1329,13 @@ dir = 8 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Tl" = ( /obj/effect/mapping_helpers/no_lava, /obj/structure/table/wood, /obj/item/flashlight/lantern, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Tr" = ( /obj/machinery/hydroponics/soil, @@ -1406,12 +1343,12 @@ dir = 8 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "TC" = ( /obj/effect/mapping_helpers/no_lava, /obj/item/flashlight/lantern, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "TO" = ( /obj/structure/stone_tile{ @@ -1423,7 +1360,7 @@ /obj/item/reagent_containers/blood/lizard, /obj/item/reagent_containers/blood/lizard, /obj/item/stack/sheet/cloth/ten, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ash_walkers) "TY" = ( /obj/structure/stone_tile/surrounding_tile{ @@ -1437,12 +1374,12 @@ dir = 4 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Uh" = ( /obj/effect/mapping_helpers/no_lava, /obj/structure/stone_tile/block, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "UI" = ( /obj/structure/stone_tile/block{ @@ -1450,12 +1387,12 @@ }, /obj/machinery/iv_drip, /obj/item/reagent_containers/cup/glass/waterbottle/large, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ash_walkers) "UL" = ( /obj/structure/stone_tile/cracked, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Wh" = ( /obj/structure/stone_tile/block, @@ -1463,26 +1400,26 @@ dir = 1 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Xp" = ( /obj/structure/stone_tile/cracked{ dir = 8 }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "YO" = ( /obj/structure/bonfire/dense, /obj/structure/stone_tile/center, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Zr" = ( /obj/structure/stone_tile/surrounding_tile/cracked, /obj/structure/ore_box, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) (1,1,1) = {" @@ -1687,8 +1624,8 @@ ah aa ai aq -at -aF +aR +aR aR aR eC @@ -1905,15 +1842,15 @@ cQ "} (20,1,1) = {" ah +aj +ak +ak +fM Gv +TC Gv -Gv -Gv -Gv -Gv -Gv -Gv -Gv +qH +KQ Gv Dz qm @@ -1926,17 +1863,17 @@ ah cR "} (21,1,1) = {" -ah +aa +aj +ak +ak Gv -ar -cp -cp -cp -cp -cp -Kg Gv Gv +PA +qH +KQ +Gv Gv qm Gv @@ -1948,16 +1885,16 @@ ah ah "} (22,1,1) = {" -ah +aa +aj +ak +ak Gv -al -fM -Gv -Gv -TC +bJ +bJ Gv qH -KQ +Tl Gv Gv qm @@ -1970,18 +1907,18 @@ ah ah "} (23,1,1) = {" -ah -Gv -al +aa +aj +ak +ak +bJ Gv Gv Gv -Gv -PA qH -KQ -Gv Gv +sz +sz qm Gv PK @@ -1992,62 +1929,62 @@ ah ah "} (24,1,1) = {" -ah -Gv -al +aa +aa +ak +ak Gv bJ bJ Gv -Gv -qH -Tl -Gv -Gv -qm -sz -Gv -ah -ah -ah -ah -ah -"} -(25,1,1) = {" -ah -Gv -al -bJ -Gv -Gv -Gv -Gv -qH -Gv -sz -sz -qm -Gv -Gv -ah -ah -ah -ah -ah -"} -(26,1,1) = {" -ah -Gv -al -Gv -bJ -bJ -Gv -Gv Pk sz Gv Oe +qm +sz +Gv +ah +ah +ah +ah +aa +"} +(25,1,1) = {" +aa +aa +ak +ak +Gv +Gv +TC +Gv +qH +Gv +Dz +Oe +qm +Gv +Gv +ah +ah +ah +ah +aa +"} +(26,1,1) = {" +aa +ah +ak +ak +Gv +JD +Gv +Gv +qH +Gv +Gv +Gv Gv Gv Gv @@ -2058,18 +1995,18 @@ aa aa "} (27,1,1) = {" +aa ah -Gv -al +ak +ak Gv Gv -TC -Gv Gv +PA qH Gv -Dz -Oe +Gv +Gv Gv Gv Gv @@ -2081,17 +2018,17 @@ aa "} (28,1,1) = {" ah +ah +ak +ak +TC Gv -al -Gv -JD -Gv -Gv -Gv +PA +TC qH Gv -Gv -Gv +mo +ah Gv Dz Gv @@ -2103,17 +2040,17 @@ aa "} (29,1,1) = {" ah -Gv -al +ah +ak +ak Gv Gv Gv Gv -PA qH -Gv -Gv -Gv +Uh +ty +ah Gv Gv Gv @@ -2124,17 +2061,17 @@ aa aa "} (30,1,1) = {" +aa ah +ak +ak +ak +ak +ak +cp +cp Gv -al -TC -Gv -PA -Gv -TC -qH -Gv -mo +ty ah ah ah @@ -2146,17 +2083,17 @@ aa aa "} (31,1,1) = {" +aa +aa +aa +ak +ak +ak +ak +ak +ah +ah ah -Gv -bh -vV -vV -vV -vV -vV -Rq -Uh -ty ah ah ah @@ -2168,32 +2105,10 @@ aa aa "} (32,1,1) = {" -ah -Gv -Gv -Gv -Gv -Gv -Gv -Gv -Gv -Gv -ty -ah -ah aa aa aa aa -aa -aa -aa -"} -(33,1,1) = {" -ah -ah -ah -ah ah ah ah @@ -2211,3 +2126,25 @@ aa aa aa "} +(33,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +ah +ah +ah +ah +ah +aa +aa +aa +aa +aa +aa +aa +aa +"} diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_bileworm_nest.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_bileworm_nest.dmm index d52147d9994..3f49c8c6f98 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_bileworm_nest.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_bileworm_nest.dmm @@ -1,8 +1,9 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "a" = ( -/turf/closed/mineral/volcanic/lava_land_surface, -/area/lavaland/surface/outdoors) +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, +/area/template_noop) "b" = ( +/obj/effect/mapping_helpers/no_lava, /turf/open/misc/asteroid/lavaland_atmos, /area/lavaland/surface/outdoors) "c" = ( @@ -10,14 +11,17 @@ /area/template_noop) "d" = ( /mob/living/basic/mining/bileworm, +/obj/effect/mapping_helpers/no_lava, /turf/open/misc/asteroid/lavaland_atmos, /area/lavaland/surface/outdoors) "e" = ( /obj/item/crusher_trophy/bileworm_spewlet, +/obj/effect/mapping_helpers/no_lava, /turf/open/misc/asteroid/lavaland_atmos, /area/lavaland/surface/outdoors) "f" = ( /obj/structure/water_source/puddle, +/obj/effect/mapping_helpers/no_lava, /turf/open/misc/asteroid/lavaland_atmos, /area/lavaland/surface/outdoors) @@ -62,9 +66,9 @@ c c a a -a -a -a +c +c +c a a c @@ -118,7 +122,7 @@ b b a a -a +c c c c @@ -168,8 +172,8 @@ b b a a -a -a +c +c c c c @@ -185,8 +189,8 @@ b b a a -a -a +c +c c c c @@ -194,6 +198,7 @@ c (11,1,1) = {" c c +c a a a @@ -202,8 +207,7 @@ a a a a -a -a +c c c c @@ -211,8 +215,8 @@ c (12,1,1) = {" c c -a -a +c +c a a a @@ -229,15 +233,15 @@ c c c c -a -a +c a a a a a c -a +c +c c c c diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_biodome_winter.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_biodome_winter.dmm index 3c228756225..56263c3b814 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_biodome_winter.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_biodome_winter.dmm @@ -302,7 +302,7 @@ /area/ruin/powered/snow_biodome) "tb" = ( /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors/explored) "tl" = ( /turf/open/floor/pod/light, @@ -422,10 +422,10 @@ "Qa" = ( /obj/effect/mapping_helpers/no_lava, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors/explored) "QI" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors/explored) "QK" = ( /obj/structure/table, diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_blooddrunk1.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_blooddrunk1.dmm index 9fc94d86979..aacebb24ac0 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_blooddrunk1.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_blooddrunk1.dmm @@ -2,64 +2,61 @@ "a" = ( /turf/template_noop, /area/template_noop) -"b" = ( -/turf/closed/mineral/volcanic/lava_land_surface, -/area/lavaland/surface/outdoors) "c" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "d" = ( /obj/structure/stone_tile/block{ dir = 8 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "e" = ( /obj/structure/stone_tile{ dir = 8 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "f" = ( /obj/structure/stone_tile/cracked{ dir = 1 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "g" = ( /obj/structure/stone_tile/cracked{ dir = 8 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "h" = ( /obj/structure/stone_tile/block{ dir = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "i" = ( /obj/structure/stone_tile{ dir = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "j" = ( /obj/structure/stone_tile, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "k" = ( /obj/structure/stone_tile/cracked{ dir = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "l" = ( /obj/structure/stone_tile, /obj/structure/stone_tile{ dir = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "m" = ( /obj/structure/stone_tile/cracked{ @@ -68,23 +65,23 @@ /obj/structure/stone_tile{ dir = 1 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "n" = ( /obj/structure/stone_tile/block/cracked{ dir = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "o" = ( /obj/structure/stone_tile/block, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "p" = ( /obj/structure/stone_tile/block/cracked{ dir = 1 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "q" = ( /obj/structure/stone_tile{ @@ -99,7 +96,7 @@ /obj/structure/stone_tile/block{ dir = 1 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "s" = ( /obj/structure/stone_tile/block, @@ -108,15 +105,6 @@ }, /turf/open/lava/smooth/lava_land_surface, /area/lavaland/surface/outdoors) -"t" = ( -/obj/structure/stone_tile/surrounding/cracked{ - dir = 6 - }, -/mob/living/basic/boss/blood_drunk_miner{ - dir = 1 - }, -/turf/open/lava/smooth/lava_land_surface, -/area/lavaland/surface/outdoors) "u" = ( /obj/structure/stone_tile{ dir = 1 @@ -129,7 +117,7 @@ dir = 4 }, /obj/structure/stone_tile/cracked, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "w" = ( /obj/structure/stone_tile, @@ -145,23 +133,35 @@ /obj/structure/stone_tile/block{ dir = 1 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "y" = ( /obj/structure/stone_tile/cracked, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, +/area/lavaland/surface/outdoors) +"I" = ( +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, +/area/template_noop) +"U" = ( +/obj/structure/stone_tile/surrounding/cracked{ + dir = 6 + }, +/mob/living/basic/boss/blood_drunk_miner{ + dir = 1 + }, +/turf/open/lava/smooth/lava_land_surface, /area/lavaland/surface/outdoors) (1,1,1) = {" a a a -b -b -b -b -b -b +a +a +a +I +I +I a a a @@ -171,38 +171,38 @@ a (2,1,1) = {" a a -b -b +I +I c c -b -b -b -b -b -b +I +I +I +I +I +I a a "} (3,1,1) = {" -b -b -b +I +I +I c d c c -b -b -b -b -b -b +I +I +I +I +I +I a "} (4,1,1) = {" -b -b +a +I c c k @@ -211,13 +211,13 @@ c c c c -b -b -b -b +I +I +I +I "} (5,1,1) = {" -b +a c d g @@ -229,11 +229,11 @@ c c c c -b -b +I +I "} (6,1,1) = {" -b +a c c h @@ -246,26 +246,26 @@ d e c c -b +I "} (7,1,1) = {" -b +a c c c c q -t +U w x y p e c -b +a "} (8,1,1) = {" -b +a c e i @@ -278,10 +278,10 @@ f d y c -b +a "} (9,1,1) = {" -b +I c f j @@ -293,53 +293,53 @@ c c c c -b -b +a +a "} (10,1,1) = {" -b -b +I +I c c c o c c -b -b +I +I c -b -b -b +a +a +a "} (11,1,1) = {" -b -b -b +I +I +I c n c c -b -b -b -b -b -b +I +I +I +I +a +a a "} (12,1,1) = {" a -b -b +I +I c c c -b -b -b -b -b +I +I +I +I +I a a a @@ -347,11 +347,11 @@ a (13,1,1) = {" a a -b -b -b -b -b +I +I +I +I +I a a a diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_blooddrunk2.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_blooddrunk2.dmm index 64d88ce895e..034e7d297ce 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_blooddrunk2.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_blooddrunk2.dmm @@ -2,90 +2,70 @@ "a" = ( /turf/template_noop, /area/template_noop) -"b" = ( -/turf/closed/mineral/volcanic/lava_land_surface, -/area/lavaland/surface/outdoors) "c" = ( /obj/structure/stone_tile/surrounding_tile{ dir = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "d" = ( /obj/structure/stone_tile/block{ dir = 1 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "e" = ( /obj/structure/stone_tile/surrounding_tile/cracked{ dir = 1 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "f" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "g" = ( /obj/structure/stone_tile{ dir = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "h" = ( /obj/structure/stone_tile/block/cracked{ dir = 8 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "i" = ( /obj/structure/stone_tile/surrounding_tile/cracked, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "j" = ( /obj/structure/stone_tile/block/cracked{ dir = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "k" = ( /obj/structure/stone_tile/surrounding_tile{ dir = 8 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "l" = ( /obj/structure/stone_tile/surrounding_tile, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "m" = ( /obj/structure/stone_tile/cracked{ dir = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "n" = ( /obj/structure/stone_tile/block{ dir = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"o" = ( -/obj/structure/stone_tile, -/obj/structure/stone_tile{ - dir = 1 - }, -/obj/structure/stone_tile/cracked{ - dir = 8 - }, -/turf/open/misc/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"p" = ( -/obj/structure/stone_tile, -/obj/structure/stone_tile/block/cracked{ - dir = 1 - }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "q" = ( /obj/structure/stone_tile{ @@ -94,80 +74,110 @@ /obj/structure/stone_tile{ dir = 1 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) -"s" = ( +"r" = ( +/obj/structure/stone_tile/surrounding/burnt, /mob/living/basic/boss/blood_drunk_miner/guidance{ dir = 8 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"t" = ( -/obj/structure/stone_tile{ - dir = 1 - }, -/obj/structure/stone_tile{ - dir = 4 - }, -/obj/structure/stone_tile/cracked{ - dir = 8 - }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/lava/smooth/lava_land_surface, /area/lavaland/surface/outdoors) "u" = ( /obj/structure/stone_tile/surrounding_tile/cracked{ dir = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "v" = ( /obj/structure/stone_tile/block/cracked, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "w" = ( /obj/structure/stone_tile/block, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "x" = ( /obj/structure/stone_tile/block/cracked{ dir = 1 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "y" = ( /obj/structure/stone_tile, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "z" = ( /obj/structure/stone_tile/surrounding_tile/cracked{ dir = 8 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "A" = ( /obj/structure/stone_tile/cracked{ dir = 8 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) -"M" = ( +"C" = ( /obj/structure/stone_tile/block{ dir = 8 }, /obj/structure/stone_tile/cracked, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors) +"F" = ( +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, +/area/template_noop) +"H" = ( +/obj/structure/stone_tile{ + dir = 8 + }, +/obj/structure/stone_tile{ + dir = 1 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors) +"L" = ( +/obj/structure/stone_tile, +/obj/structure/stone_tile/block/cracked{ + dir = 1 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors) +"V" = ( +/obj/structure/stone_tile, +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors) +"Z" = ( +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile{ + dir = 4 + }, +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/turf/open/lava/smooth/lava_land_surface, /area/lavaland/surface/outdoors) (1,1,1) = {" a a -b -b -b -b +F +F +F +F +a +a a -b -b a a a @@ -177,24 +187,24 @@ a "} (2,1,1) = {" a -b -b -b -b -b -b -b -b -b -b +F +F +F +f +f +f +f +a +F +F a a a a "} (3,1,1) = {" -b -b +F +F c h k @@ -203,15 +213,15 @@ f f k f -b -b +F +F a a a "} (4,1,1) = {" -b -b +F +F d c l @@ -220,15 +230,15 @@ f f v f -b -b -b +F +F +F a a "} (5,1,1) = {" -b -b +F +F e i m @@ -238,65 +248,65 @@ u w f f -b -b -b +F +F +F a "} (6,1,1) = {" a -b +F +F f f -f -o -M -q +V +C +H w f f f f -b -b +F +F "} (7,1,1) = {" -b -b -b +a +F +F f f -p -s -t +L +r +Z f f q n A f -b +F "} (8,1,1) = {" -b -b +a +F g f c -q -t -q +H +Z +H k x f z d f -b +a "} (9,1,1) = {" a -b +a f j n @@ -308,57 +318,57 @@ y f n y -b -b +a +a "} (10,1,1) = {" a -b -b +a +a f f f f f f -b -b +F +F f f -b -b +a +a "} (11,1,1) = {" a a -b -b -b -b -b -b -b -b -b -b -b -b +a +a +F +F +F +F +F +F +F +F +a +a a "} (12,1,1) = {" a a a -b -b -b -b -b -b a a -b -b +F +F +F +F +a +a +a +a a a "} diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_blooddrunk3.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_blooddrunk3.dmm index daa1409f6c6..bdac7f9bada 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_blooddrunk3.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_blooddrunk3.dmm @@ -2,11 +2,8 @@ "a" = ( /turf/template_noop, /area/template_noop) -"b" = ( -/turf/closed/mineral/volcanic/lava_land_surface, -/area/lavaland/surface/outdoors) "c" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "d" = ( /obj/structure/stone_tile/block{ @@ -15,7 +12,7 @@ /obj/structure/stone_tile/block{ dir = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "e" = ( /obj/structure/stone_tile/block{ @@ -24,7 +21,7 @@ /obj/structure/stone_tile/block/cracked{ dir = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "f" = ( /obj/structure/stone_tile/block{ @@ -33,19 +30,19 @@ /obj/structure/stone_tile/block/cracked{ dir = 8 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "g" = ( /obj/structure/stone_tile{ dir = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "h" = ( /obj/structure/stone_tile{ dir = 1 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "i" = ( /obj/structure/stone_tile{ @@ -55,7 +52,7 @@ dir = 1 }, /obj/structure/stone_tile/cracked, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "j" = ( /obj/structure/stone_tile, @@ -65,7 +62,7 @@ /obj/structure/stone_tile/cracked{ dir = 8 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "k" = ( /obj/structure/stone_tile/cracked, @@ -75,7 +72,7 @@ /obj/structure/stone_tile{ dir = 1 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "l" = ( /obj/structure/stone_tile{ @@ -85,7 +82,7 @@ /obj/structure/stone_tile/cracked{ dir = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "m" = ( /obj/structure/stone_tile{ @@ -95,23 +92,13 @@ dir = 8 }, /obj/structure/stone_tile/cracked, -/turf/open/misc/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"n" = ( -/obj/structure/stone_tile/block{ - dir = 8 - }, -/obj/structure/stone_tile/block{ - dir = 4 - }, -/mob/living/basic/boss/blood_drunk_miner/hunter, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "o" = ( /obj/structure/stone_tile/cracked{ dir = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "p" = ( /obj/structure/stone_tile{ @@ -121,7 +108,7 @@ dir = 8 }, /obj/structure/stone_tile, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "q" = ( /obj/structure/stone_tile{ @@ -131,7 +118,7 @@ /obj/structure/stone_tile{ dir = 8 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "r" = ( /obj/structure/stone_tile{ @@ -141,28 +128,72 @@ dir = 8 }, /obj/structure/stone_tile, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "s" = ( /obj/structure/stone_tile/surrounding_tile/cracked, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "t" = ( /obj/structure/stone_tile/block/cracked, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "u" = ( /obj/structure/stone_tile/surrounding_tile{ dir = 8 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) -"v" = ( +"z" = ( +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, +/area/template_noop) +"A" = ( +/obj/structure/stone_tile/burnt{ + dir = 1 + }, +/obj/structure/stone_tile, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors) +"I" = ( /obj/structure/stone_tile/surrounding/cracked{ dir = 6 }, /obj/structure/stone_tile/center, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/obj/structure/stone_tile/block{ + dir = 8 + }, +/obj/structure/stone_tile/block{ + dir = 4 + }, +/mob/living/basic/boss/blood_drunk_miner/hunter, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors) +"N" = ( +/obj/structure/stone_tile/block{ + dir = 8 + }, +/obj/structure/stone_tile/block{ + dir = 4 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors) +"R" = ( +/obj/structure/stone_tile{ + dir = 8 + }, +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors) +"W" = ( +/obj/structure/stone_tile/block{ + dir = 4 + }, +/obj/structure/stone_tile/block/cracked{ + dir = 8 + }, +/turf/open/lava/smooth/lava_land_surface, /area/lavaland/surface/outdoors) (1,1,1) = {" @@ -174,58 +205,58 @@ a a a a -b -b -b -b -b +a +a +a +a +a a a a "} (2,1,1) = {" a -b -b -b +z +z +z a a -b -b -b +z +z +z c c -b -b -b +a +z +z a a "} (3,1,1) = {" -b -b -b -b -b -b -b -b +z +z +z +z +z +z +z +z c g m c c -b -b +z +z a "} (4,1,1) = {" -b +z c c -b -b -b +z +z +z c c g @@ -234,11 +265,11 @@ h q c c -b -b +z +z "} (5,1,1) = {" -b +a c c c @@ -248,15 +279,15 @@ c g i c -c +R h s c c -b +z "} (6,1,1) = {" -b +a d e e @@ -265,16 +296,16 @@ f d f e +N +I +W d -n -f t -v c -b +z "} (7,1,1) = {" -b +a c c c @@ -284,17 +315,17 @@ c h j c -c +A o u c -b -b +z +z "} (8,1,1) = {" -b -b -b +a +z +z c c c @@ -305,16 +336,16 @@ l o r c -b -b -b +z +z +z "} (9,1,1) = {" a -b -b -b -b +z +z +z +z c c c @@ -323,25 +354,25 @@ h p c c -b -b +z +z a "} (10,1,1) = {" a a a -b -b -b -b -b +z +z +z +z +a c c c c -b -b +a +a a a "} @@ -351,15 +382,15 @@ a a a a -b -b -b -b -b -b -b -b -b +a +a +a +a +a +a +a +a +a a a "} diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_crashsite.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_crashsite.dmm index ef3307e388d..660d01dedff 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_crashsite.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_crashsite.dmm @@ -1,6 +1,6 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "a" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "b" = ( /obj/machinery/door/airlock/titanium{ @@ -44,11 +44,11 @@ /area/ruin/powered) "h" = ( /obj/effect/decal/cleanable/rubble, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "i" = ( /obj/effect/mob_spawn/corpse/goliath, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "j" = ( /obj/structure/chair/comfy/shuttle{ @@ -74,7 +74,7 @@ }, /area/ruin/unpowered) "o" = ( -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "p" = ( /obj/structure/rack, @@ -96,17 +96,17 @@ /area/ruin/powered) "t" = ( /obj/structure/flora/tree/stump, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "u" = ( /obj/structure/bonfire/prelit, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "v" = ( /obj/effect/decal/cleanable/rubble, /obj/item/stack/sheet/mineral/titanium, /obj/item/stack/sheet/mineral/titanium, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "w" = ( /obj/effect/decal/cleanable/glass/titanium, @@ -133,18 +133,18 @@ /area/lavaland/surface/outdoors) "B" = ( /mob/living/basic/mining/goliath, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "D" = ( /obj/item/gun/energy/recharge/kinetic_accelerator, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "E" = ( /turf/open/misc/ashplanet/wateryrock/lavaland_atmos, /area/lavaland/surface/outdoors) "F" = ( /obj/effect/mob_spawn/corpse/human/cargo_tech, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "G" = ( /turf/template_noop, @@ -193,7 +193,7 @@ /area/ruin/unpowered) "P" = ( /obj/effect/mob_spawn/corpse/human/miner, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Q" = ( /turf/closed/wall/mineral/titanium/nodiagonal, @@ -220,6 +220,9 @@ /obj/item/food/meat/steak/goliath, /turf/open/floor/pod/dark, /area/ruin/powered) +"W" = ( +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, +/area/ruin/powered) "Y" = ( /obj/machinery/power/shuttle_engine/propulsion/burst{ dir = 8 @@ -731,7 +734,7 @@ N N N N -N +W o q H diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm index 35492d9e9f2..2198bf7542f 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm @@ -15,11 +15,11 @@ /area/ruin/unpowered/cultaltar) "e" = ( /obj/effect/decal/remains/human, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/cultaltar) "f" = ( /obj/structure/destructible/cult/pylon, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/cultaltar) "g" = ( /obj/effect/decal/cleanable/blood/old, @@ -34,6 +34,9 @@ initial_gas_mix = "LAVALAND_ATMOS" }, /area/ruin/unpowered/cultaltar) +"j" = ( +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, +/area/template_noop) "k" = ( /obj/effect/decal/remains/human, /obj/item/melee/cultblade, @@ -82,8 +85,16 @@ }, /area/ruin/unpowered/cultaltar) "s" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/cultaltar) +"z" = ( +/turf/open/floor/engine/cult{ + initial_gas_mix = "LAVALAND_ATMOS" + }, +/area/template_noop) +"T" = ( +/turf/open/lava/smooth/lava_land_surface, +/area/template_noop) (1,1,1) = {" a @@ -106,16 +117,16 @@ a a d e -c -s +T +j c b b b c -s -c -s +j +T +j d a "} @@ -133,13 +144,13 @@ c d e f -s +j a "} (4,1,1) = {" a -c -s +T +j c c c @@ -150,12 +161,12 @@ c c c e -c +T a "} (5,1,1) = {" a -s +j d c c @@ -167,12 +178,12 @@ b c c d -s +j a "} (6,1,1) = {" a -c +T c c b @@ -183,12 +194,12 @@ k b b c -c -c +T +T a "} (7,1,1) = {" -b +z b c c @@ -200,12 +211,12 @@ b l b c -c +T b b "} (8,1,1) = {" -c +T b g b @@ -219,7 +230,7 @@ b b g b -c +T "} (9,1,1) = {" b @@ -240,7 +251,7 @@ b "} (10,1,1) = {" a -c +T c c g @@ -252,12 +263,12 @@ b b c c -c +T a "} (11,1,1) = {" a -s +j d c c @@ -274,7 +285,7 @@ a "} (12,1,1) = {" a -c +T s c c @@ -310,15 +321,15 @@ a a d e -c +T s -c +T b b b -c -s -c +T +j +T s d a @@ -331,7 +342,7 @@ a a a b -c +T b a a diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_dead_ratvar.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_dead_ratvar.dmm index 65a2652915d..35dc96ed6e5 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_dead_ratvar.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_dead_ratvar.dmm @@ -3,33 +3,33 @@ /turf/template_noop, /area/template_noop) "b" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ratvar) "c" = ( /obj/structure/fluff/clockwork/alloy_shards/small, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ratvar) "d" = ( /obj/structure/girder/bronze, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ratvar) "e" = ( /obj/item/stack/sheet/bronze, /turf/open/floor/bronze/filled/lavaland, /area/ruin/unpowered/ratvar) "f" = ( -/turf/closed/mineral/volcanic/lava_land_surface, -/area/ruin/unpowered/ratvar) +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, +/area/template_noop) "g" = ( /obj/structure/fluff/clockwork/alloy_shards/medium_gearbit, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ratvar) "h" = ( /turf/open/floor/bronze/filled/lavaland, /area/ruin/unpowered/ratvar) "i" = ( /obj/structure/grille/broken, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ratvar) "j" = ( /turf/closed/wall/mineral/bronze, @@ -43,15 +43,15 @@ /area/ruin/unpowered/ratvar) "m" = ( /obj/structure/fluff/clockwork/alloy_shards/medium, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ratvar) "n" = ( /obj/structure/fluff/clockwork/blind_eye, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ratvar) "o" = ( /obj/structure/fluff/clockwork/alloy_shards/large, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ratvar) "p" = ( /obj/structure/fluff/clockwork/alloy_shards/medium, @@ -59,7 +59,7 @@ /area/ruin/unpowered/ratvar) "r" = ( /obj/structure/lattice, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ratvar) "s" = ( /obj/structure/fluff/clockwork/alloy_shards/large, @@ -67,7 +67,7 @@ /area/ruin/unpowered/ratvar) "t" = ( /obj/item/stack/sheet/bronze, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ratvar) "u" = ( /obj/structure/grille, @@ -76,7 +76,7 @@ "v" = ( /obj/structure/fluff/clockwork/alloy_shards/medium, /obj/structure/lattice, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ratvar) "w" = ( /obj/structure/grille/broken, @@ -109,11 +109,11 @@ /area/ruin/unpowered/ratvar) "D" = ( /obj/structure/grille, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ratvar) "E" = ( /obj/structure/fluff/clockwork/clockgolem_remains, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ratvar) "F" = ( /obj/structure/dead_ratvar, @@ -121,8 +121,22 @@ /area/ruin/unpowered/ratvar) "G" = ( /obj/item/stack/sheet/bronze/thirty, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/ratvar) +"I" = ( +/obj/structure/fluff/clockwork/alloy_shards/large, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, +/area/template_noop) +"J" = ( +/obj/structure/fluff/clockwork/alloy_shards/small, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, +/area/template_noop) +"K" = ( +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, +/area/ruin/unpowered/ratvar) +"L" = ( +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, +/area/template_noop) (1,1,1) = {" a @@ -138,10 +152,10 @@ a a a a -b +L s h -b +L a a a @@ -158,8 +172,8 @@ a a a a -o -b +I +L a h b @@ -184,7 +198,7 @@ a a a f -b +L l b v @@ -195,8 +209,8 @@ j j c l -b -b +L +L a a a @@ -221,7 +235,7 @@ j j p l -b +L h c r @@ -303,7 +317,7 @@ l c f f -b +L a "} (8,1,1) = {" @@ -328,7 +342,7 @@ l l l f -b +L a a "} @@ -352,10 +366,10 @@ b g l l -b -b -b -b +L +L +L +L a "} (10,1,1) = {" @@ -407,7 +421,7 @@ l l l l -b +L a "} (12,1,1) = {" @@ -444,7 +458,7 @@ l l l b -p +m s r h @@ -463,9 +477,9 @@ b a "} (14,1,1) = {" -b -b -b +L +L +L m l l @@ -486,12 +500,12 @@ l b b h -b +L "} (15,1,1) = {" -b -b -b +L +L +L l l l @@ -510,8 +524,8 @@ l l l l -b -b +L +L a "} (16,1,1) = {" @@ -541,9 +555,9 @@ f a "} (17,1,1) = {" -b -b -b +L +L +L l l l @@ -563,7 +577,7 @@ l r l l -b +L a "} (18,1,1) = {" @@ -590,7 +604,7 @@ h b b m -b +L "} (19,1,1) = {" b @@ -616,7 +630,7 @@ h r h b -b +L "} (20,1,1) = {" b @@ -716,8 +730,8 @@ b l l l -b -b +L +L w r b @@ -725,8 +739,8 @@ b (24,1,1) = {" a a -b -b +L +L l l l @@ -742,7 +756,7 @@ j j l l -c +J l l b @@ -751,7 +765,7 @@ a (25,1,1) = {" a a -b +L l l l @@ -777,7 +791,7 @@ a (26,1,1) = {" a a -b +L c b l @@ -795,7 +809,7 @@ l l c m -b +L a a a @@ -859,7 +873,7 @@ a a b b -f +K c b l @@ -871,7 +885,7 @@ l c o l -b +L a a a @@ -895,7 +909,7 @@ l b l f -b +L a a a diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_elephant_graveyard.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_elephant_graveyard.dmm index 1213c3684d7..157211daadb 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_elephant_graveyard.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_elephant_graveyard.dmm @@ -3,7 +3,7 @@ /turf/template_noop, /area/template_noop) "ab" = ( -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface) "ac" = ( /turf/closed/mineral/volcanic/lava_land_surface, @@ -155,7 +155,7 @@ "iE" = ( /obj/structure/barricade/wooden/crude, /obj/item/paper/fluff/ruins/elephant_graveyard, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/elephant_graveyard) "iR" = ( /obj/structure/statue/bone/skull/half{ @@ -165,7 +165,7 @@ /area/ruin/unpowered/elephant_graveyard) "jx" = ( /obj/machinery/power/shuttle_engine/propulsion, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/floor/plating/lavaland_atmos, /area/ruin/powered/graveyard_shuttle) "jK" = ( /obj/effect/decal/cleanable/blood/tracks{ @@ -319,6 +319,9 @@ /obj/effect/decal/cleanable/blood/old, /turf/open/misc/asteroid/basalt/wasteland, /area/ruin/unpowered/elephant_graveyard) +"wT" = ( +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, +/area/ruin/unpowered/elephant_graveyard) "xr" = ( /obj/effect/decal/cleanable/vomit, /obj/item/shovel, @@ -373,7 +376,7 @@ /turf/open/misc/asteroid/basalt/wasteland, /area/ruin/unpowered/elephant_graveyard) "Bu" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/elephant_graveyard) "Cn" = ( /obj/structure/flora/rock/style_random, @@ -385,7 +388,7 @@ /turf/open/misc/asteroid/basalt/wasteland, /area/ruin/unpowered/elephant_graveyard) "Cu" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface) "Di" = ( /obj/item/organ/lungs, @@ -432,7 +435,7 @@ /area/ruin/unpowered/elephant_graveyard) "Iy" = ( /obj/item/paper/fluff/ruins/elephant_graveyard, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface) "Iz" = ( /obj/structure/table, @@ -516,7 +519,7 @@ /area/ruin/unpowered/elephant_graveyard) "NO" = ( /obj/effect/decal/cleanable/dirt, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered/elephant_graveyard) "Oa" = ( /obj/effect/decal/cleanable/generic, @@ -686,12 +689,12 @@ at ab ab ab -ac -ac -ac -ac +wT +wT +wT +wT bf -ac +wT ab ab ab @@ -722,15 +725,15 @@ bf bf bf bf -ac -ac -ac -ac +wT +wT +wT +wT bf bf bf -ac -ac +wT +wT ab ab ab @@ -760,7 +763,7 @@ Oa bf bf bf -ac +wT bf bf bf @@ -768,8 +771,8 @@ bf bf bf bf -ac -ac +wT +wT ab ab aa @@ -805,9 +808,9 @@ bJ bf bf bf -ac -ac -ac +wT +wT +wT ab ab ab @@ -843,10 +846,10 @@ WF LR gB gB -ac -ac -ac -ac +wT +wT +wT +wT ab ab ab @@ -880,12 +883,12 @@ bf bf bf gB -ac -ac -ac -ac -ac -ac +wT +wT +wT +wT +wT +wT ab ab aa @@ -917,13 +920,13 @@ gB gB bf gB -ac -ac -ac -ac -ac -ac -ac +wT +wT +wT +wT +wT +wT +wT ab ab aa @@ -955,14 +958,14 @@ tf bf gB gB -ac -ac -ac -ac -ac -ac -ac -ac +wT +wT +wT +wT +wT +wT +wT +wT aa "} (10,1,1) = {" @@ -993,14 +996,14 @@ bf bf gB gB -ac -ac -ac -ac +wT +wT +wT +wT MF yy -ac -ac +wT +wT "} (11,1,1) = {" at @@ -1030,14 +1033,14 @@ vk bf bf dr -ac -ac -ac -ac +wT +wT +wT +wT ei gB gB -ac +wT "} (12,1,1) = {" at @@ -1067,14 +1070,14 @@ gB bf bf Ks -ac -ac -ac -ac -ac -ac +wT +wT +wT +wT +wT +wT Bu -ac +wT "} (13,1,1) = {" bf @@ -1104,14 +1107,14 @@ gB bf bf gB -ac -ac -ac -ac -ac -ac +wT +wT +wT +wT +wT +wT gB -ac +wT "} (14,1,1) = {" bf @@ -1142,13 +1145,13 @@ bf Xe dr gB -ac -ac -ac -ac -ac +wT +wT +wT +wT +wT gB -ac +wT "} (15,1,1) = {" bf @@ -1176,16 +1179,16 @@ gB gB Br bf -ac +wT gB gB dr -ac -ac -ac -ac +wT +wT +wT +wT Bu -ac +wT "} (16,1,1) = {" bf @@ -1213,14 +1216,14 @@ gB gB Br bf -ac -ac +wT +wT gB gB dr -ac -ac -ac +wT +wT +wT dr iE "} @@ -1251,13 +1254,13 @@ Xe Br bf bf -ac -ac +wT +wT gB Bu -ac -ac -ac +wT +wT +wT NO Ql "} @@ -1288,9 +1291,9 @@ gB Br Yq bf -ac -ac -ac +wT +wT +wT gB dr dr @@ -1325,15 +1328,15 @@ Br AT bf bf -ac -ac -ac -ac +wT +wT +wT +wT NO dr -ac -ac -ac +wT +wT +wT "} (20,1,1) = {" aa @@ -1361,23 +1364,23 @@ bf bf bf bf -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac +wT +wT +wT +wT +wT +wT +wT +wT +wT +wT "} (21,1,1) = {" aa aa ab -ac -ac +bf +bf bf UK dr @@ -1396,16 +1399,16 @@ bf bf bf bf -ac -ac -ac -ac -ac -ac -ac -ac -ac -ac +wT +wT +wT +wT +wT +wT +wT +wT +wT +wT ab ab "} @@ -1414,7 +1417,7 @@ aa aa ab ab -ac +bf bf UK gB @@ -1429,14 +1432,14 @@ bf bf bf bf -ac -ac -ac -ac -ac -ac -ac -ac +wT +wT +wT +wT +wT +wT +wT +wT ab ab ab diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_elite_tumor.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_elite_tumor.dmm index 81cef3facd9..6a55278a1a4 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_elite_tumor.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_elite_tumor.dmm @@ -4,10 +4,10 @@ /area/template_noop) "b" = ( /obj/structure/elite_tumor, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "c" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) (1,1,1) = {" diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_envy.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_envy.dmm index ed7a0aef9e2..b03596f03f7 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_envy.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_envy.dmm @@ -1,9 +1,9 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "a" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "b" = ( -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "c" = ( /turf/open/lava/smooth/lava_land_surface, @@ -66,7 +66,7 @@ /area/ruin/unpowered) "A" = ( /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) (1,1,1) = {" diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_gaia.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_gaia.dmm index 697a9a34e72..f7f9aa5d1cc 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_gaia.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_gaia.dmm @@ -88,7 +88,7 @@ /turf/open/misc/grass/lavaland, /area/ruin/unpowered/gaia) "w" = ( -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/ruin/unpowered/gaia) "x" = ( /obj/structure/flora/bush/sunny/style_random, diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_gas.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_gas.dmm index 790879899db..7e195ebcae8 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_gas.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_gas.dmm @@ -17,9 +17,7 @@ dir = 1 }, /obj/effect/decal/cleanable/dirt/dust, -/turf/open/floor/plating/lavaland_atmos{ - baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface - }, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/thelizardsgas_lavaland) "bT" = ( /obj/structure/window/reinforced/spawner/directional/west, @@ -125,7 +123,7 @@ /area/lavaland/surface/outdoors) "fF" = ( /obj/machinery/portable_atmospherics/canister, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "fH" = ( /obj/machinery/duct, @@ -254,7 +252,7 @@ /area/ruin/thelizardsgas_lavaland) "lI" = ( /obj/effect/spawner/random/structure/billboard/roadsigns, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "mn" = ( /obj/structure/sign/poster/official/plasma_effects/directional/east, @@ -351,7 +349,7 @@ /area/ruin/thelizardsgas_lavaland) "oD" = ( /obj/effect/spawner/random/trash/crushed_can, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "pp" = ( /obj/machinery/light/directional/south, @@ -418,7 +416,7 @@ /obj/machinery/portable_atmospherics/canister/plasma{ filled = 0.05 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "sY" = ( /obj/structure/table/reinforced, @@ -603,7 +601,7 @@ }, /area/ruin/thelizardsgas_lavaland) "Ao" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Bf" = ( /obj/effect/decal/cleanable/dirt/dust, @@ -685,9 +683,7 @@ dir = 8 }, /obj/effect/decal/cleanable/dirt/dust, -/turf/open/floor/plating/lavaland_atmos{ - baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface - }, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/thelizardsgas_lavaland) "CR" = ( /obj/structure/cable, @@ -766,9 +762,7 @@ dir = 4 }, /obj/effect/decal/cleanable/dirt/dust, -/turf/open/floor/plating/lavaland_atmos{ - baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface - }, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/thelizardsgas_lavaland) "Gg" = ( /obj/effect/decal/cleanable/dirt/dust, @@ -780,7 +774,7 @@ /area/ruin/thelizardsgas_lavaland) "Gu" = ( /obj/effect/spawner/random/structure/billboard/lizardsgas, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Gv" = ( /obj/machinery/duct, @@ -793,7 +787,7 @@ /area/ruin/thelizardsgas_lavaland) "GK" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/pink/hidden, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Hz" = ( /obj/structure/cable, @@ -808,7 +802,7 @@ /area/ruin/thelizardsgas_lavaland) "HB" = ( /obj/effect/spawner/random/trash/cigbutt, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "HI" = ( /obj/effect/decal/cleanable/dirt/dust, @@ -904,7 +898,7 @@ /obj/machinery/atmospherics/components/unary/portables_connector/visible{ dir = 8 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Kc" = ( /obj/effect/decal/cleanable/dirt/dust, @@ -1059,9 +1053,7 @@ }, /obj/structure/cable, /obj/effect/turf_decal/stripes/end, -/turf/open/floor/plating/lavaland_atmos{ - baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface - }, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/thelizardsgas_lavaland) "SL" = ( /obj/structure/cable, @@ -1129,7 +1121,7 @@ "UZ" = ( /obj/structure/sign/warning/fire/directional/north, /obj/machinery/atmospherics/pipe/smart/manifold4w/pink/hidden, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "VD" = ( /obj/machinery/duct, @@ -1179,7 +1171,7 @@ /obj/machinery/atmospherics/components/unary/passive_vent/layer4{ dir = 8 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Yx" = ( /obj/structure/cable, diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_gluttony.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_gluttony.dmm index 30690101246..96f20dae29d 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_gluttony.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_gluttony.dmm @@ -108,7 +108,7 @@ /obj/structure/stone_tile/surrounding_tile/burnt{ dir = 8 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "ie" = ( /obj/item/veilrender/vealrender, @@ -130,7 +130,7 @@ /obj/structure/stone_tile/surrounding_tile/cracked{ dir = 1 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "jM" = ( /turf/closed/indestructible/necropolis, @@ -182,7 +182,7 @@ /obj/structure/stone_tile/surrounding/cracked{ dir = 1 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "nT" = ( /turf/closed/indestructible/riveted/boss, @@ -315,7 +315,7 @@ /area/lavaland/surface/outdoors) "DH" = ( /obj/structure/headpike/bone, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "DY" = ( /obj/structure/stone_tile/center/burnt, @@ -391,7 +391,7 @@ /obj/structure/stone_tile/block/burnt{ dir = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "MH" = ( /turf/open/lava/smooth/lava_land_surface, @@ -400,7 +400,7 @@ /obj/structure/stone_tile/block/burnt{ dir = 8 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Ol" = ( /obj/effect/decal/cleanable/blood/footprints{ @@ -495,7 +495,7 @@ /turf/open/indestructible/necropolis, /area/ruin/powered/gluttony) "WR" = ( -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "XY" = ( /obj/effect/decal/cleanable/blood/footprints, @@ -518,7 +518,7 @@ /turf/open/indestructible/necropolis, /area/ruin/powered/gluttony) "Zu" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Zx" = ( /obj/structure/stone_tile/surrounding/cracked, diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_greed.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_greed.dmm index d138d1c39f2..8a539ef8854 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_greed.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_greed.dmm @@ -1,9 +1,9 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "a" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "b" = ( -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "c" = ( /turf/open/lava/smooth/lava_land_surface, diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_hermit.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_hermit.dmm index 49e24125657..b642034f2d6 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_hermit.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_hermit.dmm @@ -1,6 +1,6 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "a" = ( -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "b" = ( /turf/closed/mineral/volcanic/lava_land_surface, @@ -10,10 +10,10 @@ /area/ruin/powered) "e" = ( /obj/item/clothing/suit/space/orange, -/turf/open/misc/asteroid/basalt, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/powered) "f" = ( -/turf/open/misc/asteroid/basalt, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/powered) "g" = ( /turf/open/misc/asteroid{ @@ -57,7 +57,7 @@ /obj/item/seeds/plump, /obj/item/food/grown/mushroom/glowshroom, /obj/item/seeds/tower, -/turf/open/misc/asteroid/basalt, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/powered) "n" = ( /obj/machinery/hydroponics/soil, @@ -71,7 +71,7 @@ /obj/item/storage/bag/plants/portaseeder, /obj/item/storage/bag/ore, /obj/item/storage/medkit/regular, -/turf/open/misc/asteroid/basalt, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/powered) "q" = ( /obj/structure/glowshroom/single, @@ -81,10 +81,10 @@ /obj/structure/rack, /obj/item/pickaxe/emergency, /obj/item/tank/internals/oxygen, -/turf/open/misc/asteroid/basalt, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/powered) "s" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "t" = ( /turf/closed/wall/mineral/titanium/survival/pod, @@ -174,7 +174,7 @@ /area/ruin/powered) "M" = ( /obj/machinery/portable_atmospherics/canister/oxygen, -/turf/open/misc/asteroid/basalt, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/powered) "P" = ( /turf/template_noop, @@ -185,6 +185,9 @@ name = "dirt" }, /area/ruin/powered) +"T" = ( +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, +/area/ruin/powered) (1,1,1) = {" P @@ -264,7 +267,7 @@ P a a a -b +T c b t @@ -281,8 +284,8 @@ P a a a -b -b +T +T L n t @@ -299,7 +302,7 @@ a a a a -b +T m o o @@ -314,9 +317,9 @@ s "} (8,1,1) = {" a -b -b -b +T +T +T c f o @@ -332,7 +335,7 @@ s "} (9,1,1) = {" a -b +T f i g @@ -350,7 +353,7 @@ s "} (10,1,1) = {" a -b +T S j g @@ -360,7 +363,7 @@ f u o A -b +T P s s @@ -378,7 +381,7 @@ r c c c -b +T P P s @@ -386,14 +389,14 @@ s "} (12,1,1) = {" a -b -b +T +T k M -b -b -b -b +T +T +T +T a a P @@ -405,10 +408,10 @@ E (13,1,1) = {" a a -b -b -b -b +T +T +T +T a a a diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_mookvillage.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_mookvillage.dmm index 241b2b608f2..d6b15a15993 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_mookvillage.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_mookvillage.dmm @@ -1,10 +1,10 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "a" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "b" = ( /obj/structure/bonfire/prelit, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "c" = ( /turf/open/floor/wood/lavaland, @@ -13,12 +13,12 @@ /obj/structure/railing{ dir = 1 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "e" = ( /obj/structure/flora/ash/fireblossom, /mob/living/basic/mining/mook/worker/tribal_chief, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "f" = ( /obj/structure/chair/wood{ @@ -50,7 +50,7 @@ /area/lavaland/surface/outdoors) "l" = ( /obj/structure/flora/ash/fireblossom, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "m" = ( /obj/item/flashlight/lantern{ @@ -61,15 +61,15 @@ "n" = ( /obj/structure/flora/ash/fireblossom, /mob/living/basic/mining/mook/worker, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "o" = ( /obj/structure/railing/corner, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "p" = ( /obj/structure/ore_container/material_stand, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "q" = ( /obj/item/fishing_rod, @@ -81,27 +81,27 @@ /area/lavaland/surface/outdoors) "s" = ( /obj/effect/landmark/mook_village, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "t" = ( /obj/structure/chair/pew/left, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "u" = ( /obj/structure/railing, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "v" = ( /obj/structure/railing/corner{ dir = 8 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "w" = ( /obj/structure/railing{ dir = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "x" = ( /obj/structure/table/wood/shuttle_bar, @@ -114,11 +114,11 @@ /area/lavaland/surface/outdoors) "z" = ( /mob/living/basic/mining/mook/worker/bard, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "A" = ( /obj/structure/chair/pew/right, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "E" = ( /obj/structure/flora/grass/jungle/b, @@ -126,7 +126,7 @@ /area/lavaland/surface/outdoors) "F" = ( /obj/structure/chair/pew, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "G" = ( /obj/structure/bed/pod, @@ -137,23 +137,23 @@ /obj/structure/railing/corner{ dir = 1 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "I" = ( /mob/living/basic/mining/mook, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "J" = ( /obj/structure/railing{ dir = 8 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "M" = ( /obj/structure/chair/pew/right{ dir = 8 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "O" = ( /obj/structure/table/wood/shuttle_bar, @@ -163,39 +163,39 @@ /area/lavaland/surface/outdoors) "P" = ( /mob/living/basic/mining/mook/worker, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Q" = ( /obj/structure/flora/tree/jungle/style_5, /turf/open/misc/grass/jungle/lavaland, /area/lavaland/surface/outdoors) -"S" = ( -/obj/item/flashlight/lantern{ - start_on = 1 - }, -/turf/open/misc/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) "V" = ( /obj/structure/chair/pew{ dir = 8 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "W" = ( /obj/structure/flora/tree/jungle/style_3, /turf/open/misc/grass/jungle/lavaland, /area/lavaland/surface/outdoors) +"X" = ( +/obj/item/flashlight/lantern{ + start_on = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, +/area/lavaland/surface/outdoors) "Y" = ( /obj/structure/chair/pew/left{ dir = 8 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Z" = ( /obj/structure/railing/corner{ dir = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) (1,1,1) = {" @@ -228,7 +228,7 @@ a a a l -S +X a a a @@ -294,14 +294,14 @@ g c c a -S +X a a a a P a -S +X F a a @@ -493,7 +493,7 @@ h h h z -S +X l a a @@ -606,7 +606,7 @@ a a l a -S +X h m c diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_ore_vent.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_ore_vent.dmm index 6379b7f084b..1cdb5a564ab 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_ore_vent.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_ore_vent.dmm @@ -3,11 +3,11 @@ /turf/template_noop, /area/template_noop) "l" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "L" = ( /obj/structure/ore_vent/random, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) (1,1,1) = {" diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_phonebooth.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_phonebooth.dmm index 4cbf3478bc2..80e4d6811ea 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_phonebooth.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_phonebooth.dmm @@ -9,7 +9,7 @@ /turf/open/floor/iron/dark/smooth_edge, /area/ruin/powered/lavaland_phone_booth) "e" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/powered/lavaland_phone_booth) "k" = ( /obj/machinery/vending/snack/green{ @@ -32,7 +32,7 @@ "v" = ( /obj/structure/lattice, /obj/structure/billboard/Phone_booth, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/powered/lavaland_phone_booth) "z" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -62,7 +62,7 @@ /area/ruin/powered/lavaland_phone_booth) "V" = ( /obj/structure/lattice, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/powered/lavaland_phone_booth) "W" = ( /obj/machinery/vending/cigarette{ diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_pizzaparty.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_pizzaparty.dmm index b48b6f58928..ebdcfb4850d 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_pizzaparty.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_pizzaparty.dmm @@ -3,11 +3,11 @@ /turf/template_noop, /area/template_noop) "ab" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "ac" = ( /obj/structure/lattice, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "ad" = ( /turf/closed/wall, @@ -153,7 +153,7 @@ /area/ruin/unpowered) "hQ" = ( /obj/effect/decal/cleanable/blood/old, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "is" = ( /obj/effect/mapping_helpers/burnt_floor, @@ -496,7 +496,7 @@ "Fg" = ( /mob/living/basic/mining/goliath, /obj/effect/decal/cleanable/blood/old, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "FF" = ( /obj/effect/turf_decal/tile/yellow/diagonal_edge, @@ -516,7 +516,7 @@ /area/ruin/unpowered) "Jt" = ( /obj/item/stack/sheet/iron, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "KA" = ( /obj/structure/table/wood, @@ -609,7 +609,7 @@ "RP" = ( /obj/item/clothing/under/shorts/blue, /obj/effect/decal/cleanable/blood/old, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "RV" = ( /obj/structure/girder, @@ -631,7 +631,7 @@ /area/ruin/unpowered) "Sz" = ( /obj/structure/flora/ash/fireblossom, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "SQ" = ( /obj/item/clothing/shoes/sneakers/orange, diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_pride.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_pride.dmm index 6ed4b294d41..7178948a9af 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_pride.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_pride.dmm @@ -1,6 +1,6 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "a" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "c" = ( /turf/open/lava/smooth/lava_land_surface, diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_puzzle.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_puzzle.dmm index b9ccb545ca0..ce4c3ed6a03 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_puzzle.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_puzzle.dmm @@ -4,10 +4,10 @@ /area/template_noop) "b" = ( /obj/effect/sliding_puzzle/lavaland, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "c" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) (1,1,1) = {" diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_random_ripley.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_random_ripley.dmm index 4c82e520887..a1d6abf8f9d 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_random_ripley.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_random_ripley.dmm @@ -3,20 +3,20 @@ /turf/template_noop, /area/template_noop) "b" = ( -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "c" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "d" = ( /obj/vehicle/sealed/mecha/ripley/mining, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "e" = ( /obj/item/clothing/shoes/workboots/mining, /obj/item/clothing/under/rank/cargo/miner/lavaland, /obj/effect/decal/remains/human, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) (1,1,1) = {" diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm index c03669ad0b5..e7d01d08f6d 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm @@ -1,9 +1,9 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "aa" = ( -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "ab" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "ac" = ( /turf/closed/wall/r_wall, @@ -361,7 +361,6 @@ /obj/effect/turf_decal/trimline/green/line{ dir = 1 }, -/obj/structure/tank_holder/extinguisher, /turf/open/floor/mineral/plastitanium, /area/ruin/powered/seedvault) "bf" = ( @@ -491,7 +490,7 @@ /area/ruin/powered/seedvault) "bx" = ( /obj/effect/decal/cleanable/glass, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "by" = ( /obj/structure/disposalpipe/segment{ @@ -525,9 +524,6 @@ /obj/machinery/hydroponics/constructable/fullupgrade, /turf/open/floor/mineral/plastitanium, /area/ruin/powered/seedvault) -"bD" = ( -/turf/closed/wall/r_wall, -/area/lavaland/surface/outdoors) "ca" = ( /obj/machinery/atmospherics/components/tank/air{ dir = 4 @@ -542,7 +538,7 @@ /area/ruin/powered/seedvault) "eq" = ( /obj/effect/baseturf_helper/lava_land/surface, -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "hf" = ( /obj/structure/sink/directional/east, @@ -603,6 +599,11 @@ /obj/machinery/light/floor, /turf/open/floor/mineral/titanium/blue, /area/ruin/powered/seedvault) +"yq" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/extinguisher_cabinet/directional/north, +/turf/open/floor/mineral/titanium/blue, +/area/ruin/powered/seedvault) "Bb" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, /turf/open/floor/iron/freezer, @@ -694,7 +695,7 @@ aa aa aa ab -ab +aa aa aa aa @@ -718,7 +719,7 @@ ac ac ac ac -aa +ac aa aa aa @@ -739,7 +740,7 @@ OE ah ac ca -ac +ah ac ac ac @@ -817,7 +818,7 @@ bc rF ac ac -bD +ac aa "} (8,1,1) = {" @@ -854,7 +855,7 @@ aT ac ac ac -bb +yq bb aN aN diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_shuttle_wreckage.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_shuttle_wreckage.dmm index 36950aaa0ee..b81d20e262d 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_shuttle_wreckage.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_shuttle_wreckage.dmm @@ -1,7 +1,7 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "bl" = ( /obj/item/stack/sheet/iron/five, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "bw" = ( /obj/effect/decal/cleanable/glass, @@ -12,7 +12,7 @@ "cB" = ( /obj/effect/mapping_helpers/broken_floor, /obj/effect/decal/cleanable/rubble, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "dI" = ( /obj/machinery/door/airlock/public/glass{ @@ -27,20 +27,20 @@ /obj/effect/mapping_helpers/burnt_floor, /obj/effect/decal/cleanable/dirt/dust, /obj/effect/decal/cleanable/rubble, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "en" = ( /obj/effect/mob_spawn/corpse/human/charredskeleton, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "eQ" = ( /obj/item/shard/titanium, /obj/effect/decal/cleanable/glass, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "fy" = ( /obj/structure/door_assembly/door_assembly_shuttle, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "fz" = ( /obj/effect/mapping_helpers/broken_floor, @@ -49,9 +49,6 @@ initial_gas_mix = "LAVALAND_ATMOS" }, /area/ruin/unpowered) -"gP" = ( -/turf/closed/mineral/titanium/volcanic, -/area/ruin/unpowered) "hT" = ( /turf/closed/wall/mineral/titanium{ initial_gas_mix = "LAVALAND_ATMOS" @@ -67,16 +64,16 @@ /obj/structure/chair/comfy/shuttle{ dir = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "iU" = ( /obj/effect/mapping_helpers/broken_floor, /obj/effect/decal/cleanable/glass, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "ky" = ( /obj/structure/chair/comfy/shuttle, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "ld" = ( /obj/item/stack/sheet/mineral/titanium/fifty{ @@ -106,7 +103,7 @@ /area/ruin/unpowered) "py" = ( /obj/effect/decal/cleanable/ash, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "rn" = ( /turf/open/lava/smooth/lava_land_surface, @@ -114,29 +111,26 @@ "rr" = ( /obj/effect/decal/cleanable/dirt/dust, /obj/effect/decal/cleanable/glass, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "rE" = ( /obj/structure/chair/comfy/shuttle{ dir = 8 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "se" = ( /obj/structure/table, /obj/effect/decal/cleanable/ash, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "sE" = ( /obj/item/shard/titanium, -/turf/open/misc/asteroid/basalt/lava_land_surface, -/area/ruin/unpowered) -"sZ" = ( -/turf/closed/mineral/random/volcanic, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "tp" = ( /obj/item/stack/sheet/iron, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "tx" = ( /obj/machinery/light/small/directional/east, @@ -152,12 +146,9 @@ initial_gas_mix = "LAVALAND_ATMOS" }, /area/ruin/unpowered) -"uh" = ( -/turf/closed/mineral/random/volcanic, -/area/lavaland/surface) "uH" = ( /obj/effect/spawner/random/structure/crate, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "vf" = ( /obj/effect/mapping_helpers/broken_floor, @@ -167,19 +158,19 @@ /area/ruin/unpowered) "xz" = ( /obj/machinery/computer, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "yZ" = ( -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/ruin/unpowered) "zk" = ( /obj/effect/spawner/random/structure/crate, /obj/effect/decal/cleanable/glass, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "Bb" = ( /obj/effect/mapping_helpers/broken_floor, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "BT" = ( /obj/effect/mob_spawn/corpse/human/charredskeleton, @@ -189,7 +180,7 @@ /area/ruin/unpowered) "Cg" = ( /obj/effect/decal/cleanable/glass, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "CX" = ( /obj/item/stack/sheet/mineral/titanium, @@ -200,19 +191,19 @@ /area/ruin/unpowered) "Dq" = ( /obj/effect/mapping_helpers/burnt_floor, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "Dy" = ( /obj/item/shard/titanium, /obj/machinery/light/small/directional/east, /obj/effect/mapping_helpers/broken_floor, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "DL" = ( /obj/item/stack/sheet/mineral/titanium/fifty{ amount = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "DZ" = ( /obj/effect/mapping_helpers/burnt_floor, @@ -223,7 +214,7 @@ "Ee" = ( /obj/structure/extinguisher_cabinet/directional/east, /obj/item/stack/sheet/iron, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "Er" = ( /obj/effect/decal/cleanable/dirt, @@ -233,14 +224,14 @@ }, /area/ruin/unpowered) "Fq" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface) "FI" = ( /obj/machinery/power/shuttle_engine/heater, /turf/open/floor/plating/lavaland_atmos, /area/ruin/unpowered) "FL" = ( -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface) "FR" = ( /obj/effect/mapping_helpers/broken_floor, @@ -264,51 +255,48 @@ /area/ruin/unpowered) "GF" = ( /obj/structure/window/reinforced/shuttle/unanchored, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "GS" = ( /obj/item/stack/sheet/iron/five, /obj/effect/decal/cleanable/dirt/dust, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) -"GZ" = ( -/turf/closed/mineral/titanium/volcanic, -/area/lavaland/surface) "Hy" = ( /obj/machinery/computer/communications{ dir = 8 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "HM" = ( /obj/item/stack/sheet/mineral/titanium, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "JD" = ( /mob/living/basic/mining/goliath, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "JN" = ( /obj/item/shard/titanium, /obj/item/stack/sheet/mineral/titanium, /obj/effect/mapping_helpers/broken_floor, /obj/effect/decal/cleanable/glass, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "KN" = ( -/obj/structure/spawner/lavaland/legion, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/mob/living/basic/mining/tendril, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "Lz" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "LQ" = ( /mob/living/basic/mining/goldgrub, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "Ma" = ( /obj/effect/decal/cleanable/dirt/dust, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "NI" = ( /obj/structure/chair/comfy/shuttle{ @@ -322,7 +310,7 @@ "NS" = ( /obj/item/stack/sheet/iron, /obj/effect/mapping_helpers/broken_floor, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "Om" = ( /obj/effect/mapping_helpers/broken_floor, @@ -342,7 +330,7 @@ /obj/structure/chair/comfy/shuttle{ dir = 1 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "Pa" = ( /obj/structure/table, @@ -350,7 +338,7 @@ pixel_x = 2; pixel_y = 3 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "Qq" = ( /obj/effect/mapping_helpers/broken_floor, @@ -362,7 +350,7 @@ "Rm" = ( /obj/item/shard/titanium, /obj/effect/mapping_helpers/broken_floor, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "St" = ( /obj/structure/window/reinforced/shuttle, @@ -381,11 +369,11 @@ "Tt" = ( /obj/item/stack/sheet/iron, /obj/effect/decal/cleanable/glass, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "TF" = ( /obj/effect/decal/cleanable/rubble, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "TQ" = ( /obj/item/stack/sheet/iron, @@ -397,7 +385,7 @@ "Vs" = ( /obj/item/stack/sheet/mineral/titanium, /obj/effect/mapping_helpers/broken_floor, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "VN" = ( /obj/effect/mapping_helpers/burnt_floor, @@ -408,15 +396,13 @@ "XT" = ( /obj/item/stack/sheet/mineral/titanium, /obj/effect/decal/cleanable/glass, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "XU" = ( /obj/item/stack/sheet/mineral/titanium/fifty{ amount = 4 }, -/turf/open/floor/mineral/titanium/yellow{ - initial_gas_mix = "LAVALAND_ATMOS" - }, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/ruin/unpowered) "XZ" = ( /obj/structure/chair/comfy/shuttle{ @@ -428,7 +414,7 @@ /area/ruin/unpowered) "Zo" = ( /obj/effect/mob_spawn/corpse/human/legioninfested, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/unpowered) "Zq" = ( /obj/effect/mapping_helpers/burnt_floor, @@ -446,8 +432,8 @@ SV SV SV SV -GZ -GZ +FL +FL Fq Fq Fq @@ -467,8 +453,8 @@ SV SV SV FL -GZ -gP +FL +yZ yZ fy iU @@ -485,8 +471,8 @@ SV (3,1,1) = {" SV SV -uh -uh +FL +FL yZ hT hT @@ -506,8 +492,8 @@ SV "} (4,1,1) = {" SV -uh -sZ +FL +yZ hT ky HM @@ -655,13 +641,13 @@ yZ CX yZ yZ -uh +FL FL "} (11,1,1) = {" Fq -GZ -gP +FL +yZ bw Tt JD @@ -676,15 +662,15 @@ DZ XU FI Ga -uh -uh +FL +FL FL "} (12,1,1) = {" SV -GZ -gP -gP +FL +yZ +yZ VN Ee Hy @@ -698,14 +684,14 @@ oE yZ yZ FL -uh -uh +FL +FL SV "} (13,1,1) = {" SV -GZ -gP +FL +yZ Lz py hT @@ -726,7 +712,7 @@ SV "} (14,1,1) = {" SV -GZ +FL Fq Lz lu @@ -737,7 +723,7 @@ JN Dy On Om -GZ +FL FL FL SV @@ -758,8 +744,8 @@ XT yZ St St -gP -GZ +yZ +FL SV SV SV @@ -779,8 +765,8 @@ py St yZ FL -GZ -GZ +FL +FL SV SV SV @@ -840,9 +826,9 @@ SV SV FL FL -uh -uh -uh +FL +FL +FL FL FL SV @@ -863,8 +849,8 @@ SV SV SV FL -uh -uh +FL +FL FL SV SV diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_survivalpod.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_survivalpod.dmm index 4894dbce32b..9e01f5f0063 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_survivalpod.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_survivalpod.dmm @@ -3,7 +3,7 @@ /turf/template_noop, /area/template_noop) "b" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "c" = ( /obj/effect/turf_decal/mining, @@ -40,7 +40,7 @@ /area/ruin/powered) "j" = ( /obj/effect/decal/cleanable/blood/drip, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "k" = ( /obj/machinery/sleeper/survival_pod, @@ -60,12 +60,12 @@ /area/ruin/powered) "n" = ( /obj/effect/decal/cleanable/blood, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "o" = ( /obj/effect/decal/cleanable/blood, /obj/effect/mob_spawn/corpse/goliath, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "p" = ( /obj/structure/table/survival_pod, @@ -92,7 +92,7 @@ /area/ruin/powered) "s" = ( /obj/effect/decal/cleanable/blood/footprints, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "t" = ( /obj/effect/decal/cleanable/blood/footprints{ @@ -106,14 +106,14 @@ dir = 8 }, /obj/effect/decal/cleanable/blood/drip, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "v" = ( /obj/effect/decal/cleanable/blood/footprints{ dir = 8 }, /obj/effect/decal/cleanable/blood/footprints, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "w" = ( /obj/effect/turf_decal/mining/survival{ @@ -126,7 +126,7 @@ /obj/effect/decal/cleanable/blood/footprints{ dir = 1 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "y" = ( /obj/effect/turf_decal/mining/survival{ @@ -138,12 +138,12 @@ /obj/effect/decal/cleanable/blood/footprints{ dir = 8 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "A" = ( /obj/effect/decal/cleanable/blood/footprints, /obj/effect/decal/cleanable/blood/drip, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) (1,1,1) = {" diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm index 29e0bd76c93..dd1151ee4fa 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm @@ -1898,7 +1898,7 @@ /area/ruin/syndicate_lava_base/testlab) "pa" = ( /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "pe" = ( /obj/effect/decal/cleanable/dirt, @@ -2068,7 +2068,7 @@ dir = 1 }, /obj/structure/disposalpipe/trunk, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/ruin/syndicate_lava_base/virology) "rC" = ( /obj/machinery/door/firedoor, @@ -2111,7 +2111,7 @@ /turf/open/floor/engine/co2, /area/ruin/syndicate_lava_base/engineering) "si" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "sl" = ( /obj/effect/decal/cleanable/dirt, @@ -4268,7 +4268,7 @@ key = "mistake" }, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "Wv" = ( /obj/effect/decal/cleanable/dirt, diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_ufo_crash.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_ufo_crash.dmm index 372731e7223..d01dc346b2b 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_ufo_crash.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_ufo_crash.dmm @@ -1,9 +1,9 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "a" = ( -/turf/closed/mineral/volcanic/lava_land_surface, -/area/lavaland/surface/outdoors) +/turf/template_noop, +/area/template_noop) "b" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "c" = ( /turf/closed/wall/mineral/abductor, @@ -11,6 +11,9 @@ "d" = ( /turf/closed/wall/mineral/abductor, /area/ruin/unpowered) +"g" = ( +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, +/area/lavaland/surface/outdoors) "j" = ( /obj/machinery/abductor/experiment{ team_number = 100 @@ -105,9 +108,9 @@ a a a a -a -a -a +g +g +g a a "} @@ -115,53 +118,53 @@ a a a a -a -a -a -a -a -a +g +g +g +g +g +g a "} (3,1,1) = {" a a -a +g c -a -a -a -a -a -a +g +g +g +g +g +g "} (4,1,1) = {" a -a +g c d -a -a -a -a -a -a +g +g +g +g +g +g "} (5,1,1) = {" a -a +g d j k k -a +g y d -a +g "} (6,1,1) = {" a -a +g d k o @@ -169,11 +172,11 @@ s v z d -a +g "} (7,1,1) = {" -a -a +g +g d l p @@ -181,11 +184,11 @@ k w A d -a +g "} (8,1,1) = {" -a -a +g +g c d q @@ -193,11 +196,11 @@ t q d c -a +g "} (9,1,1) = {" -a -a +g +g b c d @@ -205,67 +208,67 @@ d d c b -a +g "} (10,1,1) = {" a -a +g b b b b b b -a -a +g +g "} (11,1,1) = {" -a -a +g +g b b b b b b -a -a +g +g "} (12,1,1) = {" -a -a +g +g b b b b b b -a -a +g +g "} (13,1,1) = {" a -a +g b b b b b b -a -a +g +g "} (14,1,1) = {" a -a +g b b b b b b -a -a +b +g "} (15,1,1) = {" a @@ -276,7 +279,7 @@ b b b b -a +g a "} (16,1,1) = {" @@ -288,7 +291,7 @@ b b b b -a +g a "} (17,1,1) = {" @@ -300,13 +303,13 @@ b b b b -a +g a "} (18,1,1) = {" a a -b +a b b b @@ -336,7 +339,7 @@ b b b b -a +b a "} (21,1,1) = {" diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_watcher_grave.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_watcher_grave.dmm index 99af5bdced4..6496cdcb2b5 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_watcher_grave.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_watcher_grave.dmm @@ -1,6 +1,6 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "a" = ( -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "b" = ( /obj/structure/stone_tile/surrounding_tile, @@ -35,9 +35,6 @@ /obj/effect/mapping_helpers/bombable_wall, /turf/closed/indestructible/riveted/boss/wasteland, /area/lavaland/surface/outdoors) -"l" = ( -/turf/closed/mineral/gibtonite/volcanic, -/area/lavaland/surface/outdoors) "m" = ( /turf/open/chasm/lavaland, /area/lavaland/surface/outdoors) @@ -56,7 +53,7 @@ /obj/structure/stone_tile/cracked{ pixel_x = 16 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "u" = ( /obj/structure/flora/ash/stem_shroom, @@ -64,7 +61,7 @@ /area/lavaland/surface/outdoors) "v" = ( /obj/effect/mob_spawn/corpse/watcher/crushed, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "y" = ( /obj/structure/stone_tile/block/cracked{ @@ -91,7 +88,7 @@ /area/lavaland/surface/outdoors) "E" = ( /obj/structure/stone_tile/cracked, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "I" = ( /turf/template_noop, @@ -100,11 +97,11 @@ /obj/structure/stone_tile/slab/cracked{ dir = 4 }, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "M" = ( /obj/structure/flora/ash/fireblossom, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "R" = ( /turf/closed/indestructible/riveted/boss/wasteland, @@ -115,7 +112,7 @@ /turf/open/misc/asteroid/basalt/wasteland, /area/lavaland/surface/outdoors) "W" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) (1,1,1) = {" @@ -152,7 +149,7 @@ I I I I -l +a a a a @@ -225,7 +222,7 @@ I "} (8,1,1) = {" I -l +a a R y @@ -265,7 +262,7 @@ h c R a -l +a I "} (11,1,1) = {" diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_wizard.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_wizard.dmm index fb0a070b894..dd770bb660a 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_wizard.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_wizard.dmm @@ -1,16 +1,16 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "a" = ( -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "b" = ( -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "c" = ( /turf/template_noop, /area/template_noop) "d" = ( /obj/structure/stone_tile/slab, -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "e" = ( /obj/structure/stone_tile, @@ -283,7 +283,7 @@ "F" = ( /obj/structure/stone_tile/slab, /obj/effect/mapping_helpers/no_lava, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "G" = ( /turf/closed/indestructible/riveted/boss/see_through, @@ -302,15 +302,15 @@ /area/lavaland/surface/outdoors) "I" = ( /obj/structure/stone_tile/slab/cracked, -/turf/closed/mineral/volcanic/lava_land_surface, +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "J" = ( /obj/structure/fluff/divine/convertaltar, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) "K" = ( /mob/living/basic/dark_wizard, -/turf/open/misc/asteroid/basalt/lava_land_surface, +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace, /area/lavaland/surface/outdoors) (1,1,1) = {" diff --git a/_maps/RandomRuins/SpaceRuins/bus.dmm b/_maps/RandomRuins/SpaceRuins/bus.dmm index 177654f63ad..b725897aa36 100644 --- a/_maps/RandomRuins/SpaceRuins/bus.dmm +++ b/_maps/RandomRuins/SpaceRuins/bus.dmm @@ -295,6 +295,10 @@ }, /turf/open/misc/asteroid/airless, /area/ruin/space) +"FD" = ( +/obj/item/clothing/head/costume/paper_hat/savior, +/turf/open/misc/asteroid/airless, +/area/ruin/space) "FZ" = ( /obj/effect/decal/cleanable/dirt, /obj/item/toy/plush/awakenedplushie{ @@ -501,7 +505,7 @@ ab yY yY yY -yY +FD OD yY Ne diff --git a/_maps/RandomRuins/SpaceRuins/hauntedtradingpost.dmm b/_maps/RandomRuins/SpaceRuins/hauntedtradingpost.dmm index 349d32e62a3..dd93e77a597 100644 --- a/_maps/RandomRuins/SpaceRuins/hauntedtradingpost.dmm +++ b/_maps/RandomRuins/SpaceRuins/hauntedtradingpost.dmm @@ -813,9 +813,9 @@ "hf" = ( /obj/structure/cable/layer1, /obj/structure/sign/poster/contraband/syndicate_pistol/directional/west, -/mob/living/simple_animal/bot/secbot{ +/mob/living/basic/bot/secbot{ faction = list("Syndicate"); - bot_cover_flags = 4; + bot_access_flags = 4; baton_type = /obj/item/melee/baton/security/cattleprod; name = "\improper Syndicate Securitron"; desc = "A little security robot, reprogrammed by the syndicate. He looks downright surly."; diff --git a/_maps/RandomZLevels/heretic.dmm b/_maps/RandomZLevels/heretic.dmm index 69266c7c2e3..5c9389cf0fb 100644 --- a/_maps/RandomZLevels/heretic.dmm +++ b/_maps/RandomZLevels/heretic.dmm @@ -56,12 +56,13 @@ /turf/open/floor/iron, /area/awaymission/caves/heretic_laboratory_clean) "ao" = ( -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack{ - pixel_y = 9; - pixel_x = 15; - anchored = 1; - name = "Sam Site Missle rack" +/obj/structure/railing{ + dir = 1 }, +/obj/effect/turf_decal/stripes{ + dir = 1 + }, +/obj/machinery/deployable_turret/hmg, /turf/open/floor/iron/large, /area/awaymission/beach/heretic) "aq" = ( @@ -329,6 +330,14 @@ /obj/effect/blessing/invisible, /turf/open/floor/iron/small, /area/awaymission/caves/heretic_laboratory) +"bK" = ( +/obj/structure/fluff/sat_dish{ + dir = 4; + pixel_x = -8; + pixel_y = -1 + }, +/turf/open/floor/iron/large, +/area/awaymission/beach/heretic) "bN" = ( /obj/effect/spawner/structure/window, /turf/open/floor/plating, @@ -1611,7 +1620,7 @@ /turf/closed/wall/mineral/titanium, /area/awaymission/beach/heretic) "iw" = ( -/obj/effect/turf_decal/trimline/red/filled/end, +/obj/effect/turf_decal/trimline/yellow/filled, /turf/open/floor/iron/large, /area/awaymission/beach/heretic) "ix" = ( @@ -1669,6 +1678,11 @@ /obj/effect/mapping_helpers/airlock/access/all/medical, /turf/open/floor/iron/freezer, /area/awaymission/caves/heretic_laboratory) +"iK" = ( +/obj/machinery/deployable_turret/naval_cannon, +/obj/effect/turf_decal/trimline/yellow/filled, +/turf/open/floor/iron/large, +/area/awaymission/beach/heretic) "iL" = ( /obj/structure/fluff/tram_rail/anchor{ dir = 1 @@ -2074,6 +2088,16 @@ /obj/machinery/light/directional/east, /turf/open/floor/iron, /area/awaymission/caves/heretic_laboratory_clean) +"kS" = ( +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack{ + pixel_y = 9; + pixel_x = 15; + anchored = 1; + name = "SAM site missile rack" + }, +/obj/effect/turf_decal/trimline/red/arrow_cw, +/turf/open/floor/iron/large, +/area/awaymission/beach/heretic) "kV" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -2331,6 +2355,11 @@ "mv" = ( /turf/open/misc/beach/sand, /area/awaymission/caves/heretic_laboratory_clean) +"mA" = ( +/obj/machinery/deployable_turret/naval_cannon, +/obj/effect/turf_decal/trimline/yellow/filled/arrow_cw, +/turf/open/floor/iron/large, +/area/awaymission/beach/heretic) "mC" = ( /obj/machinery/power/rtg/lavaland, /obj/structure/window/reinforced/plasma/spawner/directional/west, @@ -2801,6 +2830,22 @@ }, /turf/open/floor/iron/white/textured_large, /area/awaymission/beach/heretic) +"oV" = ( +/obj/structure/rack, +/obj/item/ammo_casing/mm40{ + pixel_x = 6; + pixel_y = 0 + }, +/obj/item/ammo_casing/mm40{ + pixel_x = 2; + pixel_y = 0 + }, +/obj/item/ammo_casing/mm40{ + pixel_x = -2; + pixel_y = 0 + }, +/turf/open/floor/iron/large, +/area/awaymission/beach/heretic) "oW" = ( /obj/structure/filingcabinet{ pixel_x = -6; @@ -3600,6 +3645,13 @@ /obj/item/radio/intercom/mi13/directional/south, /turf/open/floor/iron, /area/awaymission/caves/heretic_laboratory_clean) +"sP" = ( +/obj/structure/ladder{ + name = "busted ladder hatch"; + desc = "A sturdy metal ladder that used to lead to the bottom part of the ship. It's completely broken and the hatch is welded shut." + }, +/turf/open/floor/plating, +/area/awaymission/caves/heretic_laboratory_clean) "sS" = ( /obj/effect/turf_decal/siding/wood/corner{ dir = 4 @@ -4119,11 +4171,13 @@ /turf/open/floor/engine, /area/awaymission/caves/heretic_laboratory) "vI" = ( -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack{ - pixel_y = 8; - pixel_x = -15; - anchored = 1; - name = "Sam Site Missle rack" +/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 = 0; + pixel_x = 0 }, /turf/open/floor/iron/large, /area/awaymission/beach/heretic) @@ -4264,6 +4318,16 @@ }, /turf/open/floor/plating, /area/awaymission/beach/heretic) +"wv" = ( +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack{ + pixel_y = 8; + pixel_x = -15; + anchored = 1; + name = "SAM site missile rack" + }, +/obj/effect/turf_decal/trimline/red/arrow_ccw, +/turf/open/floor/iron/large, +/area/awaymission/beach/heretic) "wy" = ( /obj/machinery/light/directional/west, /obj/effect/turf_decal/tile/green/anticorner/contrasted{ @@ -5285,6 +5349,10 @@ /obj/effect/turf_decal/trimline/blue/filled/line, /turf/open/floor/iron/white/smooth_large, /area/awaymission/caves/heretic_laboratory) +"BA" = ( +/obj/effect/turf_decal/trimline/yellow/filled/arrow_ccw, +/turf/open/floor/iron/large, +/area/awaymission/beach/heretic) "BE" = ( /obj/machinery/teleport/station{ name = "Forcefield generator" @@ -5451,6 +5519,10 @@ /obj/effect/turf_decal/box, /turf/open/floor/iron/white/smooth_large, /area/awaymission/caves/heretic_laboratory) +"CF" = ( +/obj/effect/turf_decal/trimline/yellow/line, +/turf/open/floor/iron/large, +/area/awaymission/beach/heretic) "CG" = ( /obj/effect/turf_decal/tile/yellow/anticorner/contrasted, /obj/effect/blessing/invisible, @@ -5831,12 +5903,19 @@ /turf/open/floor/iron/white, /area/awaymission/caves/heretic_laboratory) "EP" = ( -/obj/machinery/deployable_turret/hmg, -/obj/structure/railing{ - dir = 1 +/obj/effect/turf_decal/trimline/yellow/filled, +/obj/structure/rack, +/obj/item/ammo_casing/mm40{ + pixel_x = 6; + pixel_y = 0 }, -/obj/effect/turf_decal/stripes{ - dir = 1 +/obj/item/ammo_casing/mm40{ + pixel_x = 2; + pixel_y = 0 + }, +/obj/item/ammo_casing/mm40{ + pixel_x = -2; + pixel_y = 0 }, /turf/open/floor/iron/large, /area/awaymission/beach/heretic) @@ -6284,13 +6363,7 @@ /turf/open/floor/iron/small, /area/awaymission/caves/heretic_laboratory) "GR" = ( -/obj/effect/turf_decal/trimline/red/arrow_cw, -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack{ - pixel_y = 9; - pixel_x = 15; - anchored = 1; - name = "Sam Site Missle rack" - }, +/obj/effect/turf_decal/trimline/yellow/filled/end, /turf/open/floor/iron/large, /area/awaymission/beach/heretic) "GT" = ( @@ -9201,12 +9274,8 @@ /turf/open/floor/engine, /area/awaymission/caves/heretic_laboratory) "Wz" = ( -/obj/effect/turf_decal/trimline/red/arrow_ccw, -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack{ - pixel_y = 8; - pixel_x = -15; - anchored = 1; - name = "Sam Site Missle rack" +/obj/effect/turf_decal/trimline/red/filled/end{ + dir = 1 }, /turf/open/floor/iron/large, /area/awaymission/beach/heretic) @@ -9425,7 +9494,7 @@ dir = 5 }, /obj/machinery/camera/directional/east{ - network = list("ss13","medbay"); + network = list("heretic_gate"); c_tag = "Medical - Surgery B" }, /obj/structure/disposalpipe/trunk{ @@ -9827,7 +9896,11 @@ /turf/open/floor/iron/dark, /area/awaymission/caves/heretic_laboratory) "ZP" = ( -/obj/effect/turf_decal/trimline/red/filled, +/obj/structure/fluff/sat_dish{ + dir = 8; + pixel_x = 8; + pixel_y = -1 + }, /turf/open/floor/iron/large, /area/awaymission/beach/heretic) "ZQ" = ( @@ -50509,11 +50582,11 @@ nI nI nI nI -SY -hY -hY -hY +ao hY +Wz +xH +xH xl xl xl @@ -50530,12 +50603,12 @@ xl xl xl BY -xH -xH -ZP +EP iw -hY -hY +iw +iw +iK +GR oo oo kI @@ -50768,8 +50841,8 @@ nI nI pB hY -hY -hY +kS +ZP hY xl Kx @@ -50787,11 +50860,11 @@ IP kw ZM BY +oV hY hY -ao -GR hY +BA hY hY hY @@ -51024,16 +51097,16 @@ nI nI nI nI -EP -hY -hY +SY +Gh +Mj hY xl nL vu gi vu -vu +sP pr xl md @@ -51044,16 +51117,16 @@ IP Yy KO BY +oV hY hY -Gh -Mj -hY -hY +hY +CF hY hY hY hY +vI nR nI nI @@ -51282,8 +51355,8 @@ nI nI Hi hY -hY -hY +wv +bK hY xl Ew @@ -51301,11 +51374,11 @@ IP FF Kk BY +oV hY hY -vI -Wz hY +mA hY hY hY @@ -51537,11 +51610,11 @@ nI nI nI nI -SY -hY -hY -hY +ao hY +Wz +xH +xH xl xl xl @@ -51558,12 +51631,12 @@ xl xl xl BY -xH -xH -ZP +EP iw -hY -hY +iw +iw +iw +GR VQ VQ CC diff --git a/_maps/RandomZLevels/research.dmm b/_maps/RandomZLevels/research.dmm index c3513c00bfc..66e00db43a6 100644 --- a/_maps/RandomZLevels/research.dmm +++ b/_maps/RandomZLevels/research.dmm @@ -1678,7 +1678,7 @@ /turf/open/floor/iron/white, /area/awaymission/research/interior/security) "ij" = ( -/mob/living/simple_animal/bot/secbot/genesky, +/mob/living/basic/bot/secbot/genesky, /obj/effect/turf_decal/tile/red/half/contrasted{ dir = 1 }, diff --git a/_maps/map_files/CatwalkStation/CatwalkStation_2023.dmm b/_maps/map_files/CatwalkStation/CatwalkStation_2023.dmm index b35fef2b070..881a960774c 100644 --- a/_maps/map_files/CatwalkStation/CatwalkStation_2023.dmm +++ b/_maps/map_files/CatwalkStation/CatwalkStation_2023.dmm @@ -3967,6 +3967,10 @@ /obj/structure/lattice/catwalk, /turf/open/openspace, /area/station/hallway/primary/fore) +"bbC" = ( +/obj/effect/spawner/random/gizmo, +/turf/open/floor/engine, +/area/station/science/auxlab/firing_range) "bbV" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/power/apc/auto_name/directional/west, @@ -4231,12 +4235,6 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/catwalk_floor/iron, /area/station/hallway/primary/central) -"bex" = ( -/obj/structure/disposalpipe/segment{ - dir = 10 - }, -/turf/open/floor/plating, -/area/station/maintenance/starboard/upper) "beA" = ( /obj/effect/turf_decal/stripes{ dir = 1 @@ -6931,6 +6929,16 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/port) +"bOF" = ( +/obj/item/radio/intercom/directional/south, +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 6 + }, +/obj/structure/railing{ + dir = 1 + }, +/turf/open/floor/iron/textured, +/area/station/cargo/storage) "bOI" = ( /obj/effect/turf_decal/tile/red/fourcorners, /turf/open/floor/iron/dark, @@ -7039,13 +7047,13 @@ /turf/open/floor/iron/white, /area/station/medical/medbay/central) "bPN" = ( -/obj/structure/table, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/disposalpipe/sorting/mail{ dir = 1 }, /obj/effect/mapping_helpers/mail_sorting/science/xenobiology, +/obj/machinery/gizmo/toggle/tucker_tubes, /turf/open/floor/iron/dark/smooth_large, /area/station/science/explab) "bPO" = ( @@ -10041,11 +10049,13 @@ /turf/open/openspace, /area/station/engineering/lobby) "cCN" = ( -/obj/machinery/newscaster/directional/south, /obj/machinery/conveyor{ dir = 8; id = "mining" }, +/obj/machinery/bouldertech/refinery{ + dir = 4 + }, /turf/open/floor/iron/textured, /area/station/cargo/storage) "cCX" = ( @@ -14161,6 +14171,9 @@ /obj/structure/railing{ dir = 8 }, +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 4 + }, /turf/open/floor/iron/textured, /area/station/cargo/storage) "dKX" = ( @@ -19452,6 +19465,14 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/dark/smooth_large, /area/station/science/xenobiology) +"fiR" = ( +/obj/machinery/camera/autoname/directional/south, +/obj/effect/turf_decal/trimline/brown/filled/line, +/obj/structure/railing{ + dir = 1 + }, +/turf/open/floor/iron/textured, +/area/station/cargo/storage) "fiZ" = ( /obj/structure/showcase/machinery/oldpod{ desc = "An old NT branded sleeper, decommissioned after the lead acetate incident. None of the functional machinery remains inside."; @@ -30028,11 +30049,13 @@ /turf/open/floor/catwalk_floor, /area/station/maintenance/starboard/fore) "hXr" = ( -/obj/machinery/firealarm/directional/south, /obj/machinery/conveyor{ dir = 8; id = "mining" }, +/obj/machinery/bouldertech/refinery/smelter{ + dir = 4 + }, /turf/open/floor/iron/textured, /area/station/cargo/storage) "hXT" = ( @@ -32684,7 +32707,7 @@ /area/station/commons/dorms) "iGo" = ( /obj/structure/disposalpipe/trunk/multiz/down{ - dir = 1 + dir = 8 }, /turf/open/floor/plating, /area/station/maintenance/starboard/upper) @@ -45414,6 +45437,12 @@ }, /turf/open/floor/iron/textured, /area/station/command/eva) +"mbh" = ( +/obj/machinery/firealarm/directional/south, +/obj/effect/turf_decal/trimline/brown/filled/line, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/textured, +/area/station/cargo/storage) "mbj" = ( /obj/machinery/door/airlock/external, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ @@ -50552,6 +50581,9 @@ dir = 6; id = "mining" }, +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 4 + }, /turf/open/floor/iron/textured, /area/station/cargo/storage) "nwT" = ( @@ -56150,6 +56182,12 @@ /obj/machinery/light_switch/directional/east, /turf/open/floor/iron/dark/smooth_large, /area/station/tcommsat/server) +"oTH" = ( +/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, +/area/station/cargo/storage) "oTK" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/button/door/directional/east{ @@ -59608,13 +59646,13 @@ /turf/open/floor/iron/kitchen_coldroom/freezerfloor, /area/station/service/kitchen/coldroom) "pQI" = ( -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 10 - }, /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 8 + }, /turf/open/floor/iron/textured, /area/station/cargo/storage) "pQK" = ( @@ -65847,7 +65885,7 @@ /obj/effect/turf_decal/siding/dark{ dir = 8 }, -/mob/living/simple_animal/bot/secbot/pingsky, +/mob/living/basic/bot/secbot/pingsky, /obj/structure/cable/layer3, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -66024,12 +66062,10 @@ /turf/open/floor/plating, /area/station/maintenance/starboard/aft) "rCF" = ( -/obj/machinery/camera/autoname/directional/south, /obj/machinery/conveyor{ dir = 8; id = "mining" }, -/obj/machinery/bouldertech/refinery/smelter, /turf/open/floor/iron/textured, /area/station/cargo/storage) "rCP" = ( @@ -67426,6 +67462,11 @@ /obj/effect/decal/cleanable/blood/old, /turf/open/floor/plating, /area/station/security/interrogation) +"rXI" = ( +/obj/structure/extinguisher_cabinet/directional/south, +/obj/effect/turf_decal/trimline/brown/filled/line, +/turf/open/floor/iron/textured, +/area/station/cargo/storage) "rXL" = ( /turf/open/openspace, /area/station/science/robotics/lab) @@ -70236,7 +70277,6 @@ /turf/open/openspace, /area/station/hallway/primary/central) "sLK" = ( -/obj/structure/extinguisher_cabinet/directional/south, /obj/effect/turf_decal/delivery, /obj/effect/decal/cleanable/rubble, /turf/open/floor/iron/dark/smooth_large, @@ -75350,14 +75390,6 @@ /obj/structure/railing, /turf/open/floor/engine/hull/air, /area/station/maintenance/port) -"ucf" = ( -/obj/machinery/light/directional/south, -/obj/machinery/conveyor{ - dir = 8; - id = "mining" - }, -/turf/open/floor/iron/textured, -/area/station/cargo/storage) "ucp" = ( /obj/machinery/power/apc/auto_name/directional/north, /obj/structure/cable, @@ -75416,12 +75448,13 @@ /turf/open/openspace, /area/station/maintenance/starboard/aft/upper) "ucX" = ( -/obj/item/radio/intercom/directional/south, /obj/machinery/conveyor{ dir = 10; id = "mining" }, -/obj/machinery/bouldertech/refinery, +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 4 + }, /turf/open/floor/iron/textured, /area/station/cargo/storage) "ucZ" = ( @@ -76800,6 +76833,15 @@ /obj/machinery/duct, /turf/open/floor/wood/large, /area/station/commons/dorms) +"uvA" = ( +/obj/effect/turf_decal/trimline/brown/filled/line, +/obj/structure/railing{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/directional/south, +/turf/open/floor/iron/textured, +/area/station/cargo/storage) "uvF" = ( /obj/structure/railing/corner{ dir = 4 @@ -80086,6 +80128,18 @@ /obj/structure/cable, /turf/open/openspace, /area/station/maintenance/starboard/upper) +"vmm" = ( +/obj/item/stack/ducts, +/obj/item/stack/ducts{ + pixel_y = -8; + pixel_x = -3 + }, +/obj/item/stack/ducts{ + pixel_y = 4; + pixel_x = 2 + }, +/turf/open/floor/plating, +/area/station/maintenance/starboard/upper) "vmu" = ( /obj/machinery/door/airlock/grunge, /obj/effect/mapping_helpers/airlock/access/any/command/ai_upload, @@ -88963,6 +89017,12 @@ /obj/effect/turf_decal/trimline/brown/arrow_ccw, /turf/open/floor/iron, /area/station/hallway/primary/starboard) +"xCP" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 10 + }, +/turf/open/floor/iron/textured, +/area/station/cargo/storage) "xCS" = ( /obj/item/clothing/suit/jacket/straight_jacket, /obj/structure/closet, @@ -89334,6 +89394,11 @@ }, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) +"xHg" = ( +/obj/machinery/newscaster/directional/south, +/obj/effect/turf_decal/trimline/brown/filled/line, +/turf/open/floor/iron/textured, +/area/station/cargo/storage) "xHi" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/iron, @@ -89584,7 +89649,7 @@ /obj/machinery/holopad/secure{ pixel_y = -1 }, -/mob/living/simple_animal/bot/secbot/beepsky/armsky, +/mob/living/basic/bot/secbot/beepsky/armsky, /obj/effect/turf_decal/trimline/red/warning{ dir = 4 }, @@ -90682,7 +90747,7 @@ /obj/effect/mapping_helpers/mail_sorting/service/library, /obj/effect/mapping_helpers/mail_sorting/service/chapel, /obj/effect/mapping_helpers/mail_sorting/service/dormitories, -/mob/living/simple_animal/bot/secbot/beepsky/officer, +/mob/living/basic/bot/secbot/beepsky/officer, /obj/machinery/navbeacon{ codes_txt = "patrol;next_patrol=10-Vault"; location = "9-Bridge" @@ -193926,7 +193991,7 @@ qSk amt pON soU -sOn +bbC pOR ezP gfz @@ -199823,9 +199888,9 @@ pSB lGA xSg pQI +xCP blo ayK -lwA vmk lwA lwA @@ -200080,10 +200145,10 @@ avc mIp iwQ sLK +rXI wrT toR wUi -wUi sfc avI sfc @@ -200335,11 +200400,11 @@ pSB avc pSB lnH -peQ +oTH hXr +mbh wrT rWg -lwA oPr lwA lwA @@ -200594,9 +200659,9 @@ pSB gLT peQ rCF +fiR wrT rWg -lwA oPr lwA lwA @@ -200849,10 +200914,10 @@ gkh oaF dKL lhy -peQ +oTH cCN +xHg wrT -bex iGo oPr lwA @@ -201107,10 +201172,10 @@ geK aPg jAO bEr -ucf -wrT -wrT +rCF +uvA wrT +rYh fQz kIE kIE @@ -201365,9 +201430,9 @@ cgX nwQ dKT ucX +bOF wrT -rYh -wrT +vmm mYL wrT wrT @@ -201623,7 +201688,7 @@ uKP uKP uKP wrT -rYh +wrT wrT cYX lVF @@ -201879,7 +201944,7 @@ hRj hRj hRj hRj -wrT +hRj wrT wrT jzI diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 33ad2d7b54b..c74ea366143 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -46,6 +46,28 @@ /obj/machinery/light/small/directional/north, /turf/open/floor/iron/dark, /area/station/service/library) +"aaS" = ( +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/access/all/medical/general, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/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/door/airlock/medical/glass{ + name = "Medbay" + }, +/obj/effect/mapping_helpers/airlock/unres/delayed{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/medical/medbay) "aaV" = ( /obj/structure/disposalpipe/segment{ dir = 5 @@ -157,6 +179,24 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/hidden/layer4, /turf/open/floor/iron, /area/station/hallway/secondary/entry) +"aca" = ( +/obj/effect/turf_decal/tile/blue/half/contrasted{ + dir = 4 + }, +/obj/structure/reagent_dispensers/water_cooler, +/obj/machinery/button/door/directional/east{ + pixel_y = -4; + id = "paramed_dispatch_desk"; + name = "Desk Shutter Control" + }, +/obj/machinery/button/door/directional/east{ + pixel_y = 6; + name = "Medbay Doors Control"; + id = "MedbayFoyer"; + normaldoorcontrol = 1 + }, +/turf/open/floor/iron/white, +/area/station/medical/paramedic) "acn" = ( /obj/machinery/door/airlock/medical{ name = "Medbay Cold Room" @@ -224,6 +264,14 @@ }, /turf/open/floor/iron, /area/station/construction/mining/aux_base) +"acI" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/obj/machinery/status_display/ai/directional/north, +/obj/effect/spawner/random/gizmo, +/turf/open/floor/engine, +/area/station/science/explab) "acU" = ( /obj/structure/table_frame, /obj/effect/decal/cleanable/dirt, @@ -2006,18 +2054,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/pharmacy) -"awN" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/spawner/random/entertainment/slot_machine, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral/half/contrasted{ - dir = 1 - }, -/obj/machinery/light/small/dim/directional/north, -/turf/open/floor/iron, -/area/station/maintenance/department/crew_quarters/bar) "awT" = ( /obj/structure/chair/stool/directional/east, /turf/open/floor/iron/cafeteria, @@ -2624,6 +2660,15 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/hallway/secondary/exit/departure_lounge) +"aGy" = ( +/obj/effect/turf_decal/tile/brown/anticorner/contrasted, +/obj/machinery/brm, +/obj/machinery/conveyor{ + dir = 8; + id = "mining" + }, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "aGF" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -2788,6 +2833,14 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/hallway/primary/central/fore) +"aIa" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable/layer3, +/mob/living/basic/bot/secbot/pingsky, +/turf/open/floor/iron/grimy, +/area/station/ai/satellite/interior) "aIp" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/yellow{ @@ -3739,12 +3792,6 @@ }, /turf/open/space/basic, /area/space/nearstation) -"aUS" = ( -/obj/effect/turf_decal/bot, -/obj/structure/closet/crate/secure/loot, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/station/cargo/warehouse) "aUZ" = ( /obj/machinery/airalarm/directional/north, /obj/structure/table, @@ -3862,6 +3909,18 @@ /obj/effect/turf_decal/tile/neutral/opposingcorners, /turf/open/floor/iron, /area/station/hallway/primary/central/aft) +"aWt" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/spawner/random/entertainment/slot_machine, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/neutral/half/contrasted{ + dir = 1 + }, +/obj/machinery/light/small/dim/directional/north, +/turf/open/floor/iron, +/area/station/maintenance/department/crew_quarters/bar) "aWu" = ( /obj/structure/cable, /obj/machinery/door/poddoor/preopen{ @@ -7034,14 +7093,6 @@ /obj/machinery/atmospherics/components/tank/air/layer4, /turf/open/floor/iron/smooth, /area/station/science/xenobiology) -"bJn" = ( -/obj/machinery/dna_infuser, -/obj/item/tgui_book/manual/infuser, -/obj/effect/turf_decal/tile/blue/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron/dark, -/area/station/science/genetics) "bJs" = ( /obj/structure/table/reinforced, /obj/item/stack/sheet/iron{ @@ -7873,16 +7924,6 @@ /obj/effect/mapping_helpers/airlock/access/all/engineering/atmos, /turf/open/floor/iron, /area/station/engineering/atmos/project) -"bSZ" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 - }, -/obj/effect/turf_decal/siding/white{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral/full, -/turf/open/floor/iron/dark/smooth_large, -/area/station/science/genetics) "bTa" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -8193,14 +8234,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron/dark, /area/station/service/library) -"bXF" = ( -/obj/effect/turf_decal/tile/brown/anticorner/contrasted, -/obj/machinery/conveyor{ - id = "mining" - }, -/obj/machinery/brm, -/turf/open/floor/iron, -/area/station/cargo/warehouse) "bXG" = ( /obj/structure/cable, /obj/machinery/duct, @@ -8283,17 +8316,6 @@ /obj/effect/turf_decal/trimline/purple/filled/line, /turf/open/floor/iron/white, /area/station/science/ordnance/storage) -"bYk" = ( -/obj/effect/turf_decal/siding/white{ - dir = 4 - }, -/obj/structure/chair/office/light{ - dir = 4 - }, -/obj/effect/landmark/start/geneticist, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/science/genetics) "bYm" = ( /obj/structure/lattice, /obj/structure/transit_tube/diagonal, @@ -8312,16 +8334,6 @@ dir = 4 }, /area/station/hallway/primary/central/fore) -"bYp" = ( -/obj/structure/table, -/obj/item/stack/medical/wrap/gauze, -/obj/item/stack/medical/mesh, -/obj/item/stack/medical/suture, -/obj/effect/turf_decal/trimline/blue/filled/line{ - dir = 1 - }, -/turf/open/floor/iron/white, -/area/station/medical/medbay/lobby) "bYq" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/rack, @@ -8400,6 +8412,16 @@ /obj/effect/mob_spawn/cockroach, /turf/open/floor/iron, /area/station/medical/abandoned) +"bZs" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 1 + }, +/obj/structure/railing{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown/half/contrasted, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "bZz" = ( /obj/structure/table/wood, /obj/item/folder, @@ -8666,6 +8688,12 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) +"ccB" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted, +/obj/structure/closet/crate/secure/loot, +/obj/effect/landmark/start/hangover, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "ccK" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -8719,6 +8747,9 @@ "cdt" = ( /turf/closed/wall/r_wall, /area/station/ai/upload/chamber) +"cdy" = ( +/turf/closed/wall/r_wall, +/area/station/medical/medbay/lobby) "cdB" = ( /obj/structure/chair/sofa/bench/right{ dir = 1 @@ -8918,6 +8949,12 @@ /obj/effect/turf_decal/tile/purple/fourcorners, /turf/open/floor/iron, /area/station/science/xenobiology) +"cgK" = ( +/obj/structure/sign/poster/contraband/random/directional/south, +/obj/effect/turf_decal/tile/brown/anticorner/contrasted, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "cgP" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -9841,28 +9878,6 @@ /obj/machinery/atmospherics/components/tank/air/layer4, /turf/open/floor/plating, /area/station/maintenance/solars/starboard/fore) -"cqN" = ( -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/access/all/medical/general, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/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/door/airlock/medical/glass{ - name = "Medbay" - }, -/obj/effect/mapping_helpers/airlock/unres/delayed{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/medical/medbay) "crd" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/cable, @@ -10550,6 +10565,16 @@ }, /turf/open/floor/iron, /area/station/command/heads_quarters/rd) +"czO" = ( +/obj/item/stack/medical/wrap/sticky_tape/surgical, +/obj/structure/table/glass, +/obj/item/radio/intercom/directional/north, +/obj/item/stack/medical/wrap/sticky_tape/surgical, +/obj/item/stack/medical/bone_gel, +/obj/machinery/light/directional/north, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron/dark, +/area/station/medical/surgery/theatre) "cAb" = ( /obj/structure/table/reinforced, /obj/structure/window/reinforced/spawner/directional/east, @@ -10662,6 +10687,18 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/service/chapel/storage) +"cBx" = ( +/obj/structure/cable, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/duct, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/siding/purple{ + dir = 8 + }, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "cBC" = ( /obj/structure/table/reinforced, /obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible{ @@ -12346,22 +12383,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/service/abandoned_gambling_den) -"cXS" = ( -/obj/effect/turf_decal/siding/white{ - dir = 8 - }, -/obj/structure/chair/office/light{ - dir = 8 - }, -/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, -/obj/machinery/duct, -/obj/effect/landmark/start/geneticist, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/science/genetics) "cYf" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -12607,28 +12628,6 @@ /obj/item/radio/intercom/directional/south, /turf/open/floor/iron/dark, /area/station/service/bar) -"dbG" = ( -/obj/effect/turf_decal/siding/blue{ - dir = 1 - }, -/obj/machinery/status_display/evac/directional/south, -/obj/structure/table/wood, -/obj/effect/turf_decal/tile/neutral/half/contrasted{ - dir = 1 - }, -/obj/item/tgui_book/manual/dsm{ - pixel_y = 3; - pixel_x = 7 - }, -/obj/item/flashlight/lamp{ - pixel_y = 4; - pixel_x = -6 - }, -/obj/item/tgui_book/manual/idc{ - pixel_x = 4 - }, -/turf/open/floor/iron, -/area/station/command/heads_quarters/cmo) "dbO" = ( /obj/structure/chair/sofa/bench/right{ dir = 8 @@ -14116,6 +14115,28 @@ }, /turf/open/floor/plating, /area/station/maintenance/port) +"duY" = ( +/obj/structure/table/glass, +/obj/structure/cable, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue/fourcorners, +/obj/item/tgui_book/manual/dsm, +/obj/item/book/manual/wiki/medicine{ + pixel_x = -4; + pixel_y = 3 + }, +/obj/item/tgui_book/manual/idc{ + pixel_y = 3; + pixel_x = 3 + }, +/obj/item/clothing/neck/stethoscope{ + pixel_y = 4 + }, +/obj/item/clothing/neck/stethoscope, +/turf/open/floor/iron, +/area/station/medical/treatment_center) "dvh" = ( /obj/structure/rack, /obj/structure/cable, @@ -14739,6 +14760,40 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/wood, /area/station/service/electronic_marketing_den) +"dEm" = ( +/obj/item/wrench/medical, +/obj/item/reagent_containers/cup/beaker/cryoxadone{ + pixel_x = -6; + pixel_y = 10 + }, +/obj/item/reagent_containers/cup/beaker/cryoxadone{ + pixel_x = 6; + pixel_y = 10 + }, +/obj/item/reagent_containers/cup/beaker/cryoxadone{ + pixel_x = 6; + pixel_y = 6 + }, +/obj/item/reagent_containers/cup/beaker/cryoxadone{ + pixel_x = -6; + pixel_y = 6 + }, +/obj/item/storage/pill_bottle/mannitol, +/obj/item/reagent_containers/dropper, +/obj/structure/window/reinforced/spawner/directional/south, +/obj/machinery/camera/directional/west{ + c_tag = "Medbay - Cryogenics"; + name = "medical camera"; + network = list("ss13","medical") + }, +/obj/effect/turf_decal/siding/blue/corner{ + dir = 1 + }, +/obj/effect/turf_decal/siding/blue, +/obj/structure/table/glass, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron, +/area/station/medical/cryo) "dEr" = ( /obj/machinery/wall_healer/directional/west, /turf/open/floor/iron/white, @@ -15606,6 +15661,16 @@ /obj/machinery/wall_healer/directional/west, /turf/open/floor/iron, /area/station/commons/fitness/recreation) +"dOc" = ( +/obj/structure/table, +/obj/item/stack/medical/wrap/gauze, +/obj/item/stack/medical/mesh, +/obj/item/stack/medical/suture, +/obj/effect/turf_decal/trimline/blue/filled/line{ + dir = 1 + }, +/turf/open/floor/iron/white, +/area/station/medical/medbay/lobby) "dOk" = ( /turf/open/floor/circuit, /area/station/science/robotics/mechbay) @@ -17153,6 +17218,11 @@ /obj/effect/turf_decal/bot, /turf/open/floor/iron, /area/station/engineering/storage_shared) +"ekJ" = ( +/obj/effect/turf_decal/tile/purple/fourcorners, +/obj/item/kirbyplants/random, +/turf/open/floor/iron, +/area/station/hallway/primary/central/aft) "ekK" = ( /obj/structure/lattice/catwalk, /obj/structure/cable, @@ -17169,17 +17239,6 @@ /obj/item/kirbyplants/random, /turf/open/floor/iron, /area/station/maintenance/port) -"ekY" = ( -/obj/structure/disposalpipe/segment{ - dir = 5 - }, -/obj/effect/turf_decal/bot, -/obj/effect/decal/cleanable/dirt, -/obj/structure/closet/crate, -/obj/effect/landmark/start/hangover, -/obj/effect/spawner/random/maintenance, -/turf/open/floor/iron, -/area/station/cargo/warehouse) "ekZ" = ( /obj/effect/turf_decal/box/white{ color = "#52B4E9" @@ -18009,18 +18068,6 @@ }, /turf/open/floor/iron/white, /area/station/science/lobby) -"ewa" = ( -/obj/effect/turf_decal/tile/brown/half/contrasted, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/conveyor_switch/oneway{ - id = "mining"; - dir = 1 - }, -/obj/structure/railing{ - dir = 6 - }, -/turf/open/floor/iron, -/area/station/cargo/warehouse) "ewb" = ( /obj/effect/spawner/random/structure/crate, /turf/open/floor/plating, @@ -19714,6 +19761,16 @@ dir = 1 }, /area/station/service/bar) +"eRd" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/duct, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/siding/purple{ + dir = 9 + }, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "eRr" = ( /obj/effect/spawner/random/trash/moisture_trap, /turf/open/floor/plating, @@ -20561,15 +20618,18 @@ /obj/effect/turf_decal/tile/yellow/opposingcorners, /turf/open/floor/iron, /area/station/engineering/atmos/project) -"fdn" = ( -/obj/effect/landmark/start/hangover, -/obj/structure/closet/crate, -/obj/effect/turf_decal/bot, -/obj/item/airlock_painter/decal, -/obj/effect/decal/cleanable/dirt, -/obj/structure/railing/corner/end/flip, -/turf/open/floor/iron, -/area/station/cargo/warehouse) +"fde" = ( +/obj/machinery/requests_console/directional/south{ + department = "Genetics"; + name = "Genetics Requests console" + }, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/structure/sink/directional/north, +/obj/effect/turf_decal/siding/purple{ + dir = 4 + }, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "fdG" = ( /obj/machinery/power/apc/auto_name/directional/west, /obj/structure/cable, @@ -20841,18 +20901,6 @@ /obj/item/kirbyplants/random, /turf/open/floor/wood, /area/station/service/theater/abandoned) -"fgk" = ( -/obj/machinery/navbeacon{ - codes_txt = "patrol;next_patrol=hall12"; - location = "hall11" - }, -/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/neutral/fourcorners, -/mob/living/simple_animal/bot/secbot/beepsky/officer, -/turf/open/floor/iron, -/area/station/hallway/primary/starboard) "fgq" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -20871,6 +20919,20 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/science/ordnance) +"fgA" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/medical/glass{ + name = "Medbay Treatment Center" + }, +/obj/effect/mapping_helpers/airlock/access/all/medical/general, +/obj/structure/disposalpipe/segment, +/obj/effect/mapping_helpers/airlock/unres/delayed, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/iron, +/area/station/medical/treatment_center) "fgB" = ( /obj/structure/lattice/catwalk, /obj/machinery/atmospherics/pipe/smart/simple/orange/visible, @@ -22639,16 +22701,6 @@ }, /turf/open/floor/iron/grimy, /area/station/service/library/abandoned) -"fCA" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/brown/half/contrasted, -/obj/effect/decal/cleanable/dirt, -/obj/structure/railing, -/turf/open/floor/iron, -/area/station/cargo/warehouse) "fCD" = ( /obj/structure/table/optable, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -24478,18 +24530,6 @@ }, /turf/open/floor/iron, /area/station/cargo/sorting) -"fZn" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/item/radio/intercom/directional/north{ - pixel_y = 34 - }, -/obj/structure/sink/directional/south, -/obj/effect/turf_decal/tile/blue/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron/dark, -/area/station/science/genetics) "fZp" = ( /obj/structure/disposalpipe/segment, /obj/effect/turf_decal/trimline/blue/filled/warning{ @@ -25100,10 +25140,6 @@ dir = 1 }, /area/station/hallway/secondary/entry) -"gfR" = ( -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/science/genetics) "gfX" = ( /obj/structure/table, /obj/effect/spawner/random/entertainment/deck, @@ -26202,6 +26238,26 @@ }, /turf/open/floor/iron, /area/station/science/auxlab/firing_range) +"gsv" = ( +/obj/structure/table/reinforced, +/obj/item/toy/figure/geneticist, +/obj/machinery/computer/records/medical/laptop{ + dir = 8; + pixel_y = 1 + }, +/obj/item/radio/headset/headset_medsci{ + pixel_x = -7; + pixel_y = 0 + }, +/obj/item/radio/headset/headset_medsci{ + pixel_x = -7; + pixel_y = 4 + }, +/obj/effect/turf_decal/tile/blue/half/contrasted{ + dir = 1 + }, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "gsy" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable, @@ -27386,16 +27442,6 @@ }, /turf/open/floor/iron, /area/station/medical/medbay) -"gFB" = ( -/obj/effect/turf_decal/siding/white{ - dir = 9 - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/duct, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/science/genetics) "gFF" = ( /obj/effect/landmark/event_spawn, /obj/structure/cable, @@ -27774,12 +27820,6 @@ /obj/effect/turf_decal/tile/neutral/full, /turf/open/floor/iron/large, /area/station/commons/locker) -"gKF" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/blood/oil, -/turf/open/floor/iron, -/area/station/cargo/warehouse) "gKI" = ( /obj/structure/cable, /obj/machinery/power/apc/auto_name/directional/north, @@ -29660,6 +29700,23 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central/aft) +"hkj" = ( +/obj/effect/mapping_helpers/airlock/access/all/medical/general, +/obj/structure/cable, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/door/airlock/medical/glass{ + name = "Medbay Treatment Center" + }, +/obj/effect/mapping_helpers/airlock/unres/delayed, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/medical/treatment_center) "hkm" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -31212,14 +31269,6 @@ /obj/effect/turf_decal/trimline/green/filled/warning, /turf/open/floor/iron/white, /area/station/medical/virology) -"hGP" = ( -/obj/machinery/conveyor{ - dir = 8; - id = "mining" - }, -/obj/machinery/bouldertech/refinery, -/turf/open/floor/iron, -/area/station/cargo/warehouse) "hGW" = ( /obj/machinery/mass_driver/ordnance{ dir = 8 @@ -31365,24 +31414,6 @@ /obj/structure/lattice, /turf/open/space/basic, /area/space/nearstation) -"hII" = ( -/obj/structure/rack, -/obj/item/stack/medical/wrap/gauze, -/obj/item/stack/medical/suture, -/obj/item/stack/medical/mesh, -/obj/item/reagent_containers/syringe/epinephrine{ - pixel_x = -3; - pixel_y = 3 - }, -/obj/item/reagent_containers/syringe/multiver, -/obj/machinery/camera/directional/west{ - c_tag = "Bridge - Gateway Atrium"; - name = "command camera" - }, -/obj/effect/turf_decal/bot, -/obj/machinery/wall_healer/directional/west, -/turf/open/floor/iron, -/area/station/command/gateway) "hIP" = ( /obj/effect/turf_decal/stripes/corner{ dir = 1 @@ -32176,16 +32207,6 @@ }, /turf/open/floor/plating, /area/station/command/corporate_showroom) -"hTr" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/stripes/corner{ - dir = 4 - }, -/mob/living/simple_animal/bot/secbot/beepsky/armsky, -/turf/open/floor/iron/dark, -/area/station/security/armory) "hTv" = ( /obj/structure/cable, /obj/effect/turf_decal/trimline/green/filled/line{ @@ -32656,6 +32677,12 @@ }, /turf/open/floor/iron/white, /area/station/command/heads_quarters/rd) +"iaB" = ( +/obj/effect/turf_decal/tile/blue/anticorner/contrasted{ + dir = 4 + }, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "iaG" = ( /obj/effect/turf_decal/stripes/corner{ dir = 1 @@ -33346,37 +33373,6 @@ /obj/effect/turf_decal/siding/dark_red, /turf/open/floor/iron/dark, /area/station/security/execution/transfer) -"iiU" = ( -/obj/structure/table/reinforced, -/obj/item/storage/box/monkeycubes{ - pixel_x = 6; - pixel_y = 4 - }, -/obj/item/storage/pill_bottle/mutadone{ - pixel_x = -8; - pixel_y = 9 - }, -/obj/item/reagent_containers/spray/cleaner{ - pixel_x = -10; - pixel_y = -1 - }, -/obj/item/storage/box/monkeycubes{ - pixel_x = 4 - }, -/obj/machinery/camera/directional/east{ - c_tag = "Science - Genetics"; - dir = 6; - name = "science camera"; - network = list("ss13","rd") - }, -/obj/machinery/status_display/evac/directional/east, -/obj/effect/turf_decal/tile/blue/half/contrasted{ - dir = 4 - }, -/obj/machinery/light/directional/east, -/obj/item/flesh_shears, -/turf/open/floor/iron/dark, -/area/station/science/genetics) "iju" = ( /obj/structure/closet{ name = "evidence closet" @@ -33798,6 +33794,14 @@ /obj/effect/mapping_helpers/airlock/red_alert_access, /turf/open/floor/iron, /area/station/command/eva) +"inJ" = ( +/obj/machinery/door/poddoor/shutters/preopen{ + id = "genetics_shutters"; + name = "Genetics Shutters" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/station/science/genetics) "inR" = ( /obj/machinery/door/airlock/research{ name = "Research and Development Lab" @@ -35007,6 +35011,19 @@ /obj/item/radio/intercom/directional/west, /turf/open/floor/iron/dark, /area/station/medical/morgue) +"iCU" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/item/radio/intercom/directional/north{ + pixel_y = 34 + }, +/obj/effect/turf_decal/tile/blue/half/contrasted{ + dir = 1 + }, +/obj/machinery/dna_infuser, +/obj/item/tgui_book/manual/infuser, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "iDc" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable, @@ -35390,15 +35407,6 @@ /obj/effect/turf_decal/bot, /turf/open/floor/iron/large, /area/station/commons/fitness/recreation) -"iHT" = ( -/obj/machinery/atmospherics/components/unary/thermomachine/freezer{ - dir = 4 - }, -/obj/machinery/newscaster/directional/west, -/obj/effect/turf_decal/bot_red, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/medical/cryo) "iHV" = ( /obj/effect/turf_decal/tile/blue/fourcorners, /turf/open/floor/iron/white, @@ -38463,6 +38471,13 @@ /obj/structure/sign/warning/electric_shock, /turf/closed/wall/r_wall, /area/station/maintenance/port/aft) +"jue" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/siding/purple{ + dir = 4 + }, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "jui" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -39011,26 +39026,6 @@ /obj/structure/extinguisher_cabinet/directional/west, /turf/open/floor/iron/dark, /area/station/service/abandoned_gambling_den) -"jBA" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/medical/glass{ - name = "Medbay" - }, -/obj/effect/mapping_helpers/airlock/access/all/medical/general, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/mapping_helpers/airlock/unres/delayed{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/medical/medbay) "jBE" = ( /obj/machinery/shower/directional/east{ name = "emergency shower" @@ -39440,6 +39435,15 @@ /obj/effect/mapping_helpers/airlock/access/all/supply/general, /turf/open/floor/iron, /area/station/cargo/office) +"jFE" = ( +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/effect/turf_decal/bot, +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/start/hangover, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "jFJ" = ( /obj/structure/bed/medical/anchored{ dir = 4 @@ -39720,13 +39724,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, /area/station/cargo/lobby) -"jKb" = ( -/obj/effect/turf_decal/siding/white{ - dir = 5 - }, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/science/genetics) "jKg" = ( /obj/effect/turf_decal/stripes/line{ dir = 5 @@ -39753,6 +39750,24 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark/textured, /area/station/science/research) +"jKm" = ( +/obj/structure/rack, +/obj/item/stack/medical/wrap/gauze, +/obj/item/stack/medical/suture, +/obj/item/stack/medical/mesh, +/obj/item/reagent_containers/syringe/epinephrine{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/reagent_containers/syringe/multiver, +/obj/machinery/camera/directional/west{ + c_tag = "Bridge - Gateway Atrium"; + name = "command camera" + }, +/obj/effect/turf_decal/bot, +/obj/machinery/wall_healer/directional/west, +/turf/open/floor/iron, +/area/station/command/gateway) "jKo" = ( /obj/structure/closet/firecloset, /turf/open/floor/plating, @@ -40006,6 +40021,22 @@ /obj/structure/sign/warning/vacuum/directional/north, /turf/open/floor/iron/dark, /area/station/engineering/hallway) +"jNf" = ( +/obj/structure/sign/poster/contraband/random/directional/west, +/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ + dir = 8 + }, +/obj/machinery/light/small/directional/west, +/obj/effect/turf_decal/delivery, +/obj/machinery/conveyor{ + dir = 9; + id = "mining" + }, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "jNh" = ( /obj/effect/turf_decal/siding/white, /obj/item/radio/intercom/directional/east, @@ -40247,17 +40278,6 @@ }, /turf/open/floor/iron, /area/station/commons/fitness/recreation) -"jPY" = ( -/obj/structure/chair/office/light{ - dir = 1; - pixel_y = 3 - }, -/obj/effect/landmark/start/geneticist, -/obj/effect/turf_decal/tile/blue/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron/dark, -/area/station/science/genetics) "jPZ" = ( /obj/effect/turf_decal/siding/dark_blue{ dir = 4 @@ -40712,19 +40732,6 @@ }, /turf/open/floor/iron, /area/station/maintenance/port/aft) -"jWx" = ( -/obj/item/stack/medical/wrap/gauze, -/obj/item/stack/medical/suture, -/obj/machinery/camera/directional/north{ - c_tag = "Medbay - Treatment Center"; - name = "medbay camera"; - network = list("ss13","medbay") - }, -/obj/structure/table/reinforced/rglass, -/obj/effect/turf_decal/tile/blue/fourcorners, -/obj/machinery/firealarm/directional/north, -/turf/open/floor/iron, -/area/station/medical/treatment_center) "jWG" = ( /obj/structure/table, /obj/item/reagent_containers/cup/beaker/large, @@ -41261,6 +41268,27 @@ /obj/structure/chair/sofa/left/brown, /turf/open/floor/wood/tile, /area/station/service/library/artgallery) +"kcz" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/structure/table/reinforced, +/obj/item/storage/pill_bottle/mutadone{ + pixel_x = -8; + pixel_y = 9 + }, +/obj/item/storage/box/monkeycubes{ + pixel_x = 6; + pixel_y = 4 + }, +/obj/item/storage/box/monkeycubes{ + pixel_x = 4 + }, +/obj/item/reagent_containers/spray/cleaner{ + pixel_x = -10; + pixel_y = -1 + }, +/obj/item/flesh_shears, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "kcH" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -41544,21 +41572,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/maintenance/port/aft) -"kgc" = ( -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/access/all/medical/general, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line, -/obj/structure/disposalpipe/segment, -/obj/machinery/door/airlock/medical/glass{ - id_tag = "MedbayFoyer"; - name = "Medbay Foyer" - }, -/obj/effect/mapping_helpers/airlock/unres/delayed, -/turf/open/floor/iron, -/area/station/medical/medbay/lobby) "kgf" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -41720,6 +41733,28 @@ /obj/structure/lattice/catwalk, /turf/open/space/basic, /area/space/nearstation) +"khV" = ( +/obj/effect/turf_decal/siding/blue{ + dir = 1 + }, +/obj/machinery/status_display/evac/directional/south, +/obj/structure/table/wood, +/obj/effect/turf_decal/tile/neutral/half/contrasted{ + dir = 1 + }, +/obj/item/tgui_book/manual/dsm{ + pixel_y = 3; + pixel_x = 7 + }, +/obj/item/flashlight/lamp{ + pixel_y = 4; + pixel_x = -6 + }, +/obj/item/tgui_book/manual/idc{ + pixel_x = 4 + }, +/turf/open/floor/iron, +/area/station/command/heads_quarters/cmo) "khZ" = ( /obj/machinery/status_display/evac/directional/north, /obj/machinery/bookbinder, @@ -46265,6 +46300,17 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/entry) +"lrU" = ( +/obj/structure/chair/office/light{ + dir = 4 + }, +/obj/effect/landmark/start/geneticist, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/siding/purple{ + dir = 4 + }, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "lrX" = ( /obj/structure/bookcase/random/reference, /obj/effect/turf_decal/siding/wood{ @@ -46825,16 +46871,6 @@ }, /turf/open/floor/iron, /area/station/science/xenobiology) -"lze" = ( -/obj/structure/disposalpipe/segment{ - dir = 10 - }, -/obj/effect/spawner/random/entertainment/slot_machine, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/maintenance/department/crew_quarters/bar) "lzo" = ( /obj/machinery/atmospherics/components/binary/pump, /obj/effect/turf_decal/tile/neutral/half/contrasted{ @@ -46913,6 +46949,17 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/wood, /area/station/service/theater) +"lzR" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/bouldertech/refinery{ + dir = 4 + }, +/obj/machinery/conveyor{ + dir = 8; + id = "mining" + }, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "lAg" = ( /obj/structure/table/wood, /obj/item/folder/red, @@ -46941,23 +46988,6 @@ "lAj" = ( /turf/closed/wall, /area/station/security/prison/visit) -"lAk" = ( -/obj/effect/turf_decal/tile/blue/half/contrasted{ - dir = 4 - }, -/obj/structure/reagent_dispensers/water_cooler, -/obj/machinery/button/door/directional/east{ - pixel_y = -4; - id = "paramed_dispatch_desk"; - name = "Desk Shutter Control" - }, -/obj/machinery/button/door/directional/east{ - pixel_y = 6; - name = "Medbay Doors Control"; - id = "MedbayFoyer" - }, -/turf/open/floor/iron/white, -/area/station/medical/paramedic) "lAs" = ( /obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -47246,6 +47276,11 @@ }, /turf/open/floor/iron/dark, /area/station/service/library/printer) +"lDW" = ( +/obj/effect/turf_decal/bot, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "lDY" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -47471,6 +47506,11 @@ /obj/structure/sign/poster/official/report_crimes/directional/west, /turf/open/floor/iron/white, /area/station/medical/medbay) +"lFZ" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "lGf" = ( /obj/effect/turf_decal/tile/yellow/half/contrasted{ dir = 1 @@ -47974,13 +48014,6 @@ }, /turf/open/floor/engine/plasma, /area/station/engineering/atmos) -"lLa" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 5 - }, -/obj/machinery/status_display/ai/directional/north, -/turf/open/floor/engine, -/area/station/science/explab) "lLy" = ( /obj/effect/turf_decal/siding/white{ dir = 8 @@ -48396,6 +48429,19 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, /area/station/hallway/primary/port) +"lQX" = ( +/obj/item/stack/medical/wrap/gauze, +/obj/item/stack/medical/suture, +/obj/machinery/camera/directional/north{ + c_tag = "Medbay - Treatment Center"; + name = "medbay camera"; + network = list("ss13","medbay") + }, +/obj/structure/table/reinforced/rglass, +/obj/effect/turf_decal/tile/blue/fourcorners, +/obj/machinery/firealarm/directional/north, +/turf/open/floor/iron, +/area/station/medical/treatment_center) "lRb" = ( /obj/structure/disposalpipe/segment{ dir = 9 @@ -48505,20 +48551,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/medical/virology) -"lTb" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/medical/glass{ - name = "Medbay Treatment Center" - }, -/obj/effect/mapping_helpers/airlock/access/all/medical/general, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line, -/obj/structure/disposalpipe/segment, -/obj/effect/mapping_helpers/airlock/unres/delayed, -/turf/open/floor/iron, -/area/station/medical/treatment_center) "lTg" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/red{ @@ -48572,6 +48604,12 @@ dir = 1 }, /area/station/engineering/atmos/pumproom) +"lTI" = ( +/obj/machinery/holopad, +/obj/effect/turf_decal/bot, +/obj/effect/turf_decal/tile/neutral/full, +/turf/open/floor/iron/dark/smooth_large, +/area/station/science/genetics) "lTJ" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -48771,12 +48809,6 @@ /obj/effect/turf_decal/tile/red/fourcorners, /turf/open/floor/iron, /area/station/security/checkpoint/escape) -"lWX" = ( -/obj/effect/turf_decal/tile/brown/half/contrasted, -/obj/effect/decal/cleanable/dirt, -/obj/structure/railing, -/turf/open/floor/iron, -/area/station/cargo/warehouse) "lXm" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/decal/cleanable/dirt, @@ -50870,6 +50902,24 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/science/breakroom) +"mzp" = ( +/obj/effect/turf_decal/trimline/green/filled/line{ + dir = 9 + }, +/obj/structure/rack, +/obj/item/reagent_containers/spray/cleaner{ + pixel_x = -6 + }, +/obj/item/reagent_containers/syringe/antiviral, +/obj/item/tgui_book/manual/idc{ + pixel_y = 3; + pixel_x = 3 + }, +/obj/item/book/manual/wiki/infections, +/obj/item/reagent_containers/syringe/antiviral, +/obj/item/reagent_containers/dropper, +/turf/open/floor/iron/white, +/area/station/medical/virology) "mzu" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -51412,6 +51462,19 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark/textured, /area/station/science/ordnance/storage) +"mGl" = ( +/obj/structure/window/reinforced/spawner/directional/north, +/obj/machinery/door/firedoor/border_only{ + dir = 1 + }, +/obj/machinery/door/poddoor/preopen{ + id = "sci_experimentor"; + name = "Experimentor Blast Door" + }, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/machinery/gizmo/toggle/tucker_tubes, +/turf/open/floor/iron/dark, +/area/station/science/explab) "mGm" = ( /obj/machinery/portable_atmospherics/canister, /obj/effect/turf_decal/bot, @@ -52793,6 +52856,17 @@ /obj/effect/turf_decal/tile/neutral/full, /turf/open/floor/iron/large, /area/station/science/research) +"mYG" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/blood/oil, +/obj/structure/railing, +/obj/machinery/conveyor_switch/oneway{ + id = "mining"; + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "mYL" = ( /obj/effect/turf_decal/delivery, /obj/machinery/atmospherics/components/binary/tank_compressor{ @@ -53429,6 +53503,19 @@ dir = 8 }, /area/station/medical/medbay/lobby) +"nhZ" = ( +/obj/machinery/door/airlock/research{ + name = "Genetics Lab" + }, +/obj/effect/mapping_helpers/airlock/access/all/science/genetics, +/obj/machinery/door/poddoor/shutters/preopen{ + dir = 1; + id = "genetics_shutters"; + name = "Genetics Shutters" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "nia" = ( /obj/effect/turf_decal/tile/yellow, /turf/open/floor/iron, @@ -54034,18 +54121,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/hidden, /turf/open/floor/iron, /area/station/maintenance/department/medical/morgue) -"nqw" = ( -/obj/structure/window/reinforced/spawner/directional/north, -/obj/machinery/door/firedoor/border_only{ - dir = 1 - }, -/obj/machinery/door/poddoor/preopen{ - id = "sci_experimentor"; - name = "Experimentor Blast Door" - }, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/science/explab) "nqD" = ( /obj/effect/turf_decal/siding/purple{ dir = 1 @@ -54228,6 +54303,16 @@ /obj/machinery/light/small/directional/north, /turf/open/floor/iron/dark, /area/station/commons/fitness/recreation) +"ntU" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/brown/half/contrasted, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/conveyor{ + dir = 8; + id = "mining" + }, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "ntX" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 1 @@ -54555,26 +54640,6 @@ /obj/effect/mapping_helpers/requests_console/assistance, /turf/open/floor/carpet, /area/station/command/heads_quarters/captain) -"nxO" = ( -/obj/structure/table/reinforced, -/obj/item/toy/figure/geneticist, -/obj/machinery/computer/records/medical/laptop{ - dir = 8; - pixel_y = 1 - }, -/obj/item/radio/headset/headset_medsci{ - pixel_x = -7; - pixel_y = 0 - }, -/obj/effect/turf_decal/tile/blue/anticorner/contrasted{ - dir = 4 - }, -/obj/item/radio/headset/headset_medsci{ - pixel_x = -7; - pixel_y = 4 - }, -/turf/open/floor/iron/dark, -/area/station/science/genetics) "nxR" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -56154,6 +56219,16 @@ }, /turf/open/floor/iron, /area/station/cargo/office) +"nRd" = ( +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/obj/effect/spawner/random/entertainment/slot_machine, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/maintenance/department/crew_quarters/bar) "nRh" = ( /obj/structure/cable, /obj/effect/turf_decal/trimline/dark_red/filled/warning{ @@ -57947,6 +58022,15 @@ /obj/effect/spawner/random/structure/steam_vent, /turf/open/floor/iron/smooth, /area/station/maintenance/department/science/xenobiology) +"opt" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "opD" = ( /obj/structure/disposalpipe/segment{ dir = 6 @@ -61391,6 +61475,23 @@ /obj/structure/sink/directional/north, /turf/open/floor/iron, /area/station/medical/medbay) +"piL" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/medical/glass{ + id_tag = "MedbayFoyer"; + name = "Medbay Foyer" + }, +/obj/effect/mapping_helpers/airlock/access/all/medical/general, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/mapping_helpers/airlock/unres/delayed, +/turf/open/floor/iron, +/area/station/medical/medbay/lobby) "piM" = ( /obj/structure/cable, /obj/effect/turf_decal/siding/dark_red{ @@ -61436,6 +61537,18 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, /area/station/hallway/primary/port) +"pjE" = ( +/obj/machinery/navbeacon{ + codes_txt = "patrol;next_patrol=hall12"; + location = "hall11" + }, +/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/neutral/fourcorners, +/mob/living/basic/bot/secbot/beepsky/officer, +/turf/open/floor/iron, +/area/station/hallway/primary/starboard) "pjN" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -61543,25 +61656,6 @@ /obj/effect/turf_decal/tile/brown/anticorner/contrasted, /turf/open/floor/iron, /area/station/cargo/miningoffice) -"pkM" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/medical/glass{ - id_tag = "side_door_bolt"; - name = "Medbay Side Entrance" - }, -/obj/effect/mapping_helpers/airlock/access/all/medical/general, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/machinery/duct, -/obj/effect/mapping_helpers/airlock/unres/delayed{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/medical/cryo) "pkX" = ( /obj/machinery/computer/prisoner/management{ dir = 8 @@ -62068,6 +62162,25 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, /area/station/cargo/sorting) +"psu" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/medical/glass{ + id_tag = "side_door_bolt"; + name = "Medbay Side Entrance" + }, +/obj/effect/mapping_helpers/airlock/access/all/medical/general, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/duct, +/obj/effect/mapping_helpers/airlock/unres/delayed{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/medical/cryo) "psx" = ( /obj/item/kirbyplants/random, /obj/structure/cable, @@ -64736,14 +64849,6 @@ /obj/effect/mapping_helpers/airlock/unres/delayed, /turf/open/floor/iron, /area/station/maintenance/port) -"pVR" = ( -/obj/structure/sign/poster/contraband/random/directional/south, -/obj/machinery/conveyor{ - dir = 10; - id = "mining" - }, -/turf/open/floor/iron, -/area/station/cargo/warehouse) "pWb" = ( /obj/machinery/washing_machine, /obj/effect/decal/cleanable/cobweb, @@ -65330,6 +65435,21 @@ }, /turf/open/floor/iron, /area/station/cargo/storage) +"qcn" = ( +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/access/all/medical/general, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line, +/obj/structure/disposalpipe/segment, +/obj/machinery/door/airlock/medical/glass{ + id_tag = "MedbayFoyer"; + name = "Medbay Foyer" + }, +/obj/effect/mapping_helpers/airlock/unres/delayed, +/turf/open/floor/iron, +/area/station/medical/medbay/lobby) "qcu" = ( /obj/machinery/door/airlock/external{ name = "Escape Pod 3"; @@ -65414,6 +65534,22 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/ai/satellite/exterior) +"qdH" = ( +/obj/structure/chair/office/light{ + dir = 8 + }, +/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, +/obj/machinery/duct, +/obj/effect/landmark/start/geneticist, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/siding/purple{ + dir = 8 + }, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "qdP" = ( /obj/item/kirbyplants/random, /obj/structure/extinguisher_cabinet/directional/east, @@ -65623,6 +65759,15 @@ /obj/item/bot_assembly/medbot, /turf/open/floor/plating, /area/station/medical/abandoned) +"qgs" = ( +/obj/item/stack/medical/wrap/gauze, +/obj/item/stack/medical/mesh, +/obj/structure/table/reinforced/rglass, +/obj/effect/turf_decal/tile/blue/fourcorners, +/obj/machinery/light/cold/directional/north, +/obj/item/radio/intercom/directional/north, +/turf/open/floor/iron, +/area/station/medical/treatment_center) "qgx" = ( /obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ @@ -68285,6 +68430,14 @@ /obj/effect/turf_decal/bot, /turf/open/floor/iron, /area/station/science/robotics/lab) +"qPu" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/start/hangover, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "qPw" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/landmark/start/hangover, @@ -69022,15 +69175,6 @@ /obj/machinery/light/floor, /turf/open/floor/iron/dark, /area/station/command/bridge) -"rbL" = ( -/obj/item/stack/medical/wrap/gauze, -/obj/item/stack/medical/mesh, -/obj/structure/table/reinforced/rglass, -/obj/effect/turf_decal/tile/blue/fourcorners, -/obj/machinery/light/cold/directional/north, -/obj/item/radio/intercom/directional/north, -/turf/open/floor/iron, -/area/station/medical/treatment_center) "rbR" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -70406,28 +70550,6 @@ /obj/effect/turf_decal/bot, /turf/open/floor/iron/cafeteria, /area/station/service/kitchen) -"rud" = ( -/obj/item/stack/medical/wrap/sticky_tape/surgical, -/obj/structure/table/glass, -/obj/item/radio/intercom/directional/north, -/obj/item/stack/medical/wrap/sticky_tape/surgical, -/obj/item/stack/medical/bone_gel, -/obj/machinery/light/directional/north, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/medical/surgery/theatre) -"rue" = ( -/obj/effect/turf_decal/siding/white{ - dir = 8 - }, -/obj/structure/cable, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/duct, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/science/genetics) "rul" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, @@ -71124,6 +71246,16 @@ /obj/effect/spawner/random/structure/girder, /turf/open/floor/plating, /area/station/maintenance/fore) +"rDa" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/mob/living/basic/bot/secbot/beepsky/armsky, +/turf/open/floor/iron/dark, +/area/station/security/armory) "rDj" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/navbeacon{ @@ -71824,6 +71956,16 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/grimy, /area/station/service/chapel) +"rMe" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral/full, +/obj/effect/turf_decal/siding/purple{ + dir = 1 + }, +/turf/open/floor/iron/dark/smooth_large, +/area/station/science/genetics) "rMf" = ( /obj/effect/spawner/random/engineering/tracking_beacon, /obj/machinery/holopad, @@ -73009,6 +73151,17 @@ "rYA" = ( /turf/closed/wall, /area/station/maintenance/department/security) +"rYC" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/bouldertech/refinery/smelter{ + dir = 4 + }, +/obj/machinery/conveyor{ + dir = 8; + id = "mining" + }, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "rYE" = ( /obj/structure/table/reinforced, /obj/structure/window/reinforced/spawner/directional/east, @@ -74155,14 +74308,6 @@ /obj/machinery/duct, /turf/open/floor/iron, /area/station/science/robotics/lab) -"snE" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "genetics_shutters"; - name = "Genetics Shutters" - }, -/turf/open/floor/plating, -/area/station/science/genetics) "snK" = ( /obj/machinery/atmospherics/pipe/smart/simple/dark/visible, /obj/effect/decal/cleanable/dirt, @@ -75159,13 +75304,6 @@ "szy" = ( /turf/closed/wall, /area/station/service/bar/backroom) -"szC" = ( -/obj/machinery/conveyor{ - dir = 9; - id = "mining" - }, -/turf/open/floor/iron, -/area/station/cargo/warehouse) "szG" = ( /obj/effect/turf_decal/box/white, /turf/open/floor/iron/dark/textured_large, @@ -75228,11 +75366,6 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating, /area/station/engineering/supermatter/room) -"sAv" = ( -/obj/item/kirbyplants/random, -/obj/effect/turf_decal/tile/purple/fourcorners, -/turf/open/floor/iron, -/area/station/hallway/primary/central/aft) "sAD" = ( /obj/machinery/atmospherics/pipe/smart/simple/green/visible, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -75860,6 +75993,17 @@ }, /turf/open/floor/iron, /area/station/security/brig) +"sIA" = ( +/obj/structure/closet/crate, +/obj/effect/turf_decal/bot, +/obj/item/airlock_painter/decal, +/obj/effect/decal/cleanable/dirt, +/obj/structure/railing/corner/end/flip, +/obj/item/stack/ducts, +/obj/item/stack/ducts, +/obj/item/stack/ducts, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "sID" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, @@ -76666,6 +76810,13 @@ /obj/machinery/status_display/ai/directional/south, /turf/open/floor/iron/dark, /area/station/engineering/break_room) +"sSt" = ( +/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ + dir = 8 + }, +/obj/effect/landmark/start/hangover, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "sSw" = ( /obj/effect/turf_decal/siding/wood{ dir = 8 @@ -76888,6 +77039,15 @@ /obj/structure/sign/warning/electric_shock/directional/east, /turf/open/space/basic, /area/space/nearstation) +"sVC" = ( +/obj/machinery/atmospherics/components/unary/thermomachine/freezer{ + dir = 4 + }, +/obj/machinery/newscaster/directional/west, +/obj/effect/turf_decal/bot_red, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron/dark, +/area/station/medical/cryo) "sVP" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/stripes/line{ @@ -77990,6 +78150,17 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, /area/station/engineering/atmos) +"tlE" = ( +/obj/effect/turf_decal/tile/blue/half/contrasted{ + dir = 1 + }, +/obj/effect/landmark/start/geneticist, +/obj/structure/chair/office/light{ + dir = 1; + pixel_y = 3 + }, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "tlF" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -81298,28 +81469,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/engineering/atmos) -"ubl" = ( -/obj/structure/table/glass, -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/tile/blue/fourcorners, -/obj/item/tgui_book/manual/dsm, -/obj/item/book/manual/wiki/medicine{ - pixel_x = -4; - pixel_y = 3 - }, -/obj/item/tgui_book/manual/idc{ - pixel_y = 3; - pixel_x = 3 - }, -/obj/item/clothing/neck/stethoscope{ - pixel_y = 4 - }, -/obj/item/clothing/neck/stethoscope, -/turf/open/floor/iron, -/area/station/medical/treatment_center) "ubs" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -82120,6 +82269,26 @@ }, /turf/open/floor/plating, /area/station/engineering/transit_tube) +"ulu" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/medical/glass{ + name = "Medbay" + }, +/obj/effect/mapping_helpers/airlock/access/all/medical/general, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/mapping_helpers/airlock/unres/delayed{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/medical/medbay) "ulH" = ( /obj/structure/railing, /obj/effect/decal/cleanable/dirt, @@ -82799,13 +82968,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/secondary/entry) -"utQ" = ( -/obj/machinery/conveyor{ - dir = 8; - id = "mining" - }, -/turf/open/floor/iron, -/area/station/cargo/warehouse) "utS" = ( /obj/effect/landmark/start/hangover, /turf/open/floor/iron/dark, @@ -83438,24 +83600,6 @@ /obj/structure/sign/nanotrasen/directional/south, /turf/open/floor/iron/dark, /area/station/security/lockers) -"uAT" = ( -/obj/effect/turf_decal/trimline/green/filled/line{ - dir = 9 - }, -/obj/structure/rack, -/obj/item/reagent_containers/spray/cleaner{ - pixel_x = -6 - }, -/obj/item/reagent_containers/syringe/antiviral, -/obj/item/tgui_book/manual/idc{ - pixel_y = 3; - pixel_x = 3 - }, -/obj/item/book/manual/wiki/infections, -/obj/item/reagent_containers/syringe/antiviral, -/obj/item/reagent_containers/dropper, -/turf/open/floor/iron/white, -/area/station/medical/virology) "uBc" = ( /obj/machinery/module_duplicator, /obj/effect/turf_decal/bot, @@ -83685,16 +83829,6 @@ /obj/structure/chair/stool/bar/directional/north, /turf/open/floor/carpet/green, /area/station/commons/lounge) -"uDJ" = ( -/obj/structure/sign/poster/contraband/random/directional/west, -/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ - dir = 8 - }, -/obj/machinery/light/small/directional/west, -/obj/effect/turf_decal/delivery, -/obj/effect/landmark/start/hangover, -/turf/open/floor/iron, -/area/station/cargo/warehouse) "uDQ" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -85652,13 +85786,6 @@ /obj/machinery/newscaster/directional/south, /turf/open/floor/iron, /area/station/security/prison) -"vdA" = ( -/obj/effect/turf_decal/siding/white{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/science/genetics) "vdB" = ( /obj/machinery/computer/monitor{ dir = 1 @@ -86023,17 +86150,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, /area/station/maintenance/department/science) -"viP" = ( -/obj/effect/turf_decal/siding/white{ - dir = 4 - }, -/obj/machinery/requests_console/directional/south{ - department = "Genetics"; - name = "Genetics Requests console" - }, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/science/genetics) "viX" = ( /obj/item/wrench, /obj/machinery/atmospherics/components/trinary/filter{ @@ -86349,14 +86465,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/port/fore) -"vnI" = ( -/obj/machinery/conveyor{ - dir = 8; - id = "mining" - }, -/obj/machinery/bouldertech/refinery/smelter, -/turf/open/floor/iron, -/area/station/cargo/warehouse) "vnP" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -87737,40 +87845,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, /area/station/engineering/main) -"vEM" = ( -/obj/item/wrench/medical, -/obj/item/reagent_containers/cup/beaker/cryoxadone{ - pixel_x = -6; - pixel_y = 10 - }, -/obj/item/reagent_containers/cup/beaker/cryoxadone{ - pixel_x = 6; - pixel_y = 10 - }, -/obj/item/reagent_containers/cup/beaker/cryoxadone{ - pixel_x = 6; - pixel_y = 6 - }, -/obj/item/reagent_containers/cup/beaker/cryoxadone{ - pixel_x = -6; - pixel_y = 6 - }, -/obj/item/storage/pill_bottle/mannitol, -/obj/item/reagent_containers/dropper, -/obj/structure/window/reinforced/spawner/directional/south, -/obj/machinery/camera/directional/west{ - c_tag = "Medbay - Cryogenics"; - name = "medical camera"; - network = list("ss13","medical") - }, -/obj/effect/turf_decal/siding/blue/corner{ - dir = 1 - }, -/obj/effect/turf_decal/siding/blue, -/obj/structure/table/glass, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron, -/area/station/medical/cryo) "vEV" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -88368,23 +88442,6 @@ /obj/machinery/light/directional/west, /turf/open/floor/iron/dark, /area/station/security/courtroom) -"vMN" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/medical/glass{ - id_tag = "MedbayFoyer"; - name = "Medbay Foyer" - }, -/obj/effect/mapping_helpers/airlock/access/all/medical/general, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/mapping_helpers/airlock/unres/delayed, -/turf/open/floor/iron, -/area/station/medical/medbay/lobby) "vMQ" = ( /obj/machinery/status_display/evac/directional/west, /obj/item/kirbyplants/random, @@ -88434,6 +88491,13 @@ /obj/machinery/airalarm/directional/west, /turf/open/floor/plating, /area/station/maintenance/port/fore) +"vNP" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/siding/purple{ + dir = 5 + }, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "vOh" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -90245,14 +90309,6 @@ }, /turf/open/floor/iron/dark/corner, /area/station/engineering/atmos/mix) -"wlT" = ( -/obj/machinery/airalarm/directional/north, -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/station/cargo/warehouse) "wlW" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -90361,20 +90417,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/chemistry) -"wmS" = ( -/obj/effect/turf_decal/siding/white{ - dir = 8 - }, -/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/duct, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/science/genetics) "wmW" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 4 @@ -90655,6 +90697,16 @@ }, /turf/open/floor/iron/dark, /area/station/maintenance/port) +"wqb" = ( +/obj/machinery/airalarm/directional/north, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/closet/crate, +/obj/effect/spawner/random/maintenance, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "wqk" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/disposalpipe/segment{ @@ -93120,16 +93172,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/grimy, /area/station/commons/vacant_room/office) -"wZD" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/landmark/start/hangover, -/obj/structure/cable, -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/station/cargo/warehouse) "wZE" = ( /turf/closed/wall, /area/station/maintenance/department/electrical) @@ -93890,23 +93932,6 @@ /obj/machinery/meter, /turf/closed/wall/r_wall, /area/station/engineering/atmos) -"xie" = ( -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/access/all/medical/general, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line, -/obj/structure/cable, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/door/airlock/medical/glass{ - name = "Medbay Treatment Center" - }, -/obj/effect/mapping_helpers/airlock/unres/delayed, -/turf/open/floor/iron, -/area/station/medical/treatment_center) "xih" = ( /obj/machinery/vending/cigarette, /turf/open/floor/plating, @@ -94537,6 +94562,20 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/engineering/main) +"xrk" = ( +/obj/machinery/camera/directional/east{ + c_tag = "Science - Genetics"; + dir = 6; + name = "science camera"; + network = list("ss13","rd") + }, +/obj/machinery/status_display/evac/directional/east, +/obj/effect/turf_decal/tile/blue/half/contrasted{ + dir = 4 + }, +/obj/machinery/light/directional/east, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "xrr" = ( /turf/closed/wall/r_wall, /area/station/maintenance/solars/starboard/fore) @@ -96412,14 +96451,6 @@ }, /turf/open/floor/circuit/green, /area/station/engineering/main) -"xMP" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable/layer3, -/mob/living/simple_animal/bot/secbot/pingsky, -/turf/open/floor/iron/grimy, -/area/station/ai/satellite/interior) "xMX" = ( /obj/structure/chair/office{ dir = 4 @@ -96928,6 +96959,20 @@ /obj/machinery/duct, /turf/open/floor/plating, /area/station/maintenance/port/fore) +"xUr" = ( +/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/duct, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/siding/purple{ + dir = 8 + }, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "xUs" = ( /obj/effect/turf_decal/tile/red{ dir = 8 @@ -97159,13 +97204,6 @@ /obj/item/folder/red, /turf/open/floor/carpet, /area/station/service/library/abandoned) -"xXn" = ( -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/station/cargo/warehouse) "xXw" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 8 @@ -98104,12 +98142,6 @@ /obj/machinery/computer/security/telescreen/minisat/directional/east, /turf/open/floor/iron/dark, /area/station/engineering/transit_tube) -"yjK" = ( -/obj/machinery/holopad, -/obj/effect/turf_decal/bot_white, -/obj/effect/turf_decal/tile/neutral/full, -/turf/open/floor/iron/dark/smooth_large, -/area/station/science/genetics) "yjV" = ( /obj/structure/chair/office, /obj/effect/landmark/start/hangover, @@ -106659,7 +106691,7 @@ wgG lKC dYL bhn -xMP +aIa pFl wLX aCK @@ -128534,7 +128566,7 @@ pTC kRk uMs aNE -nqw +mGl ffb dBJ sLY @@ -129559,7 +129591,7 @@ pTC qWO duV pTC -lLa +acI fRK txc pZM @@ -132441,7 +132473,7 @@ aaa aaa gqm gqm -uAT +mzp grE uxI gqm @@ -133953,7 +133985,7 @@ gWz pdf kVo sqX -dbG +khV loe uTT nuI @@ -134958,11 +134990,11 @@ pHt ryc oJy oJy -fZn -gFB -wmS -cXS -rue +iCU +eRd +xUr +qdH +cBx gem vBk wil @@ -135214,13 +135246,13 @@ nXY whK rcW tXO -wYH -bJn -bSZ -yjK +xsn +tlE +rMe +lTI hVy -gfR -snE +kcz +inJ kdq shU bbj @@ -135470,13 +135502,13 @@ mlE dMA whK rcW -tXO -xsn -jPY -jKb -vdA -bYk -viP +ekJ +wYH +gsv +vNP +jue +lrU +fde oJy xWf uZs @@ -135727,10 +135759,10 @@ mlE dVU esr rcW -sAv -wYH -nxO -iiU +tXO +nhZ +iaB +xrk fZg eAq okD @@ -136519,7 +136551,7 @@ bzD dQT qSG hlO -nGk +rEO wtz wmn tQn @@ -136690,7 +136722,7 @@ kVP cAV cHm qAV -awN +aWt saB vxS eLY @@ -136776,7 +136808,7 @@ dQT dQT nGk acn -nGk +rEO fsa dXO ybs @@ -136947,7 +136979,7 @@ kVP aVE oWA qAV -lze +nRd vTO qAV qAV @@ -138048,8 +138080,8 @@ ptf dWe lks cwh -jBA -cqN +ulu +aaS veM cqb fiU @@ -138297,7 +138329,7 @@ iaY prP whK hiV -uNY +cdy squ pEU cwh @@ -138308,7 +138340,7 @@ cwh udd cUh veM -rbL +qgs wOP dfB knX @@ -138584,7 +138616,7 @@ pdl etk oRT aaM -rud +czO jqJ jqJ cQS @@ -138817,11 +138849,11 @@ gVB nhQ onK sQH -vMN +piL ePd dFB vIq -xie +hkj lPF mvb rKG @@ -139061,7 +139093,7 @@ liC mrK oVI cng -hII +jKm bhP bmt ksK @@ -139078,11 +139110,11 @@ pGo ntX tVM cjE -lTb +fgA oyy lSr qQG -ubl +duY gQI cpK nuG @@ -139331,7 +139363,7 @@ bLp kLo tCr iED -kgc +qcn fZp hkm azr @@ -139593,7 +139625,7 @@ keH yfM ckd veM -jWx +lQX eya wBh xVb @@ -139768,8 +139800,8 @@ lID fmk oDZ gpn -uDJ -szC +jNf +sSt lDi flB aoT @@ -139840,7 +139872,7 @@ eua whK hiV xuI -bYp +dOc iso rMf rmo @@ -140020,13 +140052,13 @@ elS jyL jvp cCb -wZD -ekY +opt +jFE azm prl -aUS -lWX -vnI +lDW +rYC +lFZ lDi hDP xKn @@ -140115,9 +140147,9 @@ fia iUg iUg tQM -vEM +dEm pHd -iHT +sVC cYF oDE osS @@ -140277,13 +140309,13 @@ jdL jdL eVz jdL -wlT +wqb szg brZ bzl -gKF -fCA -utQ +mYG +ntU +bZs lDi fPJ vBx @@ -140534,13 +140566,13 @@ hhb jdL dVA jdL -xXn +qPu pbh iXj oXl -fdn -ewa -hGP +sIA +lzR +ccB lDi oKr rgj @@ -140796,8 +140828,8 @@ soo nwQ rLa jXH -bXF -pVR +aGy +cgK lDi loU xzk @@ -141132,7 +141164,7 @@ lzH qFj pGo bYc -lAk +aca oRx gQl ivu @@ -141141,7 +141173,7 @@ oUz odc gQl cwe -pkM +psu cwe oDE fTE @@ -147779,7 +147811,7 @@ lYY lYY lYY pdY -fgk +pjE fvn rNx uPH @@ -151892,7 +151924,7 @@ lHb lHb yhE jYK -hTr +rDa pIX cdr jhr diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index c34a115efcd..36730f5a9f9 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -17,12 +17,6 @@ /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/plating, /area/station/maintenance/aft/lesser) -"aaw" = ( -/obj/structure/table, -/obj/item/folder/red, -/obj/item/taperecorder, -/turf/open/floor/iron/dark, -/area/station/security/interrogation) "aax" = ( /turf/open/floor/plating, /area/station/maintenance/central/greater) @@ -53,6 +47,12 @@ "abe" = ( /turf/open/floor/engine, /area/station/science/xenobiology) +"abq" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/carpet, +/area/station/security/prison/rec) "abv" = ( /obj/effect/turf_decal/loading_area{ dir = 1 @@ -140,6 +140,9 @@ /obj/structure/table/wood, /turf/open/floor/wood, /area/station/maintenance/port/aft) +"acf" = ( +/turf/open/floor/plating, +/area/station/security/prison) "acl" = ( /mob/living/carbon/human/species/monkey, /obj/structure/sign/warning/electric_shock/directional/north, @@ -213,6 +216,12 @@ }, /turf/open/misc/asteroid/snow/coldroom, /area/icemoon/underground/explored) +"adT" = ( +/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/security/brig/upper) "adY" = ( /obj/structure/cable, /obj/effect/spawner/structure/window/reinforced, @@ -227,6 +236,10 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/wood, /area/station/maintenance/aft/lesser) +"aef" = ( +/obj/effect/spawner/random/structure/grille, +/turf/open/floor/plating, +/area/station/maintenance/fore) "ael" = ( /obj/effect/turf_decal/siding/thinplating_new/corner{ dir = 8 @@ -253,6 +266,19 @@ /obj/effect/turf_decal/tile/green, /turf/open/floor/iron/dark, /area/station/ai/upload/chamber) +"aes" = ( +/obj/structure/rack, +/obj/item/storage/bag/ore, +/obj/item/pickaxe, +/obj/item/flashlight, +/obj/item/clothing/glasses/meson, +/obj/item/mining_scanner, +/obj/effect/decal/cleanable/dirt, +/obj/item/clothing/suit/hooded/wintercoat, +/obj/item/clothing/mask/breath, +/obj/item/tank/internals/emergency_oxygen, +/turf/open/floor/iron, +/area/mine/laborcamp) "aey" = ( /obj/machinery/camera/directional/east{ c_tag = "Xenobiology Pens - Starboard Fore"; @@ -308,6 +334,10 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/maintenance/starboard/upper) +"agc" = ( +/obj/effect/turf_decal/stripes/white/line, +/turf/open/floor/iron, +/area/station/security/prison/workout) "agd" = ( /obj/structure/table, /obj/item/stock_parts/power_store/cell/high, @@ -378,6 +408,18 @@ /obj/machinery/power/apc/auto_name/directional/south, /turf/open/floor/iron/white, /area/station/medical/medbay/central) +"agR" = ( +/obj/structure/table, +/obj/item/pen, +/obj/item/inspector, +/obj/item/inspector{ + pixel_y = 4; + pixel_x = 3 + }, +/turf/open/floor/iron/dark/textured_half{ + dir = 1 + }, +/area/station/security/office) "agY" = ( /obj/machinery/door/poddoor/shutters/window/preopen{ dir = 1; @@ -391,6 +433,14 @@ /obj/machinery/door/firedoor/heavy, /turf/open/floor/iron/dark, /area/station/engineering/atmos/project) +"ahg" = ( +/obj/effect/spawner/random/entertainment/cigar, +/obj/structure/table, +/obj/structure/railing/corner{ + dir = 8 + }, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/underground/explored) "ahm" = ( /obj/machinery/newscaster/directional/west, /obj/machinery/firealarm/directional/south, @@ -401,14 +451,6 @@ /obj/effect/turf_decal/stripes/box, /turf/open/floor/iron/dark, /area/station/engineering/lobby) -"ahA" = ( -/obj/structure/chair{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/newscaster/directional/west, -/turf/open/floor/iron/smooth, -/area/station/security/holding_cell) "ahG" = ( /obj/structure/fence/post{ dir = 2 @@ -480,6 +522,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/dark, /area/station/ai/satellite/interior) +"ajl" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/machinery/vending/cola/red, +/turf/open/floor/iron, +/area/station/security/prison/mess) "ajr" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 4 @@ -529,6 +578,29 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/dark/textured, /area/station/security/prison/workout) +"akb" = ( +/obj/structure/rack, +/obj/item/clothing/suit/hooded/wintercoat/security{ + pixel_x = -3; + pixel_y = 7 + }, +/obj/item/clothing/suit/hooded/wintercoat/security{ + pixel_x = -8 + }, +/obj/item/clothing/shoes/winterboots/ice_boots{ + pixel_x = 6; + pixel_y = 8 + }, +/obj/item/clothing/shoes/winterboots/ice_boots{ + pixel_x = 5 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/mining_weather_monitor/directional/east, +/obj/machinery/camera/directional/south{ + c_tag = "Security - EVA Interior" + }, +/turf/open/floor/iron/smooth, +/area/station/security/eva) "akd" = ( /obj/structure/rack, /obj/item/poster/random_contraband, @@ -552,6 +624,10 @@ "ako" = ( /turf/closed/wall/r_wall, /area/station/medical/morgue) +"akp" = ( +/obj/structure/ore_box, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/surface/outdoors/labor_camp) "aks" = ( /obj/machinery/holopad, /obj/structure/cable, @@ -574,6 +650,16 @@ /obj/structure/chair/stool/directional/east, /turf/open/floor/iron, /area/station/commons/dorms) +"akI" = ( +/obj/structure/table/glass, +/obj/item/stack/medical/wrap/gauze{ + pixel_x = 2 + }, +/obj/item/stack/medical/mesh, +/obj/item/stack/medical/suture, +/obj/effect/turf_decal/tile/blue/full, +/turf/open/floor/iron/large, +/area/station/medical/treatment_center) "akK" = ( /obj/effect/turf_decal/siding/wood{ dir = 1 @@ -604,14 +690,6 @@ /obj/effect/turf_decal/weather/snow/corner, /turf/open/floor/glass/reinforced/icemoon, /area/icemoon/surface/outdoors/nospawn) -"akZ" = ( -/obj/structure/window/reinforced/spawner/directional/south, -/obj/structure/flora/bush/jungle/a/style_random, -/obj/structure/flora/bush/sparsegrass/style_random, -/turf/open/misc/ashplanet/wateryrock{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, -/area/station/security/prison/rec) "alb" = ( /obj/structure/transit_tube_pod, /obj/structure/transit_tube/station/reverse/flipped{ @@ -658,10 +736,6 @@ /obj/item/clothing/suit/hooded/wintercoat/science, /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/underground/explored) -"alA" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/wood, -/area/station/security/prison/rec) "alD" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 1 @@ -847,12 +921,6 @@ dir = 1 }, /area/station/command/heads_quarters/rd) -"anQ" = ( -/obj/structure/rack, -/obj/item/clothing/gloves/latex, -/obj/structure/window/reinforced/tinted/spawner/directional/north, -/turf/open/floor/plating, -/area/station/security/prison/safe) "anW" = ( /obj/machinery/atmospherics/pipe/heat_exchanging/simple{ dir = 4 @@ -865,6 +933,15 @@ }, /turf/open/floor/plating, /area/station/engineering/lobby) +"aoa" = ( +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 1 + }, +/obj/machinery/camera/directional/north{ + c_tag = "Security - Upper Brig East" + }, +/turf/open/floor/iron, +/area/station/security/brig/upper) "aog" = ( /obj/machinery/light/floor, /turf/open/floor/iron, @@ -1092,15 +1169,6 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating, /area/station/maintenance/port/fore) -"aqa" = ( -/obj/machinery/door/airlock/external{ - glass = 1; - name = "Labor Camp External Airlock"; - opacity = 0 - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, -/turf/open/floor/plating, -/area/mine/laborcamp) "aqd" = ( /obj/structure/sign/warning/secure_area/directional/north, /turf/open/openspace, @@ -1129,6 +1197,16 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark/smooth_half, /area/station/service/hydroponics) +"aqA" = ( +/obj/structure/table, +/obj/effect/decal/cleanable/dirt, +/obj/item/plate/small, +/obj/item/book/manual/chef_recipes{ + pixel_x = 2; + pixel_y = 6 + }, +/turf/open/floor/iron, +/area/mine/laborcamp) "aqB" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -1168,15 +1246,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/service/bar/backroom) -"arb" = ( -/obj/structure/table, -/obj/item/folder/red, -/obj/item/pen, -/obj/item/inspector, -/turf/open/floor/iron/dark/textured_half{ - dir = 1 - }, -/area/station/security/office) "arg" = ( /obj/machinery/disposal/bin, /obj/structure/disposalpipe/trunk{ @@ -1218,11 +1287,6 @@ /obj/effect/turf_decal/tile/green/full, /turf/open/floor/iron/dark/smooth_large, /area/station/medical/virology) -"arA" = ( -/obj/effect/spawner/structure/window, -/obj/structure/cable, -/turf/open/floor/plating, -/area/station/security/office) "arG" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -1241,12 +1305,6 @@ }, /turf/open/floor/iron/smooth, /area/station/commons/storage/mining) -"arT" = ( -/obj/machinery/computer/security/labor{ - dir = 4 - }, -/turf/open/floor/iron/showroomfloor, -/area/station/security/processing) "arZ" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -1260,6 +1318,13 @@ /obj/item/storage/crayons, /turf/open/floor/iron, /area/station/commons/dorms) +"asd" = ( +/obj/machinery/conveyor/inverted{ + dir = 5; + id = "mining_internal" + }, +/turf/open/floor/iron, +/area/mine/production) "asf" = ( /obj/structure/plasticflaps/kitchen, /turf/open/floor/iron/dark, @@ -1411,6 +1476,18 @@ }, /turf/open/floor/plating/snowed/icemoon, /area/icemoon/surface/outdoors/less_spawns) +"atH" = ( +/obj/structure/railing/corner, +/obj/structure/railing/corner{ + dir = 8 + }, +/obj/machinery/door/poddoor/shutters/window{ + id = "executionshutters"; + name = "Exterior Shutters" + }, +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/security/execution/education) "atI" = ( /obj/structure/table/glass, /obj/item/shovel/spade, @@ -1466,16 +1543,6 @@ }, /turf/open/floor/iron, /area/station/cargo/miningdock) -"auw" = ( -/obj/machinery/atmospherics/components/binary/pump/on{ - dir = 8; - name = "Air to Distro" - }, -/obj/structure/sink/directional/south, -/obj/item/mop, -/obj/item/reagent_containers/cup/bucket, -/turf/open/floor/iron/smooth, -/area/mine/laborcamp/security) "auz" = ( /obj/machinery/door/airlock/engineering{ name = "Utilities Closet" @@ -1506,6 +1573,14 @@ /obj/structure/cable, /turf/open/floor/carpet/royalblue, /area/station/command/heads_quarters/captain) +"auZ" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Showers" + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/mine/laborcamp) "avb" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, @@ -1572,13 +1647,6 @@ /obj/effect/landmark/firealarm_sanity, /turf/open/floor/iron/white, /area/station/maintenance/aft/greater) -"avP" = ( -/obj/effect/turf_decal/bot, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/turf/open/floor/iron, -/area/mine/laborcamp) "awa" = ( /turf/open/openspace, /area/station/science/ordnance/office) @@ -1815,6 +1883,23 @@ /obj/effect/mapping_helpers/airlock/access/all/engineering/atmos, /turf/open/floor/iron/dark, /area/station/engineering/atmos) +"ayv" = ( +/obj/machinery/light/small/directional/south, +/obj/structure/closet/secure_closet/brig{ + id = "Cell 3"; + name = "Cell 3 locker" + }, +/obj/structure/cable, +/obj/machinery/flasher/directional/south{ + id = "Cell 3" + }, +/turf/open/floor/iron/smooth, +/area/station/security/brig) +"ayz" = ( +/obj/effect/landmark/generic_maintenance_landmark, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/turf/open/floor/plating, +/area/station/maintenance/fore) "ayC" = ( /obj/structure/stairs/west, /turf/open/floor/iron/smooth, @@ -1854,6 +1939,13 @@ }, /turf/open/floor/iron/dark/textured, /area/station/security/prison) +"azd" = ( +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, +/turf/open/floor/iron, +/area/station/security/brig/upper) "aze" = ( /obj/structure/railing{ dir = 8 @@ -1928,12 +2020,11 @@ }, /turf/open/floor/circuit/red, /area/station/ai/upload/chamber) -"aAl" = ( -/obj/machinery/computer/mech_bay_power_console{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/security/mechbay) +"aAk" = ( +/obj/structure/cable/multilayer/multiz, +/obj/structure/sign/warning/electric_shock/directional/north, +/turf/open/floor/plating, +/area/station/maintenance/department/security) "aAv" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -1942,6 +2033,13 @@ /obj/effect/turf_decal/tile/blue/half/contrasted, /turf/open/floor/iron, /area/station/command/bridge) +"aAw" = ( +/obj/effect/turf_decal/tile/blue/anticorner/contrasted{ + dir = 8 + }, +/obj/machinery/modular_computer/preset/command, +/turf/open/floor/iron, +/area/station/command/bridge) "aAM" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -1969,6 +2067,14 @@ /obj/machinery/firealarm/directional/south, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/cmo) +"aBx" = ( +/obj/machinery/airalarm/directional/west, +/obj/machinery/light/small/directional/west, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 4 + }, +/turf/open/floor/iron/dark/textured, +/area/station/security/interrogation) "aBE" = ( /obj/machinery/door/airlock{ name = "Custodial Closet" @@ -2125,6 +2231,16 @@ dir = 8 }, /area/station/science/ordnance/office) +"aDf" = ( +/obj/structure/table, +/obj/item/kitchen/fork/plastic, +/obj/item/kitchen/spoon/plastic{ + pixel_y = -3; + pixel_x = -6 + }, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/security/prison/mess) "aDl" = ( /obj/structure/rack, /obj/item/bouquet, @@ -2158,6 +2274,13 @@ /obj/effect/landmark/start/prisoner, /turf/open/floor/iron/dark/side, /area/station/security/prison) +"aDL" = ( +/obj/structure/window/reinforced/spawner/directional/south, +/obj/structure/flora/bush/sparsegrass/style_random, +/turf/open/misc/ashplanet/wateryrock{ + initial_gas_mix = "o2=22;n2=82;TEMP=293.15" + }, +/area/station/security/prison/rec) "aDM" = ( /obj/effect/spawner/structure/window/hollow/reinforced/middle, /turf/open/floor/plating, @@ -2204,6 +2327,13 @@ /obj/structure/railing/corner, /turf/open/floor/iron/dark/textured, /area/station/security/prison) +"aFb" = ( +/obj/effect/turf_decal/bot, +/obj/item/radio/intercom/directional/north, +/obj/item/coin/gold, +/obj/structure/closet/crate, +/turf/open/floor/iron, +/area/mine/production) "aFg" = ( /obj/machinery/button/door/directional/east{ id = "lawyer_blast"; @@ -2294,14 +2424,6 @@ dir = 10 }, /area/station/science/research) -"aGr" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/camera/directional/east{ - c_tag = "Labor Camp Operations"; - network = list("labor") - }, -/turf/open/floor/iron, -/area/mine/laborcamp) "aGB" = ( /obj/machinery/telecomms/processor/preset_two, /turf/open/floor/iron/dark/telecomms, @@ -2315,16 +2437,6 @@ }, /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/underground/explored) -"aGW" = ( -/obj/machinery/door/airlock/highsecurity{ - name = "Labor Camp Monitoring" - }, -/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/all/security/brig, -/turf/open/floor/iron, -/area/mine/laborcamp) "aHo" = ( /obj/structure/cable, /obj/item/wrench, @@ -2332,6 +2444,11 @@ /obj/machinery/portable_atmospherics/canister, /turf/open/floor/iron/white, /area/station/science/xenobiology) +"aHq" = ( +/obj/effect/turf_decal/bot, +/obj/machinery/portable_atmospherics/canister/oxygen, +/turf/open/floor/iron, +/area/mine/laborcamp) "aHt" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden, @@ -2349,18 +2466,6 @@ }, /turf/open/floor/iron/dark, /area/station/maintenance/disposal/incinerator) -"aHw" = ( -/obj/structure/rack, -/obj/item/poster/random_official, -/obj/item/poster/random_official, -/obj/item/poster/random_official, -/obj/item/poster/random_official, -/obj/item/poster/random_official, -/obj/item/poster/random_official, -/obj/item/poster/random_official, -/obj/item/poster/random_official, -/turf/open/floor/iron/dark/textured, -/area/station/security/prison) "aHz" = ( /obj/structure/cable, /obj/effect/spawner/structure/window/reinforced, @@ -2536,11 +2641,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/chemistry) -"aJu" = ( -/obj/machinery/light/small/directional/east, -/obj/machinery/space_heater, -/turf/open/floor/vault, -/area/station/security/prison/rec) "aJw" = ( /obj/structure/table, /obj/effect/spawner/random/entertainment/drugs, @@ -2652,6 +2752,11 @@ /obj/structure/cable, /turf/open/floor/iron/white/corner, /area/station/hallway/secondary/entry) +"aLy" = ( +/obj/effect/turf_decal/tile/red/half/contrasted, +/obj/machinery/firealarm/directional/south, +/turf/open/floor/iron, +/area/station/security/brig/upper) "aLz" = ( /obj/machinery/conveyor{ id = "garbage" @@ -2679,10 +2784,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/visible, /turf/open/floor/iron, /area/station/maintenance/disposal/incinerator) -"aLM" = ( -/obj/machinery/shower/directional/south, -/turf/open/floor/iron/showroomfloor, -/area/station/security/prison/toilet) +"aLN" = ( +/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/south, +/turf/open/floor/iron/smooth, +/area/station/security/eva) "aLX" = ( /obj/machinery/door/airlock/maintenance, /obj/structure/cable, @@ -2759,12 +2867,6 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) -"aML" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/security/processing) "aMP" = ( /obj/effect/turf_decal/tile/yellow, /turf/open/floor/iron/white, @@ -2948,22 +3050,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/port/aft) -"aPW" = ( -/obj/structure/table, -/obj/item/storage/box/chemimp{ - pixel_x = 6 - }, -/obj/item/storage/box/trackimp{ - pixel_x = -3 - }, -/obj/item/storage/lockbox/loyalty, -/obj/machinery/light_switch/directional/east, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/turf_decal/tile/red/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron/dark/textured, -/area/station/security/armory/upper) "aPZ" = ( /obj/machinery/atmospherics/pipe/multiz/scrubbers/visible/layer2, /obj/machinery/atmospherics/pipe/multiz/supply/visible/layer4, @@ -3003,11 +3089,6 @@ /obj/structure/rack, /turf/open/floor/iron/textured_large, /area/station/commons/storage/mining) -"aQQ" = ( -/obj/effect/decal/cleanable/blood/old, -/obj/effect/mapping_helpers/burnt_floor, -/turf/open/floor/plating, -/area/station/security/prison/safe) "aQR" = ( /obj/structure/cable, /turf/open/floor/circuit/telecomms/mainframe, @@ -3044,15 +3125,6 @@ /obj/machinery/portable_atmospherics/canister/carbon_dioxide, /turf/open/floor/engine/co2, /area/station/engineering/atmos) -"aRm" = ( -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 4 - }, -/obj/machinery/door/airlock/security/glass{ - name = "Labor Camp Shuttle Security Airlock" - }, -/turf/open/floor/iron, -/area/mine/laborcamp) "aRn" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/disposalpipe/segment{ @@ -3125,6 +3197,11 @@ }, /turf/open/floor/iron, /area/station/commons/vacant_room/commissary) +"aSa" = ( +/obj/machinery/firealarm/directional/south, +/obj/effect/turf_decal/tile/red, +/turf/open/floor/iron, +/area/station/security/brig) "aSe" = ( /obj/machinery/atmospherics/components/binary/pump{ dir = 8; @@ -3407,6 +3484,9 @@ /obj/effect/mapping_helpers/airlock/access/any/supply/maintenance, /turf/open/floor/plating, /area/station/maintenance/department/cargo) +"aVg" = ( +/turf/closed/wall/r_wall, +/area/station/maintenance/department/security) "aVi" = ( /obj/effect/decal/cleanable/generic, /turf/open/floor/plating, @@ -3427,6 +3507,11 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central) +"aVt" = ( +/obj/structure/chair/stool/directional/south, +/obj/structure/cable, +/turf/open/floor/iron, +/area/mine/laborcamp) "aVw" = ( /obj/structure/disposalpipe/segment, /obj/effect/turf_decal/tile/blue/half/contrasted{ @@ -3478,31 +3563,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) -"aWk" = ( -/obj/machinery/door/poddoor/shutters{ - dir = 1; - id = "armory"; - name = "Armory Shutter" - }, -/obj/machinery/button/door/directional/east{ - id = "armory"; - name = "Armory Shutters"; - req_access = list("armory") - }, -/turf/open/floor/iron, -/area/station/security/armory/upper) -"aWo" = ( -/obj/machinery/hydroponics/constructable, -/obj/effect/decal/cleanable/dirt, -/obj/item/seeds/redbeet, -/obj/effect/turf_decal/tile/green/half/contrasted{ - dir = 4 - }, -/obj/effect/turf_decal/siding/green{ - dir = 4 - }, -/turf/open/floor/iron/dark, -/area/mine/laborcamp) "aWD" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -3517,17 +3577,6 @@ }, /turf/open/floor/iron/large, /area/station/hallway/secondary/entry) -"aWV" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 4 - }, -/obj/machinery/camera/directional/south{ - c_tag = "Labor Camp Mud Room"; - network = list("labor") - }, -/obj/structure/cable, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "aXc" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment, @@ -3570,11 +3619,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) -"aXq" = ( -/obj/item/bedsheet/red, -/mob/living/simple_animal/bot/secbot/beepsky, -/turf/open/floor/plating, -/area/station/maintenance/fore) +"aXF" = ( +/obj/effect/turf_decal/trimline/red/warning{ + dir = 9 + }, +/obj/effect/turf_decal/stripes/red/line{ + dir = 6 + }, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/surface/outdoors/nospawn) "aXG" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -3611,6 +3664,17 @@ /obj/machinery/hydroponics/soil, /turf/open/floor/grass, /area/station/maintenance/starboard/fore) +"aYl" = ( +/obj/machinery/ai_slipper{ + uses = 10 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable/layer3, +/mob/living/basic/bot/secbot/pingsky, +/turf/open/floor/iron/dark, +/area/station/ai/satellite/interior) "aYm" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -3630,19 +3694,6 @@ "aYJ" = ( /turf/open/floor/iron/white, /area/station/science/research) -"aYM" = ( -/obj/effect/turf_decal/bot, -/obj/structure/closet/crate, -/obj/item/coin/gold, -/obj/item/radio/intercom/directional/north, -/turf/open/floor/iron, -/area/mine/production) -"aYQ" = ( -/obj/machinery/shower/directional/south, -/obj/item/soap/nanotrasen, -/obj/item/bikehorn/rubberducky/plasticducky, -/turf/open/floor/iron/freezer, -/area/mine/laborcamp) "aZd" = ( /turf/open/floor/plating, /area/station/medical/virology) @@ -3659,14 +3710,6 @@ /obj/structure/table/wood, /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) -"aZo" = ( -/obj/structure/extinguisher_cabinet/directional/west, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/turf_decal/tile/red/half/contrasted{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/security/brig/upper) "aZq" = ( /obj/item/kirbyplants/potty, /turf/open/floor/plating, @@ -3849,6 +3892,14 @@ "bbo" = ( /turf/open/floor/iron, /area/station/construction) +"bbq" = ( +/obj/machinery/camera/directional/north{ + c_tag = "Security - EVA Suits" + }, +/obj/item/radio/intercom/directional/north, +/obj/machinery/light/small/red/directional/north, +/turf/open/floor/iron/smooth, +/area/station/security/eva) "bbr" = ( /obj/effect/turf_decal/tile/yellow{ dir = 1 @@ -3928,6 +3979,24 @@ /obj/effect/mapping_helpers/airlock/access/all/supply/qm, /turf/open/floor/plating, /area/station/maintenance/port/greater) +"bcy" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/button/door/directional/south{ + pixel_x = 7; + pixel_y = -26; + name = "Visitation Shutters Control"; + id = "visitation"; + req_access = list("brig") + }, +/obj/machinery/button/flasher{ + id = "visitorflash"; + pixel_y = -26; + pixel_x = -7 + }, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/security/prison/visit) "bcC" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -3945,6 +4014,18 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/science/xenobiology) +"bcH" = ( +/obj/structure/rack, +/obj/machinery/camera/directional/west{ + c_tag = "Security - Permabrig Observation Prep"; + network = list("ss13","prison") + }, +/obj/structure/sign/warning/gas_mask/directional/west, +/obj/item/clothing/suit/hooded/wintercoat, +/obj/item/clothing/suit/hooded/wintercoat, +/obj/item/clothing/suit/hooded/wintercoat, +/turf/open/floor/vault, +/area/station/security/prison/rec) "bcN" = ( /turf/closed/wall/r_wall, /area/station/hallway/primary/central) @@ -3958,17 +4039,6 @@ "bde" = ( /turf/open/floor/plating, /area/station/cargo/storage) -"bdo" = ( -/obj/structure/table/wood, -/obj/item/food/grown/poppy{ - pixel_y = 2 - }, -/obj/item/storage/photo_album/prison, -/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/dark, -/area/station/security/prison/rec) "bdp" = ( /obj/machinery/airalarm/directional/west, /obj/structure/disposalpipe/segment, @@ -4007,13 +4077,6 @@ /obj/effect/mapping_helpers/airlock/access/all/engineering/external, /turf/open/floor/plating, /area/station/maintenance/aft/greater) -"bdJ" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/landmark/event_spawn, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) "bdK" = ( /obj/effect/turf_decal/tile/green{ dir = 4 @@ -4051,13 +4114,6 @@ /obj/effect/spawner/structure/window/reinforced/plasma, /turf/open/floor/plating/icemoon, /area/station/engineering/atmos) -"bec" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/smooth, -/area/station/engineering/lobby) "ben" = ( /obj/machinery/bluespace_beacon, /obj/effect/turf_decal/stripes/line{ @@ -4082,24 +4138,6 @@ /obj/structure/reagent_dispensers/fueltank, /turf/open/floor/plating, /area/station/maintenance/port/aft) -"beQ" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/siding/wood{ - dir = 8 - }, -/obj/structure/sign/painting/large, -/turf/open/floor/wood, -/area/station/security/prison/rec) -"beT" = ( -/obj/structure/table/glass, -/obj/item/stack/medical/wrap/gauze{ - pixel_x = 2 - }, -/obj/item/stack/medical/mesh, -/obj/item/stack/medical/suture, -/obj/effect/turf_decal/tile/blue/full, -/turf/open/floor/iron/large, -/area/station/medical/treatment_center) "bff" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/iron, @@ -4166,6 +4204,15 @@ /obj/effect/spawner/random/maintenance/two, /turf/open/floor/plating, /area/station/maintenance/aft/greater) +"bgn" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Infirmary" + }, +/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/mine/laborcamp) "bgs" = ( /obj/structure/sign/poster/random/directional/east, /obj/structure/cable, @@ -4292,6 +4339,10 @@ dir = 8 }, /area/mine/living_quarters) +"bir" = ( +/obj/structure/cable, +/turf/open/floor/catwalk_floor/iron, +/area/mine/laborcamp) "bit" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/rack, @@ -4487,6 +4538,12 @@ dir = 9 }, /area/station/science/research) +"bkO" = ( +/obj/structure/closet/secure_closet/security/sec, +/obj/machinery/status_display/ai/directional/north, +/obj/effect/turf_decal/bot, +/turf/open/floor/iron/smooth_edge, +/area/station/security/lockers) "bkQ" = ( /obj/structure/tank_holder/extinguisher, /obj/structure/sign/warning/biohazard/directional/north, @@ -4526,6 +4583,15 @@ dir = 1 }, /area/station/security/prison/workout) +"bkY" = ( +/obj/effect/turf_decal/trimline/red/warning{ + dir = 6 + }, +/obj/effect/turf_decal/stripes/red/line{ + dir = 4 + }, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/surface/outdoors/nospawn) "bla" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -4553,17 +4619,6 @@ }, /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/underground/explored) -"blk" = ( -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 8 - }, -/obj/machinery/door/airlock/security/glass{ - name = "Labor Camp Shuttle Prisoner Airlock" - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/mapping_helpers/airlock/access/all/security/brig, -/turf/open/floor/iron, -/area/mine/laborcamp) "bll" = ( /turf/open/floor/iron, /area/station/engineering/storage_shared) @@ -4586,12 +4641,6 @@ /obj/structure/girder, /turf/open/floor/plating, /area/station/maintenance/port/aft) -"blT" = ( -/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/showroomfloor, -/area/station/security/processing) "blU" = ( /obj/structure/table/glass, /obj/item/storage/box/syringes, @@ -4619,14 +4668,6 @@ /obj/effect/spawner/random/structure/steam_vent, /turf/open/floor/plating, /area/station/maintenance/port/greater) -"bml" = ( -/obj/structure/table, -/obj/item/storage/medkit/regular, -/obj/effect/turf_decal/tile/blue/opposingcorners{ - dir = 1 - }, -/turf/open/floor/iron/white, -/area/mine/laborcamp) "bmu" = ( /obj/structure/table, /obj/item/grenade/chem_grenade/cleaner, @@ -4647,6 +4688,14 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/central) +"bmE" = ( +/obj/structure/toilet/greyscale{ + cistern_open = 1; + dir = 2 + }, +/obj/machinery/light/small/dim/directional/west, +/turf/open/floor/iron/showroomfloor, +/area/mine/laborcamp) "bmM" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/cable, @@ -4739,16 +4788,6 @@ /obj/effect/mapping_helpers/airlock/access/all/engineering/atmos, /turf/open/floor/plating, /area/station/maintenance/aft/lesser) -"bnM" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 - }, -/obj/machinery/camera/directional/east{ - c_tag = "Security - Interrogation"; - network = list("interrogation") - }, -/turf/open/floor/iron/dark/textured, -/area/station/security/interrogation) "bnZ" = ( /obj/machinery/atmospherics/pipe/smart/manifold/purple/visible/layer2{ dir = 1 @@ -4784,14 +4823,6 @@ }, /turf/open/floor/plating/snowed/icemoon, /area/icemoon/underground/explored) -"boO" = ( -/obj/structure/chair/sofa/left/brown{ - dir = 8 - }, -/obj/machinery/light/directional/east, -/obj/structure/cable, -/turf/open/floor/carpet/blue, -/area/station/security/prison/work) "boQ" = ( /obj/machinery/atmospherics/pipe/layer_manifold/supply/visible, /turf/closed/wall/r_wall, @@ -4856,6 +4887,13 @@ /obj/effect/mapping_helpers/no_atoms_ontop, /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/underground/explored) +"bpv" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/station/security/prison/workout) "bpw" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/effect/landmark/event_spawn, @@ -4914,10 +4952,6 @@ /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) -"bqf" = ( -/obj/machinery/light/small/directional/south, -/turf/open/floor/plating/snowed/smoothed/icemoon, -/area/icemoon/surface/outdoors/labor_camp) "bqi" = ( /obj/item/clothing/glasses/meson, /obj/item/storage/bag/ore, @@ -4946,26 +4980,6 @@ /obj/machinery/airalarm/directional/west, /turf/open/floor/circuit, /area/station/ai/satellite/hallway) -"bqx" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/obj/machinery/light/floor, -/turf/open/floor/iron/dark, -/area/station/security/processing) -"bqz" = ( -/obj/machinery/hydroponics/constructable, -/obj/structure/window/reinforced/spawner/directional/west, -/obj/item/cultivator, -/obj/item/seeds/potato, -/obj/effect/turf_decal/tile/green/half/contrasted{ - dir = 8 - }, -/obj/effect/turf_decal/siding/green{ - dir = 8 - }, -/turf/open/floor/iron/dark, -/area/mine/laborcamp) "bqF" = ( /obj/structure/chair{ dir = 4 @@ -5063,19 +5077,6 @@ /obj/structure/chair/sofa/corp, /turf/open/floor/iron/dark, /area/station/engineering/lobby) -"brX" = ( -/obj/structure/plasticflaps, -/obj/machinery/conveyor{ - dir = 8; - id = "mining_internal" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line, -/obj/machinery/light/small/directional/south, -/turf/open/floor/iron, -/area/mine/production) "brY" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 1 @@ -5088,16 +5089,6 @@ }, /turf/open/floor/plating, /area/mine/eva/lower) -"bsd" = ( -/obj/structure/chair/stool/directional/south, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/obj/machinery/light/small/dim/directional/west, -/obj/structure/sign/poster/official/obey/directional/west, -/turf/open/floor/iron, -/area/mine/laborcamp) "bse" = ( /obj/effect/spawner/random/trash/mess, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -5146,6 +5137,12 @@ }, /turf/open/floor/plating/snowed/icemoon, /area/icemoon/surface/outdoors/less_spawns) +"bsv" = ( +/obj/structure/punching_bag, +/obj/effect/turf_decal/bot, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/dark/textured, +/area/station/security/prison/workout) "bsG" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/research/glass{ @@ -5305,11 +5302,15 @@ "btU" = ( /turf/closed/wall, /area/station/medical/morgue) -"bub" = ( -/obj/machinery/vending/cola/red, -/obj/machinery/light/warm/directional/north, -/turf/open/floor/iron/dark/textured, -/area/station/security/prison) +"btV" = ( +/obj/structure/cable, +/obj/machinery/door/airlock/security/glass{ + name = "Brig" + }, +/obj/effect/mapping_helpers/airlock/access/any/security/brig, +/obj/machinery/door/firedoor, +/turf/open/floor/iron, +/area/station/security/brig) "bum" = ( /obj/machinery/holopad, /obj/effect/turf_decal/bot, @@ -5340,14 +5341,10 @@ }, /turf/open/floor/iron/dark, /area/station/hallway/secondary/entry) -"buR" = ( -/obj/structure/table, -/obj/machinery/cell_charger, -/obj/item/stock_parts/power_store/cell/potato{ - name = "\improper Beepsky's emergency battery" - }, -/turf/open/floor/plating, -/area/station/maintenance/fore) +"buG" = ( +/obj/effect/turf_decal/tile/red, +/turf/open/floor/iron, +/area/station/security/brig) "buU" = ( /obj/structure/closet, /obj/effect/spawner/random/maintenance, @@ -5393,13 +5390,14 @@ }, /turf/open/floor/iron, /area/station/commons/locker) -"bvj" = ( -/obj/structure/table, -/obj/item/paper_bin, -/obj/item/pen, -/obj/effect/turf_decal/tile/red, -/turf/open/floor/iron, -/area/mine/laborcamp/security) +"bvh" = ( +/obj/structure/toilet{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/small/dim/directional/south, +/turf/open/floor/iron/smooth, +/area/station/security/holding_cell) "bvq" = ( /obj/effect/turf_decal/bot, /obj/machinery/light/directional/north, @@ -5454,22 +5452,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark/textured_large, /area/station/maintenance/department/medical/morgue) -"bvX" = ( -/obj/machinery/computer/security/hos, -/obj/machinery/requests_console/directional/north{ - department = "Head of Security's Desk"; - name = "Head of Security Requests Console" - }, -/obj/effect/mapping_helpers/requests_console/announcement, -/obj/effect/mapping_helpers/requests_console/information, -/obj/effect/mapping_helpers/requests_console/assistance, -/obj/item/radio/intercom/directional/west, -/obj/machinery/button/door/directional/north{ - id = "hosspace"; - name = "Icemoon Shutters Control" - }, -/turf/open/floor/carpet/royalblue, -/area/station/command/heads_quarters/hos) "bvY" = ( /obj/machinery/firealarm/directional/south, /obj/effect/turf_decal/tile/red/half/contrasted, @@ -5478,12 +5460,6 @@ "bwh" = ( /turf/closed/wall/mineral/iron, /area/icemoon/underground/explored) -"bwi" = ( -/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/security/prison/rec) "bwl" = ( /obj/structure/chair/comfy/black{ dir = 8 @@ -5593,10 +5569,6 @@ dir = 5 }, /area/station/science/lab) -"bxQ" = ( -/obj/structure/cable/multilayer/multiz, -/turf/open/floor/plating, -/area/station/maintenance/fore) "bxS" = ( /obj/effect/spawner/structure/window/hollow/reinforced/middle, /turf/open/floor/plating, @@ -5647,15 +5619,6 @@ }, /turf/open/floor/iron/dark/textured_large, /area/station/cargo/bitrunning/den) -"byq" = ( -/obj/effect/turf_decal/trimline/red/filled/line{ - dir = 5 - }, -/obj/structure/cable, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, -/obj/item/kirbyplants/random, -/turf/open/floor/iron/white, -/area/station/security/prison/safe) "byv" = ( /obj/effect/mapping_helpers/broken_floor, /obj/item/trash/semki, @@ -5769,6 +5732,11 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos/storage) +"bzG" = ( +/obj/machinery/pdapainter/security, +/obj/structure/cable, +/turf/open/floor/wood/large, +/area/station/command/heads_quarters/hos) "bzQ" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -5778,6 +5746,13 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central) +"bzS" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, +/obj/machinery/light/small/dim/directional/south, +/turf/open/floor/iron/showroomfloor, +/area/mine/laborcamp) "bzT" = ( /obj/machinery/computer/station_alert{ dir = 4 @@ -5789,6 +5764,15 @@ "bzW" = ( /turf/open/floor/engine/plasma, /area/station/engineering/atmos) +"bzX" = ( +/obj/structure/railing/corner/end{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/iron, +/area/mine/production) "bAa" = ( /obj/structure/disposalpipe/segment{ dir = 10 @@ -5796,10 +5780,6 @@ /obj/structure/chair/stool/directional/north, /turf/open/floor/carpet, /area/station/command/heads_quarters/qm) -"bAk" = ( -/obj/machinery/firealarm/directional/west, -/turf/open/floor/carpet, -/area/station/security/prison/rec) "bAo" = ( /obj/effect/turf_decal/tile/blue{ dir = 1 @@ -5818,37 +5798,11 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/port) -"bAE" = ( -/obj/structure/table/glass, -/obj/item/stack/medical/wrap/gauze{ - pixel_x = -2; - pixel_y = 8 - }, -/obj/item/stack/medical/mesh{ - pixel_x = 6; - pixel_y = 5 - }, -/obj/item/stack/medical/suture, -/obj/item/reagent_containers/cup/bottle/epinephrine, -/obj/item/reagent_containers/cup/bottle/multiver{ - pixel_x = 6 - }, -/obj/item/reagent_containers/syringe, -/obj/machinery/defibrillator_mount/directional/east, -/obj/effect/turf_decal/tile/blue/full, -/turf/open/floor/iron/large, -/area/station/medical/treatment_center) "bAF" = ( /turf/open/floor/iron/chapel{ dir = 1 }, /area/station/service/chapel) -"bAM" = ( -/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/mine/laborcamp/security) "bAT" = ( /obj/structure/table/reinforced, /obj/machinery/fax{ @@ -5873,20 +5827,18 @@ /obj/machinery/light/floor, /turf/open/floor/iron, /area/station/engineering/lobby) +"bBt" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, +/obj/structure/cable, +/obj/item/radio/intercom/directional/south, +/turf/open/floor/iron/smooth, +/area/station/security/brig) "bBw" = ( /obj/item/trash/sosjerky, /turf/open/floor/plating, /area/station/maintenance/aft/greater) -"bBx" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 - }, -/obj/structure/cable, -/obj/machinery/door/window/brigdoor/right/directional/east{ - req_access = list("armory") - }, -/turf/open/floor/iron/dark, -/area/station/security/execution/education) "bBE" = ( /obj/item/radio/intercom/directional/south, /obj/effect/turf_decal/tile/purple/anticorner/contrasted, @@ -5909,23 +5861,17 @@ /obj/structure/flora/rock/pile/icy/style_random, /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/underground/explored) +"bBP" = ( +/obj/structure/cable, +/obj/structure/chair/office{ + dir = 1 + }, +/turf/open/floor/iron, +/area/mine/laborcamp/security) "bBW" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/engineering/atmos/pumproom) -"bCd" = ( -/obj/machinery/door/airlock/maintenance{ - name = "Genetics Lab Maintenance" - }, -/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/mapping_helpers/airlock/access/all/science/genetics, -/turf/open/floor/plating, -/area/station/maintenance/starboard/upper) "bCf" = ( /obj/machinery/door/poddoor/preopen{ id = "cmoprivacy"; @@ -5943,6 +5889,11 @@ }, /turf/open/floor/iron/cafeteria, /area/station/security/prison/work) +"bCr" = ( +/obj/structure/closet/boxinggloves, +/obj/structure/sign/warning/electric_shock/directional/south, +/turf/open/floor/iron, +/area/station/security/prison/workout) "bCs" = ( /obj/machinery/door/airlock/engineering{ name = "Construction Area" @@ -5997,10 +5948,6 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos) -"bDj" = ( -/obj/machinery/light/warm/directional/south, -/turf/open/floor/iron/dark/textured, -/area/station/security/prison/workout) "bDl" = ( /obj/machinery/light/small/directional/north, /obj/effect/turf_decal/weather/snow/corner{ @@ -6028,27 +5975,10 @@ dir = 1 }, /area/mine/production) -"bDF" = ( -/obj/structure/table/wood, -/obj/item/food/grown/harebell, -/obj/structure/cable, -/turf/open/floor/iron/dark, -/area/station/security/prison/rec) "bDH" = ( /obj/effect/landmark/start/chaplain, /turf/open/floor/iron/dark, /area/station/service/chapel/office) -"bDI" = ( -/obj/structure/rack, -/obj/item/storage/bag/ore, -/obj/item/flashlight, -/obj/item/pickaxe, -/obj/item/clothing/glasses/meson, -/obj/item/mining_scanner, -/obj/effect/decal/cleanable/dirt, -/obj/item/clothing/suit/hooded/wintercoat, -/turf/open/floor/iron, -/area/mine/laborcamp) "bDR" = ( /obj/effect/turf_decal/tile/red/half/contrasted{ dir = 4 @@ -6082,16 +6012,6 @@ }, /turf/open/floor/iron/dark, /area/station/maintenance/disposal) -"bEf" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/dark/textured, -/area/station/security/interrogation) -"bEi" = ( -/obj/structure/sign/poster/official/work_for_a_future/directional/north, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/mine/laborcamp) "bEk" = ( /obj/structure/railing/wooden_fence{ dir = 4 @@ -6347,6 +6267,13 @@ /obj/effect/turf_decal/tile/yellow/half/contrasted, /turf/open/floor/iron/white, /area/station/medical/pharmacy) +"bHR" = ( +/obj/effect/spawner/random/contraband/prison, +/obj/structure/chair/sofa/corp/left{ + dir = 1 + }, +/turf/open/floor/carpet/blue, +/area/station/security/prison/work) "bIa" = ( /obj/machinery/atmospherics/components/binary/pump/on{ dir = 8; @@ -6472,34 +6399,12 @@ /obj/effect/turf_decal/tile/red/half/contrasted, /turf/open/floor/iron/dark/textured, /area/station/security/armory/upper) -"bJp" = ( -/obj/machinery/camera/directional/east{ - c_tag = "Security - Permabrig Workout"; - network = list("ss13","prison"); - view_range = 5 - }, -/obj/effect/turf_decal/trimline/red/warning{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/red/line{ - dir = 4 - }, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) -"bJx" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/light/directional/south, -/turf/open/floor/iron, -/area/mine/laborcamp) "bJD" = ( /obj/machinery/atmospherics/components/trinary/filter/atmos/n2{ dir = 4 }, /turf/open/floor/iron, /area/station/engineering/atmos) -"bJE" = ( -/turf/open/floor/iron/dark/smooth_large, -/area/station/security/processing) "bJQ" = ( /obj/structure/table/wood, /obj/item/stack/package_wrap, @@ -6564,6 +6469,10 @@ }, /turf/open/floor/iron, /area/station/science/xenobiology) +"bKK" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, +/turf/open/floor/iron, +/area/station/security/prison/visit) "bKN" = ( /obj/machinery/door/airlock/security/glass{ name = "Brig Control" @@ -6578,6 +6487,12 @@ /obj/machinery/door/firedoor, /turf/open/floor/iron/showroomfloor, /area/station/security/warden) +"bKU" = ( +/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/dark, +/area/station/security/range) "bKZ" = ( /obj/effect/decal/cleanable/glass, /obj/effect/decal/cleanable/dirt, @@ -6585,27 +6500,23 @@ dir = 5 }, /area/station/maintenance/port/aft) -"bLc" = ( -/turf/open/floor/iron/dark/textured_edge{ - dir = 1 - }, -/area/station/security/prison) -"bLd" = ( -/obj/structure/cable, -/obj/machinery/power/apc/auto_name/directional/west, -/turf/open/floor/iron/dark/textured, -/area/station/security/interrogation) +"bLl" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/item/radio/intercom/directional/east, +/turf/open/floor/iron/smooth, +/area/station/security/execution/transfer) "bLn" = ( /obj/machinery/light/directional/west, /obj/item/radio/intercom/directional/west, /obj/effect/landmark/event_spawn, /turf/open/floor/iron/freezer, /area/station/commons/toilet/locker) -"bLq" = ( +"bLw" = ( +/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/broken_floor, -/turf/open/floor/wood, -/area/station/maintenance/fore) +/turf/open/floor/plating, +/area/station/maintenance/department/security) "bLz" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -6617,26 +6528,6 @@ /obj/structure/closet, /turf/open/floor/plating, /area/station/maintenance/port/aft) -"bLI" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/camera/directional/south{ - c_tag = "Security - Transport Parlor" - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/power/apc/auto_name/directional/south, -/turf/open/floor/iron, -/area/station/security/processing) -"bLL" = ( -/obj/structure/sink/kitchen/directional/west{ - desc = "A sink used for washing one's hands and face. It looks rusty and home-made"; - name = "old sink" - }, -/turf/open/floor/iron/freezer, -/area/mine/laborcamp) "bLQ" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/turf_decal/siding/wood{ @@ -6653,6 +6544,17 @@ /obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) +"bMe" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "labor"; + name = "Labor Camp Blast Door" + }, +/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/mine/laborcamp) "bMk" = ( /obj/item/radio/intercom/directional/west, /turf/open/floor/wood, @@ -6670,18 +6572,6 @@ }, /turf/open/floor/iron/dark, /area/station/engineering/storage/tech) -"bMz" = ( -/obj/docking_port/stationary{ - dir = 8; - dwidth = 2; - height = 5; - name = "fore bay 1"; - roundstart_template = /datum/map_template/shuttle/labour/box; - shuttle_id = "laborcamp_home"; - width = 9 - }, -/turf/open/misc/asteroid/snow/icemoon, -/area/icemoon/surface/outdoors/nospawn) "bMC" = ( /obj/structure/table, /obj/item/flashlight{ @@ -6761,11 +6651,6 @@ /obj/effect/mapping_helpers/airlock/access/all/engineering/atmos, /turf/open/floor/iron/dark, /area/station/engineering/atmos/storage/gas) -"bOg" = ( -/obj/item/kirbyplants/random, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/showroomfloor, -/area/station/security/processing) "bOh" = ( /obj/structure/table/wood, /obj/item/folder/red, @@ -6949,12 +6834,29 @@ }, /turf/open/floor/iron/dark/diagonal, /area/station/engineering/atmos/storage) +"bQg" = ( +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 8 + }, +/obj/machinery/airalarm/directional/west, +/turf/open/floor/iron, +/area/station/security/brig/upper) "bQh" = ( /obj/item/radio/intercom/directional/north, /turf/open/floor/iron/dark/corner{ dir = 1 }, /area/station/hallway/primary/starboard) +"bQq" = ( +/obj/structure/closet/emcloset, +/obj/machinery/camera/directional/north{ + c_tag = "Security - Access" + }, +/obj/effect/turf_decal/tile/red/half, +/obj/machinery/light/directional/north, +/obj/machinery/airalarm/directional/north, +/turf/open/floor/iron/smooth_half, +/area/station/security/brig/upper) "bQx" = ( /obj/structure/ladder{ name = "upper dispenser access" @@ -6972,12 +6874,6 @@ }, /turf/open/floor/plating, /area/mine/eva/lower) -"bQS" = ( -/obj/machinery/power/apc/auto_name/directional/south, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/turf/open/floor/iron/dark, -/area/station/security/execution/education) "bRb" = ( /obj/structure/flora/bush/lavendergrass/style_random, /turf/open/floor/grass, @@ -7075,6 +6971,17 @@ }, /turf/open/floor/iron/dark/textured, /area/station/engineering/storage/tech) +"bRY" = ( +/obj/machinery/door/airlock/medical/glass{ + id_tag = "MedbayFoyer"; + name = "Medbay" + }, +/obj/effect/mapping_helpers/airlock/access/all/medical/general, +/obj/effect/turf_decal/tile/blue/full, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/unres/delayed, +/turf/open/floor/iron/large, +/area/station/medical/medbay/lobby) "bSi" = ( /obj/effect/turf_decal/trimline/yellow/filled/line, /obj/structure/railing/corner{ @@ -7082,27 +6989,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/chemistry) -"bSk" = ( -/obj/machinery/door/poddoor/preopen{ - id = "Prison Gate"; - name = "Prison Blast Door" - }, -/obj/machinery/door/firedoor, -/obj/structure/cable, -/obj/effect/turf_decal/tile/red, -/turf/open/floor/iron/textured, -/area/station/security/brig) -"bSo" = ( -/obj/structure/chair/wood{ - dir = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 - }, -/obj/structure/sign/poster/contraband/random/directional/south, -/obj/machinery/light/small/directional/south, -/turf/open/floor/eighties/red, -/area/station/security/prison/safe) "bSp" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/disposalpipe/segment{ @@ -7119,6 +7005,13 @@ }, /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/surface/outdoors/less_spawns) +"bSB" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/mapping_helpers/turn_off_lights_with_lightswitch, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/dark/textured, +/area/station/security/interrogation) "bSH" = ( /obj/effect/landmark/start/hangover, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -7281,13 +7174,6 @@ /obj/structure/sink/directional/south, /turf/open/floor/iron/dark, /area/station/science/robotics/lab) -"bVs" = ( -/obj/machinery/camera/directional/west{ - c_tag = "Security - Permabrig Observation Prep"; - network = list("ss13","prison") - }, -/turf/open/floor/vault, -/area/station/security/prison/rec) "bVv" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -7428,6 +7314,10 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/command/gateway) +"bXc" = ( +/obj/structure/sign/poster/official/nanotrasen_logo/directional/east, +/turf/open/floor/iron/dark, +/area/station/security/execution/education) "bXf" = ( /obj/structure/closet/emcloset, /turf/open/floor/plating, @@ -7456,15 +7346,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/starboard/upper) -"bXI" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 - }, -/obj/effect/turf_decal/tile/red/half/contrasted, -/turf/open/floor/iron/dark/textured_edge{ - dir = 1 - }, -/area/station/security/prison) "bYd" = ( /obj/machinery/airalarm/directional/west, /obj/machinery/light/small/directional/west, @@ -7528,16 +7409,6 @@ /obj/machinery/status_display/ai/directional/north, /turf/open/floor/wood/parquet, /area/station/service/bar/backroom) -"bYF" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/firealarm/directional/south, -/turf/open/floor/iron, -/area/station/security/processing) "bYK" = ( /obj/effect/landmark/start/chemist, /obj/structure/chair/office/light{ @@ -7649,11 +7520,6 @@ /obj/effect/turf_decal/tile/blue/fourcorners, /turf/open/floor/iron/dark/textured, /area/station/medical/treatment_center) -"bZK" = ( -/obj/structure/table, -/obj/effect/turf_decal/tile/red, -/turf/open/floor/iron, -/area/station/security/prison/mess) "bZQ" = ( /turf/closed/wall/r_wall, /area/station/hallway/primary/starboard) @@ -7792,6 +7658,10 @@ /obj/effect/turf_decal/tile/red/full, /turf/open/floor/iron/dark/textured_large, /area/station/security/brig/entrance) +"ccm" = ( +/obj/effect/turf_decal/tile/red/half/contrasted, +/turf/open/floor/iron/dark, +/area/station/security/mechbay) "ccp" = ( /obj/structure/bed, /obj/effect/spawner/random/bedsheet, @@ -7842,12 +7712,6 @@ /obj/structure/cable, /turf/open/floor/iron/dark, /area/station/ai/satellite/atmos) -"ccx" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "ccz" = ( /obj/item/radio/intercom/directional/east, /obj/machinery/atmospherics/pipe/smart/simple/orange/visible{ @@ -7884,6 +7748,13 @@ }, /turf/open/floor/wood/large, /area/station/commons/lounge) +"ccO" = ( +/obj/effect/turf_decal/loading_area/red, +/obj/effect/turf_decal/siding/dark{ + dir = 1 + }, +/turf/open/floor/iron/dark, +/area/mine/laborcamp/security) "ccQ" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -7933,12 +7804,6 @@ /obj/structure/lattice/catwalk, /turf/open/openspace/icemoon/keep_below, /area/icemoon/underground/explored) -"cdd" = ( -/obj/structure/chair/office{ - dir = 1 - }, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "cdg" = ( /obj/machinery/disposal/bin, /obj/structure/disposalpipe/trunk{ @@ -7956,12 +7821,6 @@ }, /turf/open/floor/iron/white, /area/station/science/xenobiology) -"cdp" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable, -/obj/structure/sign/warning/electric_shock/directional/north, -/turf/open/floor/iron, -/area/station/security/prison/workout) "cef" = ( /obj/machinery/biogenerator, /obj/effect/turf_decal/trimline/green/filled/line{ @@ -7999,24 +7858,17 @@ /obj/effect/turf_decal/trimline/blue/filled/corner, /turf/open/floor/iron/white, /area/station/medical/treatment_center) -"ceF" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 +"ceI" = ( +/obj/structure/railing{ + dir = 1 }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/structure/rack, +/obj/item/storage/medkit/brute, +/obj/structure/window/reinforced/spawner/directional/west, +/turf/open/floor/iron/dark/side{ + dir = 9 }, -/obj/machinery/light/small/directional/east, -/obj/machinery/conveyor{ - id = "mining_internal" - }, -/obj/machinery/bouldertech/refinery, -/obj/machinery/camera/directional/east{ - c_tag = "Mining Ore Smeltery"; - network = list("ss13", "mine") - }, -/turf/open/floor/iron, -/area/mine/production) +/area/station/security/prison/workout) "ceO" = ( /obj/machinery/button/crematorium{ id = "crematoriumChapel"; @@ -8322,16 +8174,6 @@ }, /turf/open/floor/iron, /area/station/commons/vacant_room/commissary) -"ciN" = ( -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 8 - }, -/obj/machinery/door/airlock/security/glass{ - name = "Labor Camp Shuttle Security Airlock" - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/mine/laborcamp) "ciS" = ( /obj/structure/table/wood, /obj/effect/spawner/random/trash/cigbutt, @@ -8342,6 +8184,18 @@ /obj/structure/sign/warning/cold_temp/directional/north, /turf/open/floor/plating, /area/station/maintenance/aft/lesser) +"ciW" = ( +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 8 + }, +/obj/structure/rack, +/obj/item/storage/briefcase/secure{ + pixel_y = 4 + }, +/obj/item/storage/toolbox/electrical, +/obj/item/radio/intercom/directional/west, +/turf/open/floor/iron, +/area/station/security/brig/upper) "cjJ" = ( /obj/effect/turf_decal/trimline/yellow/filled/warning{ dir = 8 @@ -8367,6 +8221,28 @@ /obj/machinery/light/small/dim/directional/north, /turf/open/floor/iron, /area/station/maintenance/starboard/fore) +"cjZ" = ( +/obj/machinery/airalarm/directional/west, +/obj/machinery/computer/security/labor, +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 9 + }, +/obj/machinery/button/door/directional/north{ + id = "labor"; + name = "Labor Camp Lockdown"; + req_access = list("brig"); + pixel_x = -6 + }, +/obj/machinery/button/door/directional/north{ + id = "labordoor"; + name = "Labour Camp Emergency Entrance"; + req_access = list("brig"); + pixel_x = 6 + }, +/turf/open/floor/iron/dark/side{ + dir = 9 + }, +/area/mine/laborcamp/security) "cke" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -8376,6 +8252,15 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/port) +"ckm" = ( +/obj/structure/table, +/obj/effect/decal/cleanable/dirt, +/obj/effect/spawner/random/food_or_drink/donkpockets, +/obj/structure/sign/poster/official/obey/directional/north, +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/mine/laborcamp) "cks" = ( /obj/item/wrench, /obj/effect/turf_decal/delivery, @@ -8383,6 +8268,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/engineering/supermatter/room) +"ckC" = ( +/obj/structure/window/reinforced/spawner/directional/north, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/dark/textured, +/area/station/security/prison/workout) "ckL" = ( /obj/structure/fence/corner{ dir = 2; @@ -8412,9 +8302,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible, /turf/open/floor/engine, /area/station/engineering/supermatter/room) -"clq" = ( -/turf/open/floor/iron/dark, -/area/station/security/processing) "clz" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/stripes/line{ @@ -8432,14 +8319,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/wood, /area/station/command/meeting_room) -"clR" = ( -/obj/structure/chair/sofa/corp/left{ - dir = 1 - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/carpet/blue, -/area/station/security/prison/work) "clT" = ( /obj/item/kirbyplants/random, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -8508,10 +8387,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/break_room) -"cmD" = ( -/obj/structure/window/reinforced/spawner/directional/east, -/turf/open/floor/iron/dark/textured, -/area/station/security/prison/workout) "cmJ" = ( /obj/item/radio/intercom/directional/north, /obj/machinery/atmospherics/pipe/smart/simple/general/visible{ @@ -8581,10 +8456,15 @@ }, /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/underground/explored) -"cno" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/smooth, -/area/station/security/lockers) +"cnk" = ( +/obj/structure/table, +/obj/machinery/cell_charger, +/obj/item/stock_parts/power_store/cell/potato{ + name = "\improper Beepsky's emergency battery" + }, +/obj/effect/decal/cleanable/cobweb/cobweb2, +/turf/open/floor/plating, +/area/station/maintenance/fore) "cnp" = ( /obj/structure/minecart_rail{ dir = 4 @@ -8633,10 +8513,6 @@ }, /turf/open/floor/iron, /area/station/commons/storage/mining) -"coc" = ( -/obj/machinery/camera/autoname/directional/north, -/turf/open/floor/iron/smooth, -/area/station/engineering/lobby) "cod" = ( /obj/effect/turf_decal/tile/yellow/half/contrasted{ dir = 1 @@ -8658,12 +8534,6 @@ }, /turf/open/floor/plastic, /area/station/commons/dorms/laundry) -"coY" = ( -/obj/machinery/airalarm/directional/south, -/obj/effect/turf_decal/delivery, -/obj/effect/decal/cleanable/rubble, -/turf/open/floor/iron, -/area/mine/production) "coZ" = ( /obj/machinery/camera/directional/south{ c_tag = "Locker Room West" @@ -8674,15 +8544,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/commons/locker) -"cpe" = ( -/obj/machinery/atmospherics/components/tank/air{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/plating, -/area/mine/laborcamp/security) "cpg" = ( /obj/effect/turf_decal/trimline/purple/filled/warning{ dir = 8 @@ -8703,11 +8564,6 @@ "cpm" = ( /turf/closed/wall/r_wall, /area/station/command/heads_quarters/hop) -"cpp" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, -/turf/open/floor/iron, -/area/station/security/prison/workout) "cpq" = ( /obj/machinery/light/small/directional/east, /turf/open/openspace, @@ -8745,13 +8601,6 @@ /obj/structure/railing, /turf/open/lava/plasma/ice_moon, /area/icemoon/underground/explored) -"cpG" = ( -/obj/structure/table, -/obj/item/toy/cards/deck, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/turf/open/floor/iron, -/area/mine/laborcamp) "cpH" = ( /obj/machinery/portable_atmospherics/canister/plasma, /obj/machinery/light/small/directional/west, @@ -8768,10 +8617,6 @@ "cpY" = ( /turf/closed/wall, /area/station/service/kitchen) -"cqa" = ( -/obj/item/radio/intercom/directional/north, -/turf/open/floor/iron/smooth, -/area/station/engineering/lobby) "cqb" = ( /obj/machinery/food_cart, /obj/structure/extinguisher_cabinet/directional/east, @@ -8810,17 +8655,6 @@ /obj/effect/spawner/random/maintenance, /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) -"cqx" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/firealarm/directional/south, -/turf/open/floor/iron/smooth, -/area/station/security/brig/upper) -"cqz" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "cqK" = ( /obj/item/stack/sheet/animalhide/carbon/lizard{ desc = "Landssslidessss, the landssslidesss..."; @@ -9038,6 +8872,16 @@ }, /turf/open/floor/iron, /area/station/service/kitchen/coldroom) +"ctW" = ( +/obj/item/food/grown/poppy{ + pixel_y = 2 + }, +/obj/item/storage/photo_album/prison, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/table/wood, +/turf/open/floor/iron/dark, +/area/station/security/prison/rec) "ctY" = ( /obj/structure/tank_holder/anesthetic, /turf/open/floor/iron/dark, @@ -9058,30 +8902,6 @@ }, /turf/open/floor/glass/reinforced/icemoon, /area/icemoon/surface/outdoors/nospawn) -"cur" = ( -/obj/effect/turf_decal/siding/wideplating/dark{ - dir = 8 - }, -/turf/open/floor/iron/dark/textured, -/area/station/security/prison/rec) -"cus" = ( -/obj/structure/table/glass, -/obj/item/stack/medical/wrap/gauze{ - pixel_x = 1 - }, -/obj/item/stack/medical/mesh, -/obj/effect/turf_decal/stripes/corner{ - dir = 8 - }, -/obj/machinery/button/door/directional/west{ - id = "chemistry_access_shutters"; - name = "Chemistry Access Shutter Control"; - req_access = list("medical") - }, -/obj/item/stack/medical/suture, -/obj/effect/turf_decal/tile/blue/full, -/turf/open/floor/iron/large, -/area/station/medical/treatment_center) "cut" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/light_switch/directional/west, @@ -9166,14 +8986,6 @@ /obj/structure/railing/corner, /turf/open/floor/iron, /area/station/service/kitchen/coldroom) -"cvq" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/obj/effect/turf_decal/tile/red/half/contrasted{ - dir = 8 - }, -/obj/machinery/light/small/directional/west, -/turf/open/floor/iron/dark/textured, -/area/station/security/prison) "cvr" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, @@ -9450,9 +9262,6 @@ }, /turf/open/floor/iron, /area/station/cargo/storage) -"czD" = ( -/turf/closed/wall, -/area/mine/laborcamp/security) "czM" = ( /obj/effect/decal/cleanable/dirt/dust, /obj/effect/turf_decal/tile/brown{ @@ -9479,12 +9288,6 @@ /obj/effect/spawner/random/trash/grille_or_waste, /turf/open/floor/plating, /area/station/maintenance/port/aft) -"cAi" = ( -/obj/effect/turf_decal/tile/purple/anticorner, -/turf/open/floor/iron/corner{ - dir = 1 - }, -/area/station/hallway/primary/starboard) "cAo" = ( /obj/machinery/airalarm/directional/west, /obj/structure/closet/toolcloset, @@ -9650,6 +9453,14 @@ "cBY" = ( /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/underground/unexplored/rivers/deep/shoreline) +"cCa" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/airalarm/directional/east, +/obj/machinery/light/directional/east, +/turf/open/floor/catwalk_floor/iron, +/area/mine/laborcamp) "cCb" = ( /obj/structure/flora/tree/pine/style_random, /turf/open/misc/asteroid/snow/icemoon, @@ -9665,14 +9476,6 @@ /obj/machinery/newscaster/directional/east, /turf/open/floor/iron/white/smooth_large, /area/station/science/genetics) -"cCG" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/button/flasher{ - id = "GulagCell 2"; - pixel_y = -30 - }, -/turf/open/floor/iron, -/area/mine/laborcamp) "cCP" = ( /obj/structure/closet/crate/miningcar, /obj/item/shovel, @@ -9713,10 +9516,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) -"cDt" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/smooth, -/area/station/engineering/lobby) "cDv" = ( /obj/item/stack/rods/fifty, /obj/structure/rack, @@ -9769,6 +9568,18 @@ /obj/machinery/power/energy_accumulator/tesla_coil/anchored, /turf/open/floor/engine, /area/station/engineering/supermatter) +"cDN" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Permabrig Visitation" + }, +/obj/machinery/door/firedoor, +/obj/structure/cable, +/obj/effect/mapping_helpers/airlock/access/any/security/brig, +/obj/effect/mapping_helpers/airlock/unres/delayed{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/security/prison/visit) "cDT" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/cable, @@ -9868,13 +9679,6 @@ }, /turf/open/floor/iron/dark/textured_edge, /area/station/security/evidence) -"cFb" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/obj/item/radio/intercom/directional/north, -/turf/open/floor/iron/smooth_edge, -/area/station/security/lockers) "cFp" = ( /obj/effect/turf_decal/tile/brown, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -10045,6 +9849,15 @@ }, /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/surface/outdoors/nospawn) +"cIn" = ( +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 10 + }, +/obj/machinery/firealarm/directional/west, +/turf/open/floor/iron/dark/side{ + dir = 10 + }, +/area/station/security/prison) "cIq" = ( /obj/machinery/computer/slot_machine{ balance = 15; @@ -10056,12 +9869,6 @@ /obj/item/coin/diamond, /turf/open/floor/plating, /area/station/maintenance/port/fore) -"cIK" = ( -/obj/structure/table/wood, -/obj/item/pai_card, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/wood, -/area/station/maintenance/fore) "cIP" = ( /obj/machinery/bookbinder, /obj/structure/sign/poster/official/random/directional/west, @@ -10074,20 +9881,6 @@ /obj/machinery/firealarm/directional/west, /turf/open/floor/iron/white, /area/station/medical/storage) -"cIY" = ( -/obj/machinery/door/airlock/security/glass{ - name = "Security EVA" - }, -/obj/effect/mapping_helpers/airlock/access/all/security/armory, -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/red_alert_access, -/turf/open/floor/iron/smooth, -/area/station/security/brig/upper) -"cJb" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/airalarm/directional/north, -/turf/open/floor/iron, -/area/mine/laborcamp) "cJd" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -10148,6 +9941,20 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/port/fore) +"cJO" = ( +/obj/structure/closet/crate/internals, +/obj/item/tank/internals/emergency_oxygen, +/obj/item/tank/internals/emergency_oxygen, +/obj/item/tank/internals/emergency_oxygen, +/obj/item/tank/internals/emergency_oxygen, +/obj/item/clothing/mask/breath, +/obj/item/clothing/mask/breath, +/obj/item/clothing/mask/breath, +/obj/item/clothing/mask/breath, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/bot, +/turf/open/floor/iron, +/area/mine/laborcamp) "cJX" = ( /obj/machinery/holopad, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -10191,13 +9998,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/hallway/primary/central) -"cKv" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, -/obj/effect/turf_decal/tile/red/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron/dark/side, -/area/station/security/processing) "cKy" = ( /obj/structure/window/reinforced/spawner/directional/west, /obj/effect/turf_decal/tile/blue/opposingcorners{ @@ -10243,12 +10043,6 @@ /obj/machinery/recharge_station, /turf/open/floor/iron, /area/station/science/robotics/mechbay) -"cLp" = ( -/obj/structure/table, -/obj/item/razor, -/obj/item/storage/backpack/duffelbag/sec/surgery, -/turf/open/floor/plating/icemoon, -/area/station/security/execution/education) "cLq" = ( /obj/effect/turf_decal/loading_area{ dir = 1 @@ -10259,6 +10053,18 @@ /obj/structure/cable, /turf/open/floor/iron/smooth_large, /area/station/cargo/warehouse) +"cLu" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, +/obj/machinery/camera/directional/east{ + c_tag = "Security - Interrogation"; + network = list("interrogation") + }, +/obj/machinery/light/small/directional/east, +/obj/structure/cable, +/turf/open/floor/iron/dark/textured, +/area/station/security/interrogation) "cLw" = ( /obj/structure/table/reinforced, /obj/machinery/door/firedoor, @@ -10283,23 +10089,6 @@ }, /turf/open/floor/iron, /area/station/engineering/lobby) -"cLB" = ( -/obj/machinery/computer/prisoner/gulag_teleporter_computer{ - dir = 4 - }, -/turf/open/floor/iron/showroomfloor, -/area/station/security/processing) -"cLD" = ( -/obj/machinery/door/airlock/security/glass{ - name = "Equipment Room" - }, -/obj/machinery/door/firedoor, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/obj/effect/mapping_helpers/airlock/access/all/security/brig, -/turf/open/floor/iron/dark/textured, -/area/station/security/lockers) "cLJ" = ( /obj/structure/table/wood, /obj/item/paper{ @@ -10413,6 +10202,17 @@ /obj/effect/spawner/structure/window/hollow/reinforced/middle, /turf/open/floor/plating, /area/station/maintenance/fore/lesser) +"cMY" = ( +/obj/effect/turf_decal/trimline/red/filled/line{ + 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/dark/side{ + dir = 8 + }, +/area/station/security/prison) "cNe" = ( /obj/structure/sign/warning/secure_area/directional/north, /turf/open/floor/plating, @@ -10583,14 +10383,6 @@ dir = 1 }, /area/station/security/prison/garden) -"cPQ" = ( -/obj/effect/turf_decal/stripes/white/line, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/security/prison/workout) "cPV" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -10706,12 +10498,24 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/science/ordnance/office) +"cRt" = ( +/obj/structure/sign/warning/directional/south, +/turf/open/lava/plasma/ice_moon, +/area/icemoon/underground/explored) "cRu" = ( /obj/structure/disposalpipe/junction, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/hallway/primary/central) +"cRx" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/security/prison/workout) "cRy" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable, @@ -10719,16 +10523,24 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/starboard/upper) +"cRB" = ( +/obj/structure/table/reinforced, +/obj/machinery/recharger, +/obj/machinery/light_switch/directional/south, +/obj/effect/turf_decal/tile/red/half/contrasted, +/obj/effect/mapping_helpers/turn_off_lights_with_lightswitch, +/obj/machinery/button/door/directional/south{ + name = "FIring Range Shutter Control"; + id = "firingrangeshuttersoutside"; + pixel_y = -36; + req_access = list("security") + }, +/turf/open/floor/iron/dark, +/area/station/security/range) "cRC" = ( /obj/structure/flora/bush/fullgrass/style_random, /turf/open/floor/grass, /area/station/service/hydroponics) -"cRE" = ( -/obj/structure/rack, -/obj/item/wirecutters, -/obj/structure/cable, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "cRF" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -10776,6 +10588,11 @@ initial_gas_mix = "ICEMOON_ATMOS" }, /area/icemoon/underground/explored) +"cSu" = ( +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/grille/broken, +/turf/open/floor/plating, +/area/station/maintenance/fore) "cSw" = ( /obj/structure/cable, /turf/open/floor/iron, @@ -10786,6 +10603,11 @@ }, /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/surface/outdoors/less_spawns) +"cSC" = ( +/obj/machinery/light/warm/directional/south, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/dark/textured, +/area/station/security/prison/workout) "cSE" = ( /obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -10813,12 +10635,6 @@ /obj/effect/mapping_helpers/airlock/access/all/engineering/engine_equipment, /turf/open/floor/iron, /area/station/engineering/storage) -"cTv" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/turf/open/floor/iron/dark/textured, -/area/station/security/prison/rec) "cTD" = ( /obj/effect/decal/cleanable/dirt/dust, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ @@ -10886,14 +10702,13 @@ dir = 1 }, /area/station/hallway/primary/port) -"cVD" = ( -/obj/machinery/door/poddoor/preopen{ - id = "labor"; - name = "Labor Camp Blast Door" +"cVR" = ( +/obj/structure/toilet/greyscale, +/obj/structure/cable, +/turf/open/floor/iron/smooth_half{ + dir = 1 }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/mine/laborcamp) +/area/station/security/prison/safe) "cVV" = ( /obj/machinery/newscaster/directional/north, /obj/structure/railing{ @@ -10920,29 +10735,13 @@ }, /turf/open/floor/iron, /area/station/security/prison/garden) +"cWw" = ( +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/surface/outdoors/labor_camp) "cWE" = ( /obj/effect/spawner/structure/window/reinforced/tinted, /turf/open/floor/plating, /area/station/service/chapel/office) -"cWG" = ( -/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/security/processing) -"cWH" = ( -/obj/effect/decal/cleanable/dirt, -/obj/item/kirbyplants/organic/plant5, -/obj/machinery/camera/directional/west{ - c_tag = "Labor Camp Cellblock"; - network = list("labor") - }, -/obj/machinery/button/flasher{ - id = "GulagCell 1"; - pixel_y = -30 - }, -/turf/open/floor/iron, -/area/mine/laborcamp) "cWX" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -11075,11 +10874,6 @@ }, /turf/open/floor/iron/dark, /area/station/engineering/supermatter/room) -"cYv" = ( -/obj/structure/window/reinforced/spawner/directional/north, -/obj/structure/window/reinforced/spawner/directional/east, -/turf/open/floor/iron/dark/textured, -/area/station/security/prison/workout) "cYC" = ( /obj/machinery/atmospherics/pipe/smart/simple/green/visible, /obj/effect/turf_decal/tile/blue/anticorner/contrasted{ @@ -11096,6 +10890,20 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/starboard) +"cYF" = ( +/obj/effect/spawner/random/structure/crate_abandoned, +/turf/open/floor/plating, +/area/station/maintenance/department/security) +"cYJ" = ( +/obj/structure/closet/l3closet/janitor, +/obj/machinery/airalarm/directional/north, +/obj/effect/turf_decal/tile/purple{ + dir = 1 + }, +/obj/item/restraints/legcuffs/beartrap, +/obj/item/restraints/legcuffs/beartrap, +/turf/open/floor/iron, +/area/station/service/janitor) "cYK" = ( /obj/machinery/netpod, /obj/machinery/light/small/directional/south, @@ -11168,15 +10976,6 @@ /obj/machinery/light/small/dim/directional/east, /turf/open/floor/iron/dark, /area/station/medical/morgue) -"cZm" = ( -/obj/machinery/door/firedoor/border_only{ - dir = 8 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/security/brig/upper) "cZt" = ( /obj/effect/turf_decal/tile/green/half/contrasted{ dir = 4 @@ -11272,6 +11071,9 @@ }, /turf/open/floor/wood, /area/station/service/library) +"dan" = ( +/turf/open/openspace, +/area/station/security/brig) "daq" = ( /obj/machinery/computer/crew{ dir = 8 @@ -11331,6 +11133,13 @@ /obj/item/cultivator, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) +"dbh" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "mining_internal" + }, +/turf/open/floor/iron, +/area/mine/production) "dbm" = ( /obj/machinery/door/airlock{ name = "Private Restroom" @@ -11365,10 +11174,6 @@ "dbH" = ( /turf/closed/wall/r_wall, /area/station/security/prison/mess) -"dbL" = ( -/obj/effect/spawner/random/structure/grille, -/turf/open/floor/plating, -/area/station/security/prison/safe) "dbO" = ( /obj/machinery/door/airlock/wood{ name = "Backstage" @@ -11456,6 +11261,12 @@ }, /turf/open/floor/iron, /area/station/engineering/lobby) +"dcD" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/machinery/vending/cigarette, +/turf/open/floor/iron, +/area/station/security/prison/visit) "dcE" = ( /obj/machinery/atmospherics/pipe/smart/simple/violet/visible{ dir = 1 @@ -11497,25 +11308,6 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/port/lesser) -"dcX" = ( -/obj/structure/rack, -/obj/item/clothing/suit/hooded/wintercoat/security{ - pixel_x = -3; - pixel_y = 7 - }, -/obj/item/clothing/suit/hooded/wintercoat/security{ - pixel_x = -8 - }, -/obj/item/clothing/shoes/winterboots/ice_boots{ - pixel_x = 6; - pixel_y = 8 - }, -/obj/item/clothing/shoes/winterboots/ice_boots{ - pixel_x = 5 - }, -/obj/structure/cable, -/turf/open/floor/iron/smooth, -/area/station/security/brig/upper) "ddd" = ( /obj/effect/turf_decal/tile/blue, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -11593,16 +11385,15 @@ }, /turf/open/floor/plating, /area/station/maintenance/aft/greater) -"ddK" = ( -/obj/machinery/hydroponics/constructable, +"ddC" = ( +/obj/effect/gibspawner/human, +/obj/structure/sign/warning/directional/east, +/turf/open/misc/asteroid/snow/icemoon, +/area/icemoon/surface/outdoors/nospawn) +"ddD" = ( /obj/effect/decal/cleanable/dirt, -/obj/item/seeds/onion, -/obj/effect/turf_decal/tile/green/anticorner/contrasted, -/obj/effect/turf_decal/siding/green{ - dir = 4 - }, -/turf/open/floor/iron/dark, -/area/mine/laborcamp) +/turf/open/floor/iron, +/area/mine/production) "ddQ" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/item/kirbyplants/random, @@ -11697,6 +11488,19 @@ }, /turf/open/floor/glass/reinforced, /area/station/science/xenobiology) +"dfl" = ( +/obj/structure/chair/sofa/bench/right{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 4 + }, +/turf/open/floor/iron/smooth, +/area/station/security/brig/upper) +"dfn" = ( +/obj/machinery/firealarm/directional/east, +/turf/open/floor/iron/dark/textured, +/area/station/security/office) "dfq" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible, /turf/closed/wall/r_wall, @@ -11710,13 +11514,6 @@ }, /turf/open/floor/iron/dark, /area/station/security/checkpoint/science) -"dfz" = ( -/obj/structure/closet/secure_closet/security/sec, -/obj/structure/cable, -/turf/open/floor/iron/smooth_edge{ - dir = 1 - }, -/area/station/security/lockers) "dfB" = ( /turf/open/floor/iron/white/corner, /area/station/hallway/primary/starboard) @@ -11770,11 +11567,6 @@ /obj/effect/turf_decal/tile/green/full, /turf/open/floor/iron/white/smooth_large, /area/station/medical/virology) -"dgx" = ( -/obj/structure/rack, -/obj/effect/spawner/random/contraband/permabrig_gear, -/turf/open/floor/vault, -/area/station/security/prison/rec) "dgA" = ( /obj/item/kirbyplants/random, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -11867,13 +11659,6 @@ /obj/machinery/door/firedoor, /turf/open/floor/iron/showroomfloor, /area/station/security/prison/toilet) -"dhU" = ( -/obj/machinery/airalarm/directional/north, -/obj/effect/turf_decal/tile/red/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron/dark/side, -/area/station/security/processing) "dhV" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/chair{ @@ -11947,9 +11732,6 @@ /obj/machinery/light/small/dim/directional/south, /turf/open/floor/plating, /area/station/maintenance/port/fore) -"diC" = ( -/turf/open/floor/iron/dark/textured, -/area/station/security/armory/upper) "diI" = ( /obj/machinery/mech_bay_recharge_port, /obj/item/radio/intercom/directional/south, @@ -12112,6 +11894,26 @@ /obj/structure/sign/nanotrasen/directional/east, /turf/open/openspace/icemoon/keep_below, /area/icemoon/underground/explored) +"dkM" = ( +/obj/structure/table/glass, +/obj/item/stack/medical/wrap/gauze{ + pixel_x = -2; + pixel_y = 8 + }, +/obj/item/stack/medical/mesh{ + pixel_x = 6; + pixel_y = 5 + }, +/obj/item/stack/medical/suture, +/obj/item/reagent_containers/cup/bottle/epinephrine, +/obj/item/reagent_containers/cup/bottle/multiver{ + pixel_x = 6 + }, +/obj/item/reagent_containers/syringe, +/obj/machinery/defibrillator_mount/directional/east, +/obj/effect/turf_decal/tile/blue/full, +/turf/open/floor/iron/large, +/area/station/medical/treatment_center) "dkT" = ( /obj/effect/spawner/structure/window/hollow/reinforced/middle{ dir = 1 @@ -12139,15 +11941,6 @@ /obj/effect/landmark/start/cook, /turf/open/floor/iron/kitchen/diagonal, /area/station/service/kitchen) -"dlq" = ( -/obj/machinery/camera/directional/south{ - c_tag = "Labor Camp Security Office"; - network = list("labor") - }, -/obj/effect/turf_decal/tile/red/half/contrasted, -/obj/machinery/light/directional/south, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "dlt" = ( /obj/effect/turf_decal/weather/snow/corner{ dir = 8 @@ -12266,6 +12059,19 @@ "dnq" = ( /turf/open/floor/iron, /area/station/hallway/primary/central) +"dnr" = ( +/obj/structure/window/reinforced/spawner/directional/north, +/obj/structure/window/reinforced/spawner/directional/west, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/dark/textured, +/area/station/security/prison/workout) +"dns" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/machinery/light/floor, +/turf/open/floor/iron/smooth, +/area/station/security/brig/upper) "dnz" = ( /obj/effect/turf_decal/siding/wideplating_new/light{ dir = 6 @@ -12451,6 +12257,10 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/secondary/entry) +"dqc" = ( +/obj/structure/sign/warning/firing_range/directional/east, +/turf/open/misc/asteroid/snow/icemoon, +/area/icemoon/surface/outdoors/nospawn) "dqw" = ( /obj/machinery/holopad, /turf/open/floor/iron, @@ -12601,13 +12411,6 @@ }, /turf/open/floor/engine, /area/station/maintenance/disposal/incinerator) -"drP" = ( -/obj/structure/toilet{ - dir = 8 - }, -/obj/machinery/light/small/directional/north, -/turf/open/floor/plating, -/area/mine/laborcamp/security) "drR" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/cable, @@ -12710,17 +12513,28 @@ /obj/structure/sign/poster/contraband/random/directional/south, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) -"dtz" = ( -/obj/item/kirbyplants/random, -/obj/machinery/light/small/directional/east, -/turf/open/floor/iron/dark/textured, -/area/station/security/processing) "dtC" = ( /obj/effect/turf_decal/tile/neutral{ dir = 1 }, /turf/open/floor/iron/dark, /area/station/service/chapel) +"dtI" = ( +/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, +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/open/floor/plating, +/area/station/maintenance/fore) +"dtN" = ( +/obj/structure/curtain, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/smooth, +/area/station/security/holding_cell) "dtP" = ( /obj/effect/turf_decal/weather/snow/corner{ dir = 9 @@ -12747,15 +12561,6 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/iron/dark, /area/station/science/ordnance/office) -"duS" = ( -/obj/machinery/door/airlock{ - name = "Labor Camp Library" - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/mine/laborcamp) "duT" = ( /obj/item/chair/stool/bar{ pixel_y = -2 @@ -12920,6 +12725,15 @@ /obj/effect/spawner/random/clothing/kittyears_or_rabbitears, /turf/open/floor/plastic, /area/station/commons/dorms/laundry) +"dwR" = ( +/obj/effect/turf_decal/stripes/red/line{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/iron, +/area/mine/laborcamp/security) "dwY" = ( /obj/machinery/light_switch/directional/west, /obj/structure/closet/secure_closet/quartermaster, @@ -13031,6 +12845,13 @@ /obj/item/kirbyplants/random, /turf/open/floor/iron/white, /area/station/medical/cryo) +"dxS" = ( +/obj/machinery/conveyor{ + dir = 10; + id = "mining_internal" + }, +/turf/open/floor/iron, +/area/mine/production) "dyf" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -13434,12 +13255,6 @@ }, /turf/open/floor/plating/snowed/coldroom, /area/station/service/kitchen/coldroom) -"dEz" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/carpet, -/area/station/security/prison/rec) "dEI" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -13536,21 +13351,6 @@ /obj/structure/sign/departments/evac/directional/north, /turf/open/floor/iron, /area/station/hallway/primary/starboard) -"dFR" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 - }, -/obj/structure/cable, -/obj/machinery/power/apc/auto_name/directional/south, -/obj/effect/turf_decal/tile/blue/opposingcorners{ - dir = 1 - }, -/obj/effect/turf_decal/siding/white{ - dir = 8 - }, -/turf/open/floor/iron/cafeteria, -/area/mine/laborcamp) "dFW" = ( /turf/open/floor/iron/white/side, /area/station/science/research) @@ -13623,15 +13423,6 @@ /obj/effect/mapping_helpers/airlock/access/all/command/captain, /turf/open/floor/plating, /area/station/maintenance/central/lesser) -"dHb" = ( -/obj/structure/flora/grass/jungle/b/style_random, -/obj/structure/window/reinforced/spawner/directional/west, -/obj/structure/window/reinforced/spawner/directional/south, -/obj/item/throwing_star/toy, -/turf/open/misc/ashplanet/wateryrock{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, -/area/station/security/prison/rec) "dHf" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 4 @@ -13692,15 +13483,47 @@ }, /turf/open/floor/iron/dark/textured_edge, /area/station/security/prison) +"dHD" = ( +/obj/structure/table, +/obj/item/storage/box/chemimp{ + pixel_x = 6 + }, +/obj/item/storage/box/trackimp{ + pixel_x = -3 + }, +/obj/item/storage/lockbox/loyalty, +/obj/machinery/light_switch/directional/east, +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 1 + }, +/turf/open/floor/iron/dark/textured, +/area/station/security/armory/upper) "dHF" = ( /obj/structure/flora/grass/green/style_random, /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/surface/outdoors/less_spawns) +"dHG" = ( +/obj/machinery/conveyor{ + id = "gulag"; + dir = 6 + }, +/obj/machinery/light/small/directional/north, +/obj/structure/sign/warning/directional/north, +/turf/open/floor/iron, +/area/mine/laborcamp) "dHJ" = ( /obj/structure/cable/multilayer/multiz, /obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/station/maintenance/department/chapel) +"dId" = ( +/obj/machinery/camera/directional/north{ + c_tag = "Security - Upper Permabrig Cafeteria"; + network = list("ss13","prison") + }, +/obj/machinery/light/warm/directional/north, +/turf/open/floor/iron/dark/textured, +/area/station/security/prison) "dIl" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible{ dir = 4 @@ -13824,19 +13647,6 @@ /obj/effect/landmark/start/cargo_technician, /turf/open/floor/iron, /area/station/cargo/sorting) -"dKP" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/firealarm/directional/south, -/obj/effect/turf_decal/tile/red/half/contrasted, -/turf/open/floor/iron/dark/side{ - dir = 1 - }, -/area/station/security/processing) "dKW" = ( /obj/structure/sign/directions/evac{ dir = 4; @@ -13856,6 +13666,12 @@ "dLf" = ( /turf/closed/wall/r_wall, /area/station/cargo/storage) +"dLj" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/vault, +/area/station/security/prison/rec) "dLo" = ( /obj/structure/disposalpipe/segment, /obj/machinery/status_display/evac/directional/east, @@ -13885,10 +13701,6 @@ /obj/structure/sign/warning/secure_area/directional/north, /turf/open/floor/plating, /area/station/ai/satellite/maintenance) -"dLN" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/mine/laborcamp) "dLQ" = ( /obj/machinery/door/firedoor, /obj/structure/cable, @@ -13901,12 +13713,6 @@ }, /turf/open/floor/iron/dark/textured, /area/station/hallway/primary/central) -"dLR" = ( -/obj/structure/table, -/obj/effect/decal/cleanable/dirt, -/obj/effect/spawner/random/food_or_drink/donkpockets, -/turf/open/floor/iron, -/area/mine/laborcamp) "dLT" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 1 @@ -13981,15 +13787,6 @@ }, /turf/open/floor/iron, /area/station/command/bridge) -"dNt" = ( -/obj/structure/disposalpipe/segment{ - dir = 5 - }, -/obj/effect/turf_decal/tile/red/anticorner/contrasted{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/security/brig/upper) "dNw" = ( /obj/structure/chair/office{ dir = 8 @@ -14012,26 +13809,39 @@ }, /turf/open/floor/iron, /area/station/maintenance/port/aft) +"dNE" = ( +/obj/machinery/conveyor{ + id = "mining_internal" + }, +/obj/machinery/bouldertech/refinery/smelter{ + dir = 1 + }, +/obj/structure/railing/corner/end/flip{ + dir = 4 + }, +/turf/open/floor/iron, +/area/mine/production) "dNG" = ( /obj/structure/disposalpipe/segment, /obj/structure/reagent_dispensers/watertank, /turf/open/floor/iron/dark, /area/station/engineering/storage) -"dNH" = ( +"dNI" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/camera/directional/west{ - c_tag = "Security - Permabrig Cold Room"; - network = list("ss13","prison") - }, -/obj/machinery/firealarm/directional/west, -/turf/open/floor/iron/showroomfloor, -/area/station/security/prison/mess) +/turf/open/floor/catwalk_floor/iron, +/area/mine/laborcamp) "dNN" = ( /obj/effect/turf_decal/weather/snow/corner{ dir = 6 }, /turf/open/floor/plating/snowed/icemoon, /area/icemoon/underground/explored) +"dNT" = ( +/obj/structure/sign/warning/directional/west, +/turf/open/misc/asteroid/snow/icemoon, +/area/icemoon/surface/outdoors/nospawn) "dNX" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 1 @@ -14202,14 +14012,6 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/iron, /area/station/science/xenobiology) -"dRk" = ( -/obj/effect/turf_decal/bot, -/obj/structure/ore_box, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/mine/laborcamp) "dRx" = ( /obj/effect/turf_decal/tile/brown, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -14271,12 +14073,6 @@ /obj/machinery/firealarm/directional/west, /turf/open/floor/iron, /area/mine/production) -"dSm" = ( -/obj/effect/turf_decal/trimline/red/filled/line{ - dir = 1 - }, -/turf/open/floor/iron/white, -/area/station/security/prison/safe) "dSJ" = ( /obj/machinery/flasher/directional/north{ id = "visitorflash" @@ -14309,6 +14105,12 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/service/bar) +"dTg" = ( +/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/security/prison/visit) "dTh" = ( /obj/machinery/airalarm/directional/west, /obj/effect/decal/cleanable/dirt/dust, @@ -14354,19 +14156,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron, /area/station/commons/storage/primary) -"dTF" = ( -/obj/machinery/conveyor{ - dir = 10; - id = "mining_internal" - }, -/obj/effect/turf_decal/stripes/corner{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/turf/open/floor/iron, -/area/mine/production) "dTI" = ( /obj/structure/sign/warning/docking/directional/north, /turf/open/misc/asteroid/snow/icemoon, @@ -14434,14 +14223,6 @@ /obj/item/clothing/glasses/meson/engine/tray, /turf/open/floor/iron/showroomfloor, /area/station/engineering/atmos) -"dUG" = ( -/obj/machinery/door/airlock/public/glass{ - name = "Showers" - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/freezer, -/area/mine/laborcamp) "dUL" = ( /obj/machinery/door/poddoor/preopen{ id = "maint1" @@ -14466,10 +14247,6 @@ /obj/structure/sign/poster/random/directional/north, /turf/open/floor/plating, /area/station/medical/virology) -"dUW" = ( -/obj/machinery/light_switch/directional/south, -/turf/open/floor/wood, -/area/station/security/courtroom) "dVb" = ( /obj/structure/table, /obj/item/toy/cards/deck, @@ -14511,15 +14288,6 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron/dark, /area/station/hallway/secondary/entry) -"dWn" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/obj/machinery/camera/directional/north{ - c_tag = "Security - Upper Permabrig Cafeteria"; - network = list("ss13","prison") - }, -/obj/structure/sign/poster/official/random/directional/north, -/turf/open/floor/iron/dark/textured, -/area/station/security/prison) "dWI" = ( /obj/effect/turf_decal/siding/wood{ dir = 4 @@ -14692,6 +14460,17 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos/storage) +"dYO" = ( +/obj/machinery/door/airlock/security/glass{ + name = "N2O Storage" + }, +/obj/effect/mapping_helpers/airlock/access/all/security/armory, +/obj/effect/mapping_helpers/airlock/unres/delayed{ + dir = 8 + }, +/obj/effect/mapping_helpers/airlock/locked, +/turf/open/floor/plating, +/area/station/maintenance/fore) "dYP" = ( /obj/item/toy/snowball{ pixel_x = -11; @@ -14714,6 +14493,14 @@ /obj/machinery/firealarm/directional/south, /turf/open/floor/iron, /area/station/hallway/primary/starboard) +"dYY" = ( +/obj/structure/table/reinforced, +/obj/structure/cable, +/obj/machinery/power/apc/auto_name/directional/south, +/obj/effect/spawner/random/engineering/toolbox, +/obj/machinery/light/small/directional/south, +/turf/open/floor/iron, +/area/station/security/mechbay) "dZc" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/checker, @@ -14730,6 +14517,17 @@ dir = 8 }, /area/mine/eva) +"dZz" = ( +/obj/effect/turf_decal/tile/red/half/contrasted, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/security/brig/upper) +"dZL" = ( +/obj/structure/cable, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/tile/red/half/contrasted, +/turf/open/floor/iron, +/area/station/security/brig/upper) "dZN" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 4 @@ -14883,6 +14681,17 @@ initial_gas_mix = "ICEMOON_ATMOS" }, /area/icemoon/underground/explored) +"ebF" = ( +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 6 + }, +/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/side{ + dir = 6 + }, +/area/station/security/prison/safe) "ebH" = ( /obj/structure/sign/departments/medbay/alt/directional/east, /turf/open/floor/iron, @@ -14915,6 +14724,12 @@ }, /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/surface/outdoors/nospawn) +"ecp" = ( +/obj/structure/cable, +/obj/effect/spawner/structure/window/hollow/reinforced/middle, +/obj/machinery/door/firedoor, +/turf/open/floor/plating, +/area/station/security/prison/mess) "ecs" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -14938,6 +14753,10 @@ /obj/effect/mapping_helpers/airlock/access/all/science/genetics, /turf/open/floor/iron, /area/station/science/genetics) +"ecI" = ( +/obj/machinery/light/cold/dim/directional/west, +/turf/open/floor/iron/kitchen_coldroom/freezerfloor, +/area/station/security/prison/mess) "ecU" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -15052,6 +14871,11 @@ /obj/effect/decal/cleanable/blood/old, /turf/open/floor/plating, /area/station/maintenance/port/fore) +"eeP" = ( +/obj/structure/cable, +/obj/machinery/light/small/directional/west, +/turf/open/floor/wood, +/area/station/maintenance/fore) "eeR" = ( /obj/structure/stairs/south{ dir = 2 @@ -15084,15 +14908,6 @@ }, /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/surface/outdoors/nospawn) -"efx" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable, -/obj/effect/turf_decal/stripes/red/line, -/obj/effect/turf_decal/trimline/red/corner{ - dir = 1 - }, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) "efy" = ( /obj/structure/railing{ dir = 1 @@ -15172,23 +14987,10 @@ /obj/effect/spawner/random/armory/riot_shield, /turf/open/floor/iron/dark/textured, /area/station/security/armory) -"egm" = ( -/obj/structure/table, -/obj/item/restraints/handcuffs, -/obj/item/assembly/timer, -/turf/open/floor/iron/dark/textured_half{ - dir = 1 - }, -/area/station/security/office) "egp" = ( /obj/structure/reagent_dispensers/fueltank, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) -"egz" = ( -/obj/structure/table/wood, -/obj/item/radio/intercom/prison, -/turf/open/floor/wood, -/area/station/security/prison/rec) "egF" = ( /obj/structure/filingcabinet, /obj/item/folder/documents, @@ -15320,14 +15122,6 @@ /obj/effect/turf_decal/tile/blue/half/contrasted, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) -"ehZ" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/table/wood, -/obj/effect/spawner/random/entertainment/toy_figure, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/wood, -/area/station/security/prison/rec) "eia" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/cable, @@ -15342,28 +15136,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/dark/textured, /area/station/security/execution/transfer) -"eig" = ( -/obj/structure/rack, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/blood/old, -/obj/item/restraints/handcuffs{ - pixel_y = 5 - }, -/obj/item/restraints/handcuffs{ - pixel_y = 1 - }, -/obj/item/restraints/handcuffs{ - pixel_x = 1; - pixel_y = -4 - }, -/obj/machinery/airalarm/directional/east, -/obj/machinery/camera/directional/south{ - c_tag = "Security - Holding Cells" - }, -/obj/structure/cable, -/obj/machinery/power/apc/auto_name/directional/south, -/turf/open/floor/iron/smooth, -/area/station/security/holding_cell) "eik" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 9 @@ -15409,14 +15181,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/hallway/secondary/exit/departure_lounge) -"ejb" = ( -/obj/structure/cable, -/obj/machinery/door/airlock/security/glass{ - name = "Permabrig Visitation" - }, -/obj/effect/mapping_helpers/airlock/access/any/security/brig, -/turf/open/floor/iron, -/area/station/security/prison/visit) "ejc" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 1 @@ -15451,6 +15215,16 @@ }, /turf/open/floor/iron/dark, /area/station/commons/storage/primary) +"ejJ" = ( +/obj/machinery/door/airlock/maintenance{ + name = "Permabrig Maintenance" + }, +/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/security/brig, +/turf/open/floor/plating, +/area/station/maintenance/department/security) "ejL" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 9 @@ -15481,9 +15255,6 @@ /obj/machinery/status_display/ai/directional/north, /turf/open/floor/carpet/royalblue, /area/station/command/heads_quarters/captain) -"ejX" = ( -/turf/open/floor/plating, -/area/station/security/prison/safe) "ekh" = ( /obj/machinery/camera/directional/west{ c_tag = "Atmospherics - Central" @@ -15493,11 +15264,6 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos) -"eki" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) "ekj" = ( /obj/structure/closet, /obj/effect/spawner/random/clothing/costume, @@ -15552,13 +15318,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/commons/fitness) -"ekW" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/landmark/event_spawn, -/turf/open/floor/iron, -/area/station/security/processing) "elj" = ( /obj/effect/landmark/start/depsec/engineering, /obj/structure/cable, @@ -15652,14 +15411,6 @@ }, /turf/open/lava/plasma/ice_moon, /area/icemoon/underground/explored) -"eni" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/red/line, -/obj/effect/turf_decal/trimline/red/line{ - dir = 1 - }, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) "enq" = ( /obj/machinery/doppler_array{ dir = 4 @@ -15875,16 +15626,6 @@ /obj/structure/sign/poster/official/random/directional/north, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) -"eqS" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/trimline/red/warning{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/red/line{ - dir = 1 - }, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) "eqU" = ( /obj/machinery/firealarm/directional/south, /obj/structure/cable, @@ -16011,11 +15752,12 @@ }, /turf/open/floor/plating/icemoon, /area/station/science/ordnance/bomb/planet) -"erY" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/carpet/blue, -/area/station/security/prison/work) +"erU" = ( +/obj/machinery/vending/security, +/obj/item/radio/intercom/directional/north, +/obj/effect/turf_decal/bot/right, +/turf/open/floor/iron/smooth_edge, +/area/station/security/lockers) "erZ" = ( /obj/machinery/power/apc/auto_name/directional/west, /obj/structure/cable, @@ -16028,6 +15770,18 @@ }, /turf/open/floor/iron/dark, /area/station/cargo/miningdock) +"esm" = ( +/obj/machinery/light/small/directional/south, +/obj/structure/closet/secure_closet/brig{ + id = "Cell 2"; + name = "Cell 2 locker" + }, +/obj/structure/cable, +/obj/machinery/flasher/directional/south{ + id = "Cell 2" + }, +/turf/open/floor/iron/smooth, +/area/station/security/brig) "eso" = ( /obj/machinery/telecomms/receiver/preset_left, /turf/open/floor/iron/dark/telecomms, @@ -16071,12 +15825,6 @@ /obj/structure/window/reinforced/spawner/directional/east, /turf/open/floor/glass/reinforced, /area/station/security/brig/entrance) -"esS" = ( -/obj/machinery/computer/shuttle/labor{ - dir = 8 - }, -/turf/open/floor/iron/showroomfloor, -/area/station/security/processing) "eta" = ( /obj/machinery/camera/directional/west{ c_tag = "Central Hallway East" @@ -16116,12 +15864,6 @@ /obj/structure/window/reinforced/spawner/directional/west, /turf/open/floor/iron/white/smooth_large, /area/station/medical/pharmacy) -"etw" = ( -/obj/effect/turf_decal/stripes/white/line, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/airalarm/directional/west, -/turf/open/floor/iron, -/area/station/security/prison/workout) "etz" = ( /obj/structure/sign/warning/directional/north, /turf/open/lava/plasma/ice_moon, @@ -16255,37 +15997,21 @@ }, /turf/open/floor/iron/white, /area/station/medical/treatment_center) -"evv" = ( -/obj/structure/table/glass, -/obj/item/book/manual/wiki/infections{ - pixel_y = 7 - }, -/obj/item/reagent_containers/syringe/antiviral, -/obj/effect/turf_decal/trimline/green/filled/line, -/obj/structure/reagent_dispensers/wall/virusfood/directional/south, -/obj/item/tgui_book/manual/idc{ - pixel_y = 3; - pixel_x = 3 - }, -/obj/item/reagent_containers/spray/cleaner, -/obj/item/reagent_containers/dropper, -/turf/open/floor/iron/white, -/area/station/medical/virology) -"evw" = ( -/obj/structure/window/reinforced/spawner/directional/north{ - pixel_y = 2 - }, -/obj/structure/closet/emcloset, -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/security/processing) -"evP" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ +"ewf" = ( +/obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/structure/sign/warning/cold_temp/directional/north, -/turf/open/floor/vault, -/area/station/security/prison/rec) +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/tile/purple/half/contrasted{ + dir = 4 + }, +/turf/open/floor/iron/white/side{ + dir = 4 + }, +/area/station/science/genetics) "ewi" = ( /obj/machinery/navbeacon{ codes_txt = "delivery;dir=8"; @@ -16315,16 +16041,6 @@ }, /turf/open/floor/iron/dark, /area/station/cargo/miningdock) -"ewM" = ( -/obj/structure/disposalpipe/segment{ - dir = 9 - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/light/floor, -/turf/open/floor/iron, -/area/station/security/brig/upper) "ewP" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/carpet/royalblue, @@ -16403,9 +16119,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/dark/visible, /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) -"eyb" = ( -/turf/closed/wall, -/area/station/security/processing) "eyc" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 4 @@ -16455,11 +16168,6 @@ /obj/structure/closet/firecloset, /turf/open/floor/iron/dark, /area/station/hallway/secondary/entry) -"eym" = ( -/obj/structure/girder, -/obj/effect/spawner/random/structure/grille, -/turf/open/floor/plating, -/area/station/maintenance/fore) "eyv" = ( /obj/effect/turf_decal/stripes/line{ dir = 10 @@ -16572,6 +16280,12 @@ /obj/structure/flora/grass/green/style_2, /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/surface/outdoors/nospawn) +"eAv" = ( +/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/security/prison/mess) "eAw" = ( /obj/structure/cable/multilayer/multiz, /turf/open/floor/plating/snowed/icemoon, @@ -16648,12 +16362,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/visible, /turf/closed/wall/r_wall, /area/station/security/checkpoint/engineering) -"eCg" = ( -/obj/structure/tank_holder/oxygen, -/obj/effect/decal/cleanable/wrapping, -/obj/structure/sign/poster/official/safety_internals/directional/north, -/turf/open/floor/vault, -/area/station/security/prison/rec) "eCn" = ( /obj/structure/disposalpipe/trunk/multiz{ dir = 1 @@ -16800,6 +16508,18 @@ }, /turf/open/floor/plating/snowed/icemoon, /area/icemoon/surface/outdoors/less_spawns) +"eDL" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Escape Pod Access" + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/access/all/security/general, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/iron/smooth, +/area/station/security/brig/upper) "eDM" = ( /obj/machinery/door/airlock/command/glass{ name = "Head of Security" @@ -16874,16 +16594,6 @@ /obj/structure/chair/stool/directional/north, /turf/open/floor/carpet, /area/station/commons/dorms) -"eFu" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 1 - }, -/obj/structure/sign/warning/gas_mask/directional/north, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/mine/laborcamp) "eFG" = ( /obj/structure/disposalpipe/trunk{ dir = 8 @@ -17049,6 +16759,12 @@ /obj/machinery/shower/directional/north, /turf/open/floor/iron/smooth, /area/mine/eva) +"eHv" = ( +/obj/effect/turf_decal/stripes/red/line{ + dir = 8 + }, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/surface/outdoors/nospawn) "eHC" = ( /obj/structure/marker_beacon/burgundy, /obj/effect/turf_decal/weather/snow/corner{ @@ -17101,13 +16817,6 @@ }, /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/underground/explored) -"eIg" = ( -/obj/effect/turf_decal/tile/red/anticorner/contrasted{ - dir = 1 - }, -/obj/structure/sign/poster/official/here_for_your_safety/directional/west, -/turf/open/floor/iron, -/area/station/security/prison/visit) "eIk" = ( /obj/structure/filingcabinet, /obj/machinery/power/apc/auto_name/directional/north, @@ -17292,6 +17001,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/smooth_large, /area/station/science/cytology) +"eLB" = ( +/obj/machinery/camera/directional/east{ + c_tag = "Service - Gambling Lounge" + }, +/obj/effect/spawner/random/entertainment/slot_machine{ + name = "two-armed bandit" + }, +/turf/open/floor/wood/large, +/area/station/commons/lounge) "eLN" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/visible/layer4, /obj/machinery/meter/layer4, @@ -17336,16 +17054,6 @@ }, /turf/open/floor/wood/parquet, /area/station/service/bar/atrium) -"eMG" = ( -/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/red{ - dir = 1 - }, -/obj/machinery/digital_clock/directional/north, -/turf/open/floor/iron, -/area/station/security/prison/mess) "eMH" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/landmark/start/assistant, @@ -17378,6 +17086,14 @@ }, /turf/open/floor/plating, /area/station/maintenance/department/medical/morgue) +"eNw" = ( +/obj/machinery/camera/directional/east{ + c_tag = "Security - Permabrig Observation South"; + network = list("ss13","prison") + }, +/obj/machinery/light/small/directional/east, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/underground/explored) "eNC" = ( /obj/machinery/status_display/evac/directional/west, /obj/item/kirbyplants/random, @@ -17412,6 +17128,20 @@ }, /turf/open/floor/iron/white, /area/station/science/research) +"eNX" = ( +/obj/structure/closet/secure_closet/security/sec, +/obj/structure/cable, +/obj/structure/extinguisher_cabinet/directional/south, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/turf_decal/bot, +/turf/open/floor/iron/smooth_edge{ + dir = 1 + }, +/area/station/security/lockers) +"eOe" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, +/turf/open/floor/iron, +/area/mine/laborcamp) "eOl" = ( /obj/effect/landmark/start/hangover, /turf/open/floor/iron, @@ -17420,13 +17150,6 @@ /obj/structure/sign/poster/official/no_erp/directional/west, /turf/closed/wall, /area/station/maintenance/starboard/fore) -"eOw" = ( -/obj/machinery/computer/shuttle/labor, -/obj/effect/turf_decal/tile/blue/anticorner/contrasted{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/command/bridge) "eOx" = ( /obj/structure/table, /obj/machinery/fax{ @@ -17452,6 +17175,10 @@ }, /turf/open/floor/iron/stairs/medium, /area/station/cargo/storage) +"eOY" = ( +/obj/machinery/firealarm/directional/west, +/turf/open/openspace, +/area/station/security/brig) "ePi" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/turf_decal/trimline/blue/filled/corner{ @@ -17518,6 +17245,17 @@ /obj/machinery/light/small/directional/north, /turf/open/floor/iron, /area/station/cargo/miningdock) +"ePD" = ( +/obj/structure/railing{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/decal/cleanable/greenglow/waste, +/obj/effect/turf_decal/tile/brown/opposingcorners, +/turf/open/floor/iron, +/area/mine/production) "ePP" = ( /obj/machinery/camera/directional/south{ c_tag = "Starboard Primary Hallway Center West" @@ -17567,11 +17305,6 @@ /obj/structure/grille, /turf/open/floor/plating, /area/station/maintenance/port/aft) -"eQA" = ( -/obj/item/kitchen/rollingpin, -/obj/structure/table, -/turf/open/floor/iron, -/area/station/security/prison/mess) "eQF" = ( /obj/structure/railing/corner, /obj/structure/sign/departments/holy/directional/west, @@ -17579,22 +17312,12 @@ dir = 9 }, /area/station/service/chapel) -"eQH" = ( -/obj/structure/sign/departments/medbay/alt/directional/west, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/mine/laborcamp) "eQO" = ( /obj/structure/reagent_dispensers/fueltank, /obj/effect/decal/cleanable/dirt/dust, /obj/effect/decal/cleanable/blood/oil, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) -"eQT" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable, -/turf/open/floor/plating, -/area/mine/laborcamp/security) "eRf" = ( /obj/effect/spawner/random/structure/grille, /turf/open/floor/plating, @@ -17608,16 +17331,6 @@ /obj/machinery/duct, /turf/open/floor/iron/freezer, /area/station/commons/toilet) -"eRp" = ( -/obj/structure/bed{ - dir = 1; - pixel_x = -2 - }, -/obj/machinery/flasher/directional/north{ - id = "Cell 1" - }, -/turf/open/floor/iron/smooth, -/area/station/security/brig) "eRw" = ( /obj/effect/landmark/event_spawn, /obj/structure/cable, @@ -17652,6 +17365,10 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/showroomfloor, /area/station/security/warden) +"eSf" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, +/turf/open/floor/iron, +/area/station/security/brig/upper) "eSn" = ( /obj/structure/chair/office, /obj/effect/landmark/start/assistant, @@ -17662,16 +17379,20 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/wood, /area/station/service/library) +"eSo" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment, +/obj/machinery/holopad, +/turf/open/floor/iron, +/area/station/security/brig/upper) "eSq" = ( /obj/machinery/atmospherics/components/unary/thermomachine/freezer/layer2{ dir = 1 }, /turf/open/floor/iron, /area/station/science/ordnance) -"eSr" = ( -/obj/effect/turf_decal/tile/red, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "eSC" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -17693,6 +17414,9 @@ }, /turf/open/floor/iron/white, /area/station/science/genetics) +"eSQ" = ( +/turf/open/floor/iron/dark/side, +/area/station/security/range) "eSY" = ( /obj/structure/closet/emcloset, /turf/open/floor/iron/smooth, @@ -17702,13 +17426,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/department/chapel) -"eTb" = ( -/obj/structure/fireplace, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 - }, -/turf/open/floor/carpet/black, -/area/station/security/prison/safe) "eTe" = ( /obj/effect/turf_decal/tile/blue{ dir = 4 @@ -17730,6 +17447,19 @@ /obj/structure/cable, /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/surface/outdoors/less_spawns) +"eTr" = ( +/obj/machinery/conveyor{ + id = "gulag"; + dir = 1 + }, +/obj/machinery/mineral/unloading_machine{ + dir = 1; + icon_state = "unloader-corner"; + input_dir = 2; + output_dir = 1 + }, +/turf/open/floor/iron, +/area/mine/laborcamp) "eTv" = ( /obj/machinery/door/airlock/security{ name = "Permanent Cell 1" @@ -17849,27 +17579,6 @@ }, /turf/open/floor/iron, /area/station/service/hydroponics/garden) -"eUB" = ( -/obj/structure/table, -/obj/item/flashlight{ - pixel_x = 1; - pixel_y = 5 - }, -/obj/item/clothing/suit/hooded/wintercoat{ - pixel_x = -5 - }, -/obj/item/clothing/suit/hooded/wintercoat/security{ - pixel_x = 5 - }, -/obj/item/clothing/suit/hooded/wintercoat/security{ - pixel_x = 5 - }, -/obj/item/clothing/suit/hooded/wintercoat/security{ - pixel_x = 5 - }, -/obj/machinery/light/small/directional/north, -/turf/open/floor/iron/dark, -/area/station/security/execution/education) "eUI" = ( /obj/structure/table/reinforced, /obj/machinery/reagentgrinder{ @@ -17934,6 +17643,14 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/mine/eva/lower) +"eVh" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 4 + }, +/obj/machinery/airalarm/directional/south, +/obj/machinery/firealarm/directional/west, +/turf/open/floor/iron/showroomfloor, +/area/station/security/prison/toilet) "eVn" = ( /obj/machinery/airalarm/directional/west, /obj/effect/landmark/start/bitrunner, @@ -18024,12 +17741,6 @@ /obj/machinery/portable_atmospherics/canister/plasma, /turf/open/floor/engine/plasma, /area/station/engineering/atmos) -"eWB" = ( -/obj/structure/rack, -/obj/item/electropack, -/obj/machinery/light_switch/directional/south, -/turf/open/floor/iron/dark/textured, -/area/station/security/interrogation) "eWF" = ( /obj/machinery/camera/directional/east{ c_tag = "Arrivals Escape Pod 2" @@ -18095,6 +17806,19 @@ }, /turf/open/floor/plating, /area/station/ai/satellite/service) +"eXx" = ( +/obj/structure/window/reinforced/spawner/directional/north{ + pixel_y = 2 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/chair/sofa/bench/left{ + dir = 4 + }, +/obj/effect/turf_decal/siding/red{ + dir = 1 + }, +/turf/open/floor/iron/smooth, +/area/station/security/holding_cell) "eXD" = ( /obj/structure/minecart_rail{ dir = 4 @@ -18150,16 +17874,6 @@ /obj/machinery/light/small/directional/south, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) -"eYz" = ( -/obj/machinery/mineral/processing_unit/gulag{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/mine/laborcamp) -"eYC" = ( -/turf/open/floor/iron/smooth, -/area/mine/laborcamp/security) "eYF" = ( /obj/machinery/power/apc/auto_name/directional/east, /obj/structure/cable, @@ -18312,39 +18026,20 @@ /obj/structure/sign/warning/cold_temp/directional/north, /turf/open/floor/plating, /area/station/maintenance/fore) +"faa" = ( +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/effect/turf_decal/tile/red/anticorner/contrasted{ + dir = 8 + }, +/obj/item/kirbyplants/random, +/turf/open/floor/iron, +/area/station/security/brig/upper) "fab" = ( /obj/structure/cable, /turf/open/floor/engine, /area/station/engineering/supermatter/room) -"fad" = ( -/obj/machinery/camera/directional/west{ - c_tag = "Security - HoS Office" - }, -/obj/item/flashlight/lamp/green{ - pixel_x = -6; - pixel_y = 16; - start_on = 0 - }, -/obj/structure/table/wood, -/obj/item/paper_bin{ - pixel_x = 8; - pixel_y = 3 - }, -/obj/item/stamp/head/hos{ - pixel_x = 10; - pixel_y = 6 - }, -/obj/machinery/recharger{ - pixel_x = -4; - pixel_y = -1 - }, -/obj/machinery/airalarm/directional/west, -/obj/item/phone{ - pixel_x = -9; - pixel_y = 7 - }, -/turf/open/floor/wood/large, -/area/station/command/heads_quarters/hos) "faf" = ( /obj/structure/tank_holder/extinguisher, /turf/open/floor/plating, @@ -18400,12 +18095,6 @@ /obj/effect/mapping_helpers/no_atoms_ontop, /turf/open/openspace/icemoon/keep_below, /area/icemoon/underground/explored) -"faV" = ( -/obj/machinery/atmospherics/components/unary/passive_vent/layer2{ - dir = 1 - }, -/turf/open/floor/plating/snowed/icemoon, -/area/mine/laborcamp/security) "faW" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 4 @@ -18421,6 +18110,16 @@ "fbl" = ( /turf/open/floor/iron/dark, /area/station/science/breakroom) +"fbp" = ( +/obj/machinery/firealarm/directional/east{ + pixel_y = 6 + }, +/obj/structure/cable, +/obj/machinery/light_switch/directional/east{ + pixel_y = -5 + }, +/turf/open/floor/iron, +/area/station/security/prison/visit) "fbw" = ( /obj/machinery/camera/directional/north{ c_tag = "Bridge Conference Room" @@ -18471,6 +18170,11 @@ }, /turf/open/floor/iron, /area/station/engineering/main) +"fch" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/machinery/airalarm/directional/west, +/turf/open/floor/iron/smooth, +/area/station/security/eva) "fcu" = ( /obj/machinery/power/apc/auto_name/directional/east, /obj/structure/chair, @@ -18513,11 +18217,6 @@ /obj/effect/spawner/random/structure/furniture_parts, /turf/open/floor/plating, /area/station/construction) -"fcY" = ( -/obj/structure/cable, -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/mine/laborcamp/security) "fdb" = ( /obj/machinery/atmospherics/pipe/smart/simple/orange/visible{ dir = 4 @@ -18561,10 +18260,6 @@ }, /turf/open/floor/iron, /area/station/science/xenobiology) -"fdm" = ( -/obj/structure/falsewall, -/turf/open/floor/iron, -/area/station/security/prison/safe) "fdp" = ( /turf/open/floor/iron, /area/mine/eva/lower) @@ -18574,6 +18269,17 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/aft) +"fdz" = ( +/obj/machinery/airalarm/directional/south, +/turf/open/floor/wood/large, +/area/station/security/prison/rec) +"fdD" = ( +/obj/structure/bed{ + dir = 1; + pixel_x = -2 + }, +/turf/open/floor/iron/smooth, +/area/station/security/brig) "fdF" = ( /obj/structure/closet/secure_closet/chemical, /obj/effect/turf_decal/trimline/blue/filled/line{ @@ -18585,10 +18291,6 @@ /obj/effect/decal/cleanable/plastic, /turf/open/floor/iron/white, /area/station/maintenance/port/fore) -"fdG" = ( -/obj/structure/cable, -/turf/open/floor/plating/icemoon, -/area/station/security/execution/education) "fdH" = ( /obj/machinery/meter, /obj/effect/turf_decal/stripes/line, @@ -18642,17 +18344,12 @@ /obj/structure/signpost, /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/underground/explored) -"fez" = ( +"fer" = ( +/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/stripes/red/line, /obj/effect/decal/cleanable/dirt, -/obj/structure/closet/crate, -/obj/item/seeds/wheat, -/obj/item/seeds/wheat, -/obj/item/seeds/tomato, -/obj/item/seeds/onion, -/obj/item/seeds/garlic, -/obj/item/seeds/carrot, -/obj/item/seeds/ambrosia, -/obj/item/seeds/apple, /turf/open/floor/iron, /area/mine/laborcamp) "feD" = ( @@ -18663,6 +18360,12 @@ "feJ" = ( /turf/closed/wall/r_wall, /area/station/security/armory/upper) +"feL" = ( +/obj/machinery/vending/wardrobe/sec_wardrobe, +/obj/machinery/airalarm/directional/north, +/obj/effect/turf_decal/bot/left, +/turf/open/floor/iron/smooth_edge, +/area/station/security/lockers) "feQ" = ( /obj/machinery/portable_atmospherics/canister/air, /turf/open/floor/plating, @@ -18699,6 +18402,14 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/service/chapel) +"ffN" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, +/obj/machinery/light/small/directional/south, +/turf/open/floor/iron/showroomfloor, +/area/station/security/prison/toilet) "ffQ" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 10 @@ -18793,12 +18504,6 @@ /obj/machinery/light/directional/west, /turf/open/floor/iron, /area/station/commons/dorms) -"fhu" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/security/processing) "fhw" = ( /obj/machinery/piratepad/civilian, /obj/effect/turf_decal/loading_area, @@ -18809,26 +18514,10 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating, /area/station/maintenance/fore) -"fhF" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/obj/machinery/light/warm/directional/east, -/turf/open/floor/iron, -/area/station/security/prison/mess) "fhL" = ( /obj/structure/sign/warning/directional/north, /turf/open/openspace/icemoon/keep_below, /area/icemoon/underground/explored) -"fhU" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 1 - }, -/obj/effect/turf_decal/tile/red, -/turf/open/floor/iron, -/area/station/security/prison/mess) "fhW" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -18948,6 +18637,16 @@ /obj/machinery/atmospherics/pipe/heat_exchanging/simple, /turf/open/floor/plating/snowed/coldroom, /area/station/service/kitchen/coldroom) +"fjb" = ( +/obj/structure/chair/sofa/bench{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 4 + }, +/obj/machinery/newscaster/directional/east, +/turf/open/floor/iron/smooth, +/area/station/security/brig/upper) "fjg" = ( /obj/machinery/shower/directional/west, /obj/effect/turf_decal/trimline/blue, @@ -18981,10 +18680,6 @@ /obj/structure/reagent_dispensers/watertank, /turf/open/floor/plating, /area/station/maintenance/port/fore) -"fjG" = ( -/obj/machinery/portable_atmospherics/canister/air, -/turf/open/floor/plating, -/area/station/security/prison/safe) "fjH" = ( /obj/structure/cable, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ @@ -19080,16 +18775,6 @@ }, /turf/open/floor/plating/icemoon, /area/station/science/ordnance/bomb/planet) -"fkV" = ( -/obj/machinery/door/airlock/maintenance{ - name = "Permabrig Maintenance" - }, -/obj/structure/cable, -/obj/effect/mapping_helpers/airlock/access/all/security/brig, -/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/prison/safe) "fkX" = ( /obj/structure/lattice/catwalk, /obj/structure/railing/corner{ @@ -19121,6 +18806,11 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/large, /area/station/commons/storage/mining) +"flz" = ( +/obj/structure/easel, +/obj/item/canvas/nineteen_nineteen, +/turf/open/floor/iron/sepia, +/area/station/security/prison/rec) "flD" = ( /obj/effect/spawner/random/structure/tank_holder, /turf/open/floor/plating, @@ -19226,14 +18916,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/fore) -"fnj" = ( -/obj/structure/table/wood, -/obj/effect/spawner/random/entertainment/deck, -/obj/effect/turf_decal/siding/wood{ - dir = 1 - }, -/turf/open/floor/wood, -/area/station/security/prison/rec) "fnt" = ( /obj/effect/turf_decal/tile/red{ dir = 4 @@ -19255,19 +18937,6 @@ /obj/structure/chair/sofa/middle/brown, /turf/open/floor/carpet/blue, /area/station/security/prison/work) -"fnS" = ( -/obj/structure/cable, -/obj/effect/mapping_helpers/broken_floor, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/plating, -/area/station/maintenance/fore) -"fnW" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/trimline/red/warning{ - dir = 8 - }, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) "fog" = ( /obj/machinery/rnd/production/techfab/department/medical, /obj/effect/turf_decal/trimline/blue/filled/line{ @@ -19366,12 +19035,6 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/iron, /area/station/engineering/atmos/pumproom) -"fqG" = ( -/obj/structure/fluff/fokoff_sign, -/obj/effect/mapping_helpers/no_atoms_ontop, -/obj/structure/sign/departments/security/directional/north, -/turf/open/misc/asteroid/snow/icemoon, -/area/icemoon/underground/explored) "fqJ" = ( /obj/effect/turf_decal/trimline/white/filled/warning, /turf/open/genturf, @@ -19428,6 +19091,13 @@ /obj/effect/turf_decal/tile/neutral/anticorner/contrasted, /turf/open/floor/iron, /area/station/commons/locker) +"frf" = ( +/obj/effect/decal/cleanable/dirt, +/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/security/prison/workout) "fri" = ( /obj/structure/flora/tree/pine/style_random, /turf/open/misc/asteroid/snow/icemoon, @@ -19483,6 +19153,13 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/security/evidence) +"fsd" = ( +/obj/structure/cable, +/obj/machinery/light/directional/south, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/mine/laborcamp) "fsj" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/decal/cleanable/dirt, @@ -19495,16 +19172,6 @@ /obj/structure/flora/rock/pile/icy/style_random, /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/surface/outdoors/nospawn) -"fsp" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/obj/effect/turf_decal/stripes/red/line{ - dir = 1 - }, -/obj/effect/turf_decal/trimline/red/corner{ - dir = 8 - }, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) "fsv" = ( /turf/open/floor/iron, /area/station/hallway/secondary/entry) @@ -19531,6 +19198,20 @@ }, /turf/open/floor/plating, /area/station/security/execution/education) +"fsP" = ( +/obj/machinery/firealarm/directional/south, +/obj/structure/secure_safe/hos{ + pixel_x = 28; + pixel_y = 6 + }, +/obj/structure/filingcabinet/security{ + pixel_x = -6 + }, +/obj/structure/filingcabinet{ + pixel_x = 6 + }, +/turf/open/floor/iron/dark/smooth_large, +/area/station/command/heads_quarters/hos) "fsQ" = ( /obj/machinery/atmospherics/pipe/smart/simple/cyan/visible, /obj/effect/turf_decal/tile/blue{ @@ -19566,31 +19247,12 @@ /obj/structure/sign/flag/nanotrasen/directional/north, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) -"ftA" = ( -/obj/structure/table, -/obj/item/storage/box/prisoner, -/turf/open/floor/iron/showroomfloor, -/area/station/security/processing) "ftE" = ( /obj/machinery/light/directional/east, /obj/machinery/newscaster/directional/east, /obj/machinery/hydroponics/soil/rich, /turf/open/floor/grass, /area/station/service/hydroponics/garden) -"ftJ" = ( -/obj/structure/table/reinforced, -/obj/machinery/door/poddoor/shutters/preopen{ - dir = 8; - id = "gene_desk_shutters"; - name = "Genetics Shutters" - }, -/obj/machinery/door/firedoor, -/obj/machinery/door/window/right/directional/east{ - name = "Genetics Desk"; - req_access = list("genetics") - }, -/turf/open/floor/plating, -/area/station/science/genetics) "ftN" = ( /obj/machinery/rnd/destructive_analyzer, /turf/open/floor/iron/checker, @@ -19646,11 +19308,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/central) -"fuX" = ( -/obj/structure/cable, -/obj/machinery/power/apc/auto_name/directional/south, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) "fuY" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -19787,11 +19444,6 @@ /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/plating, /area/station/maintenance/department/medical/morgue) -"fwL" = ( -/obj/structure/sink/kitchen/directional/south, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron/cafeteria, -/area/station/security/prison/mess) "fwM" = ( /obj/effect/turf_decal/tile/blue{ dir = 4 @@ -19842,6 +19494,25 @@ /obj/effect/turf_decal/tile/red/anticorner/contrasted, /turf/open/floor/iron, /area/station/security/checkpoint/supply) +"fxw" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/mapping_helpers/airlock/access/all/security/general, +/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/maintenance{ + name = "Security Maintenance" + }, +/turf/open/floor/plating, +/area/station/security/range) +"fxP" = ( +/obj/machinery/newscaster/directional/north, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/station/security/prison/visit) "fxR" = ( /obj/machinery/telecomms/hub/preset, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -19885,6 +19556,15 @@ /obj/structure/cable/layer3, /turf/open/floor/iron/dark, /area/station/ai/satellite/chamber) +"fyt" = ( +/obj/machinery/conveyor{ + id = "gulag"; + dir = 5 + }, +/obj/machinery/light/small/directional/north, +/obj/structure/sign/warning/directional/north, +/turf/open/floor/iron, +/area/mine/laborcamp) "fyw" = ( /obj/machinery/telecomms/server/presets/service, /turf/open/floor/iron/dark/telecomms, @@ -19931,6 +19611,17 @@ /obj/effect/spawner/random/maintenance/no_decals/two, /turf/open/floor/iron/smooth_large, /area/station/cargo/warehouse) +"fzk" = ( +/obj/effect/turf_decal/stripes/red/line{ + dir = 9 + }, +/obj/machinery/door/poddoor/shutters/window/preopen{ + name = "Firing Range Shutters"; + dir = 1; + id = "firingrangeshuttersoutside" + }, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/surface/outdoors/nospawn) "fzo" = ( /obj/machinery/firealarm/directional/west, /obj/effect/turf_decal/tile/blue/anticorner/contrasted{ @@ -19953,6 +19644,12 @@ /obj/machinery/light/directional/north, /turf/open/floor/iron, /area/station/hallway/primary/central) +"fzB" = ( +/obj/effect/spawner/structure/window, +/obj/structure/cable, +/obj/machinery/door/firedoor, +/turf/open/floor/plating, +/area/station/security/office) "fzD" = ( /obj/structure/disposalpipe/segment, /obj/item/radio/intercom/directional/east, @@ -20007,6 +19704,11 @@ /obj/structure/cable, /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/surface/outdoors/less_spawns) +"fAa" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/plating, +/area/station/maintenance/department/security) "fAF" = ( /obj/structure/rack, /obj/item/clothing/gloves/boxing/green, @@ -20021,13 +19723,6 @@ /obj/item/clothing/mask/breath/muzzle, /turf/open/floor/iron/dark, /area/station/science/robotics/lab) -"fAH" = ( -/obj/effect/turf_decal/tile/red/anticorner/contrasted, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 1 - }, -/turf/open/floor/iron/dark, -/area/station/security/mechbay) "fAV" = ( /obj/item/kirbyplants/random, /turf/open/floor/iron, @@ -20059,20 +19754,6 @@ }, /turf/open/floor/plating, /area/station/cargo/drone_bay) -"fBs" = ( -/obj/structure/table, -/obj/item/paper, -/obj/item/pen, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/camera/directional/west{ - c_tag = "Labor Camp Cell 3"; - network = list("labor") - }, -/obj/machinery/flasher/directional/west{ - id = "GulagCell 3" - }, -/turf/open/floor/iron, -/area/mine/laborcamp) "fBw" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 5 @@ -20097,6 +19778,13 @@ /obj/item/radio/intercom/directional/north, /turf/open/floor/iron/white, /area/station/medical/virology) +"fBz" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/plating, +/area/station/maintenance/department/security) "fBJ" = ( /obj/machinery/modular_computer/preset/civilian, /obj/machinery/requests_console/directional/north{ @@ -20121,6 +19809,16 @@ /obj/structure/cable, /turf/open/floor/iron/white, /area/station/medical/medbay/central) +"fBY" = ( +/obj/effect/turf_decal/trimline/red/warning{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/red/line{ + dir = 4 + }, +/obj/machinery/light/small/red/directional/east, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/surface/outdoors/nospawn) "fCm" = ( /obj/structure/sign/warning/secure_area/directional/north, /turf/closed/mineral/random/snow, @@ -20143,10 +19841,6 @@ }, /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/surface/outdoors/less_spawns) -"fCW" = ( -/obj/structure/extinguisher_cabinet/directional/east, -/turf/open/floor/iron/dark/textured, -/area/station/security/processing) "fDc" = ( /obj/structure/chair/office, /obj/effect/landmark/start/warden, @@ -20228,17 +19922,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/commons/fitness) -"fEA" = ( -/obj/structure/cable, -/obj/machinery/door/airlock/maintenance{ - name = "Transport Maintenance" - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment, -/obj/effect/mapping_helpers/airlock/access/all/security/general, -/turf/open/floor/plating, -/area/station/security/processing) "fEL" = ( /obj/machinery/holopad, /obj/machinery/duct, @@ -20270,14 +19953,6 @@ /obj/effect/mapping_helpers/airlock/access/all/supply/mining, /turf/open/floor/stone, /area/mine/eva/lower) -"fEX" = ( -/obj/structure/cable, -/obj/machinery/power/apc/auto_name/directional/north, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "fEZ" = ( /obj/effect/spawner/structure/window, /turf/open/floor/plating, @@ -20297,6 +19972,12 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/stone, /area/station/service/bar/atrium) +"fFg" = ( +/obj/structure/window/reinforced/spawner/directional/north, +/turf/open/floor/iron/dark/side{ + dir = 1 + }, +/area/station/security/range) "fFi" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -20351,17 +20032,21 @@ /obj/effect/turf_decal/bot, /turf/open/floor/iron/dark, /area/station/science/ordnance/office) -"fGq" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/toilet{ - dir = 8 - }, -/obj/item/radio/intercom/directional/east, +"fGr" = ( +/obj/effect/turf_decal/tile/red/anticorner/contrasted, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 1 + }, +/obj/effect/landmark/event_spawn, +/turf/open/floor/iron/dark, +/area/station/security/mechbay) +"fGA" = ( +/obj/effect/turf_decal/stripes/line{ dir = 8 }, -/turf/open/floor/iron/smooth, -/area/station/security/holding_cell) +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/plating, +/area/station/maintenance/fore) "fGI" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, @@ -20478,6 +20163,18 @@ /obj/machinery/light/small/directional/west, /turf/open/floor/iron/white, /area/station/maintenance/port/fore) +"fIE" = ( +/obj/structure/table, +/obj/item/restraints/handcuffs, +/obj/item/restraints/handcuffs{ + pixel_y = 2; + pixel_x = 4 + }, +/obj/item/assembly/timer, +/turf/open/floor/iron/dark/textured_half{ + dir = 1 + }, +/area/station/security/office) "fIK" = ( /obj/structure/railing/corner/end/flip{ dir = 4 @@ -20594,9 +20291,6 @@ /obj/structure/fluff/tram_rail, /turf/open/openspace/icemoon/keep_below, /area/icemoon/underground/explored) -"fKw" = ( -/turf/open/floor/plating/snowed/smoothed/icemoon, -/area/icemoon/surface/outdoors/labor_camp) "fKF" = ( /obj/effect/turf_decal/plaque{ icon_state = "L7" @@ -20687,10 +20381,6 @@ }, /turf/open/floor/iron/dark, /area/station/security/checkpoint/engineering) -"fLs" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/closed/wall/r_wall, -/area/station/security/armory/upper) "fLu" = ( /obj/effect/turf_decal/tile/green/opposingcorners{ dir = 1 @@ -20749,13 +20439,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/port/greater) -"fLT" = ( -/obj/machinery/door/airlock{ - name = "Restroom" - }, -/obj/effect/mapping_helpers/airlock/access/all/security/brig, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "fLY" = ( /obj/structure/table, /obj/item/stock_parts/micro_laser{ @@ -20781,6 +20464,11 @@ }, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) +"fMk" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, +/obj/machinery/firealarm/directional/east, +/turf/open/floor/iron/smooth, +/area/station/security/eva) "fMt" = ( /obj/effect/turf_decal/bot{ dir = 1 @@ -20868,6 +20556,12 @@ /obj/structure/window/reinforced/spawner/directional/south, /turf/open/floor/iron/white/smooth_large, /area/station/service/kitchen) +"fOd" = ( +/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/mine/laborcamp) "fOq" = ( /obj/structure/sign/warning/cold_temp/directional/north, /turf/open/floor/plating, @@ -20931,6 +20625,10 @@ }, /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/surface/outdoors/nospawn) +"fPe" = ( +/obj/structure/cable, +/turf/open/floor/iron/dark, +/area/station/security/prison/rec) "fPv" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -20979,17 +20677,6 @@ /obj/effect/landmark/navigate_destination/dockesc, /turf/open/floor/plating, /area/station/hallway/secondary/exit/departure_lounge) -"fPY" = ( -/obj/structure/table/reinforced, -/obj/structure/extinguisher_cabinet/directional/south, -/obj/item/gun/energy/laser/carbine/practice{ - pixel_x = 3; - pixel_y = -3 - }, -/obj/item/gun/energy/laser/practice, -/obj/item/clothing/ears/earmuffs, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) "fPZ" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -21038,6 +20725,13 @@ dir = 1 }, /area/station/security/prison) +"fQR" = ( +/obj/structure/lattice/catwalk, +/obj/structure/railing{ + dir = 4 + }, +/turf/open/lava/plasma/ice_moon, +/area/icemoon/underground/explored) "fRb" = ( /obj/machinery/door/airlock/maintenance, /obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance, @@ -21111,6 +20805,16 @@ /obj/effect/turf_decal/weather/snow/corner, /turf/open/floor/plating/snowed/coldroom, /area/icemoon/underground/explored) +"fSF" = ( +/obj/structure/sign/nanotrasen/directional/east, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/underground/explored) +"fSL" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/security/brig/upper) "fSP" = ( /obj/structure/railing{ dir = 1 @@ -21157,19 +20861,6 @@ }, /turf/open/floor/iron/dark/smooth_half, /area/station/medical/morgue) -"fTo" = ( -/obj/item/reagent_containers/condiment/saltshaker{ - pixel_x = -3 - }, -/obj/item/reagent_containers/condiment/peppermill{ - pixel_x = 3 - }, -/obj/structure/window/reinforced/spawner/directional/west, -/obj/item/knife/plastic, -/obj/structure/table/reinforced, -/obj/item/radio/intercom/prison/directional/north, -/turf/open/floor/iron/cafeteria, -/area/station/security/prison/mess) "fTx" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 4 @@ -21244,10 +20935,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) -"fUj" = ( -/obj/structure/bed/medical/emergency, -/turf/open/floor/iron/white/textured, -/area/station/security/medical) "fUr" = ( /obj/machinery/airalarm/directional/south, /obj/structure/closet/emcloset, @@ -21371,28 +21058,19 @@ /obj/machinery/light/small/directional/west, /turf/open/floor/iron/dark, /area/station/command/gateway) -"fWa" = ( -/obj/structure/chair/wood{ - dir = 4 - }, -/obj/effect/turf_decal/siding/wood{ - dir = 8 - }, -/turf/open/floor/wood, -/area/station/security/prison/rec) "fWe" = ( /obj/machinery/hydroponics/soil, /obj/item/plant_analyzer, /turf/open/floor/grass, /area/station/security/prison/garden) -"fWo" = ( -/obj/effect/decal/cleanable/dirt, -/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, -/area/mine/laborcamp) +"fWm" = ( +/obj/structure/rack, +/obj/item/storage/box/prisoner, +/obj/effect/turf_decal/siding/dark{ + dir = 1 + }, +/turf/open/floor/iron/dark, +/area/mine/laborcamp/security) "fWw" = ( /obj/structure/railing/corner, /turf/open/misc/asteroid/snow/icemoon, @@ -21431,21 +21109,21 @@ /obj/effect/spawner/random/trash/mess, /turf/open/floor/plating, /area/station/maintenance/aft/lesser) -"fWQ" = ( -/obj/machinery/flasher/directional/north{ - id = "Cell 2" - }, -/obj/structure/bed{ - dir = 1; - pixel_x = -2 - }, -/turf/open/floor/iron/smooth, -/area/station/security/brig) "fWS" = ( /obj/structure/mineral_door/wood, /obj/structure/barricade/wooden/crude/snow, /turf/open/floor/wood, /area/station/maintenance/space_hut/cabin) +"fWW" = ( +/obj/machinery/door/airlock{ + name = "Utility Closet" + }, +/obj/effect/mapping_helpers/airlock/access/all/security/brig, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/department/security) "fWX" = ( /obj/structure/cable/multilayer/multiz, /turf/open/floor/plating/snowed/icemoon, @@ -21459,6 +21137,15 @@ }, /turf/open/floor/carpet, /area/station/command/heads_quarters/captain) +"fXi" = ( +/obj/vehicle/sealed/mecha/ripley/paddy/preset, +/obj/structure/cable, +/obj/machinery/light/small/directional/south, +/obj/machinery/camera/directional/west{ + c_tag = "Security - Mechbay" + }, +/turf/open/floor/iron/recharge_floor, +/area/station/security/mechbay) "fXq" = ( /obj/item/clothing/head/cone{ pixel_x = 3 @@ -21484,23 +21171,10 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/service/bar) -"fXy" = ( -/obj/structure/cable, -/obj/machinery/computer/prisoner/management, -/obj/effect/turf_decal/tile/red/opposingcorners, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "fXL" = ( /obj/structure/sign/poster/official/here_for_your_safety/directional/north, /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/underground/explored) -"fXO" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/obj/machinery/airalarm/directional/south, -/turf/open/floor/iron/showroomfloor, -/area/station/security/prison/toilet) "fXQ" = ( /obj/structure/railing{ dir = 1 @@ -21514,6 +21188,11 @@ }, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) +"fXY" = ( +/obj/structure/bed/medical/emergency, +/obj/structure/extinguisher_cabinet/directional/west, +/turf/open/floor/iron/white/textured, +/area/station/security/medical) "fYi" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -21546,11 +21225,6 @@ /obj/structure/cable, /turf/open/floor/carpet, /area/station/security/detectives_office) -"fYQ" = ( -/obj/machinery/light/small/directional/west, -/mob/living/basic/mouse/brown/tom, -/turf/open/floor/plating, -/area/station/security/prison/safe) "fYS" = ( /turf/closed/wall, /area/station/commons/storage/primary) @@ -21588,10 +21262,6 @@ }, /turf/open/floor/plating, /area/station/command/teleporter) -"fZq" = ( -/obj/structure/curtain/cloth, -/turf/open/floor/iron/showroomfloor, -/area/station/security/prison/toilet) "fZy" = ( /obj/structure/lattice/catwalk, /obj/structure/railing{ @@ -21631,6 +21301,14 @@ }, /turf/open/floor/iron, /area/station/commons/dorms) +"fZY" = ( +/obj/machinery/conveyor{ + id = "gulag"; + dir = 2 + }, +/obj/structure/plasticflaps, +/turf/open/floor/iron, +/area/mine/laborcamp) "gad" = ( /obj/item/radio/intercom/directional/east, /obj/structure/table/reinforced, @@ -21730,12 +21408,6 @@ /obj/machinery/light/small/directional/west, /turf/open/misc/asteroid/snow/standard_air, /area/station/science/cytology) -"gaS" = ( -/obj/item/hot_potato/harmless/toy, -/obj/structure/table/wood, -/obj/machinery/airalarm/directional/south, -/turf/open/floor/eighties/red, -/area/station/security/prison/safe) "gaT" = ( /obj/effect/turf_decal/stripes/line{ dir = 5 @@ -21770,6 +21442,10 @@ /obj/machinery/light/small/directional/south, /turf/open/floor/engine, /area/station/engineering/supermatter) +"gbt" = ( +/obj/structure/closet/secure_closet/freezer/fridge/all_access, +/turf/open/floor/iron/kitchen_coldroom/freezerfloor, +/area/station/security/prison/mess) "gbu" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -21833,21 +21509,21 @@ /obj/structure/cable, /turf/open/floor/iron/white, /area/station/medical/storage) +"gbT" = ( +/obj/machinery/button/door/directional/west{ + name = "Security Mech Garage Door Controls"; + id = "secmechbaymaint"; + req_access = list("security") + }, +/obj/structure/girder, +/obj/structure/grille, +/turf/open/floor/plating, +/area/station/maintenance/fore) "gcd" = ( /obj/structure/chair/sofa/corp/left, /obj/effect/landmark/start/hangover, /turf/open/floor/iron/dark, /area/station/engineering/lobby) -"gck" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/obj/machinery/door/airlock/maintenance{ - name = "Vestibule Maintenance" - }, -/obj/effect/mapping_helpers/airlock/access/all/security/general, -/turf/open/floor/plating, -/area/station/security/processing) "gcu" = ( /obj/effect/mapping_helpers/burnt_floor, /obj/structure/cable, @@ -21909,6 +21585,15 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) +"gdE" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/machinery/light/warm/directional/west, +/obj/machinery/vending/sovietsoda, +/obj/item/radio/intercom/prison/directional/west, +/turf/open/floor/iron, +/area/station/security/prison/mess) "gdG" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/shutters/preopen{ @@ -21985,10 +21670,6 @@ }, /turf/open/floor/iron/grimy, /area/station/hallway/secondary/entry) -"gem" = ( -/obj/structure/railing, -/turf/open/floor/plating/snowed/smoothed/icemoon, -/area/icemoon/underground/explored) "geq" = ( /obj/structure/closet/secure_closet/personal{ anchored = 1 @@ -21997,6 +21678,15 @@ /obj/machinery/status_display/ai/directional/south, /turf/open/floor/iron, /area/station/commons/locker) +"gew" = ( +/obj/machinery/door/poddoor/shutters/preopen{ + dir = 8; + id = "gene_shutters"; + name = "Genetics Shutters" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/station/science/genetics) "geJ" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -22047,6 +21737,14 @@ /obj/structure/light_construct/directional/south, /turf/open/floor/plating, /area/station/maintenance/port/aft) +"gfE" = ( +/obj/structure/lattice/catwalk, +/obj/structure/railing{ + dir = 8 + }, +/obj/structure/sign/nanotrasen/directional/north, +/turf/open/lava/plasma/ice_moon, +/area/icemoon/underground/explored) "gfF" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -22055,10 +21753,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/cafeteria, /area/station/commons/storage/art) -"gfV" = ( -/obj/machinery/light/small/directional/north, -/turf/open/floor/iron/smooth, -/area/station/engineering/lobby) +"gfR" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/machinery/airalarm/directional/south, +/turf/open/floor/iron/cafeteria, +/area/station/security/prison/mess) "gga" = ( /obj/machinery/light/small/directional/west, /obj/effect/spawner/random/trash/hobo_squat, @@ -22122,14 +21823,6 @@ }, /turf/open/floor/plating, /area/station/ai/satellite/interior) -"ggV" = ( -/obj/machinery/conveyor{ - id = "gulag" - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/light/small/directional/east, -/turf/open/floor/plating, -/area/mine/laborcamp) "ghb" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/neutral{ @@ -22271,14 +21964,31 @@ /obj/item/radio/intercom/directional/east, /turf/open/floor/iron, /area/station/science/robotics/lab) +"gjo" = ( +/obj/structure/chair/pew/right{ + dir = 8 + }, +/turf/open/floor/wood/large, +/area/station/security/prison/rec) "gjq" = ( /turf/open/openspace/icemoon/keep_below, /area/icemoon/underground/explored) +"gjs" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, +/obj/item/radio/intercom/prison/directional/south, +/turf/open/floor/iron/dark/textured, +/area/station/security/prison) "gjt" = ( /obj/effect/mapping_helpers/broken_floor, /obj/structure/cable, /turf/open/floor/plating, /area/station/medical/morgue) +"gjy" = ( +/obj/structure/sign/poster/official/random/directional/east, +/turf/open/floor/iron, +/area/station/security/brig/upper) "gjI" = ( /obj/effect/spawner/random/structure/tank_holder, /obj/effect/turf_decal/tile/yellow, @@ -22347,18 +22057,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, /area/station/science/xenobiology) -"gko" = ( -/obj/machinery/conveyor{ - dir = 8; - id = "mining_internal" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line, -/obj/machinery/bouldertech/refinery/smelter, -/turf/open/floor/iron, -/area/mine/production) "gks" = ( /obj/effect/spawner/random/structure/closet_maintenance, /turf/open/floor/plating, @@ -22428,6 +22126,16 @@ "glh" = ( /turf/closed/wall/r_wall, /area/station/maintenance/solars/port/aft) +"glj" = ( +/obj/structure/chair{ + dir = 8 + }, +/obj/structure/sign/departments/evac/directional/east, +/obj/effect/turf_decal/tile/blue/half/contrasted{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/hallway/primary/starboard) "glk" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -22469,6 +22177,29 @@ /obj/structure/cable, /turf/open/floor/iron/dark/textured_large, /area/station/security/evidence) +"glE" = ( +/obj/machinery/button/door/directional/north{ + id = "labor"; + name = "Labor Camp Lockdown"; + req_access = list("brig"); + pixel_x = -6 + }, +/obj/structure/bed/dogbed, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/button/door/directional/north{ + id = "labordoor"; + name = "Labour Camp Emergency Entrance"; + req_access = list("brig"); + pixel_x = 6 + }, +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 4 + }, +/mob/living/basic/bot/secbot/pingsky, +/turf/open/floor/iron/dark/side{ + dir = 4 + }, +/area/mine/laborcamp/security) "glI" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, @@ -22589,10 +22320,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/service/hydroponics) -"gnL" = ( -/obj/structure/closet/bombcloset/security, -/turf/open/floor/iron/smooth, -/area/station/security/brig/upper) "gnM" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -22684,6 +22411,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/dark, /area/station/commons/vacant_room/office) +"goP" = ( +/obj/structure/railing, +/obj/machinery/door/poddoor/shutters/window{ + id = "executionshutters"; + name = "Exterior Shutters" + }, +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/security/execution/education) "goY" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/decal/cleanable/dirt/dust, @@ -22739,6 +22475,10 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/ai/satellite/interior) +"gpD" = ( +/obj/machinery/light/small/directional/west, +/turf/open/floor/iron, +/area/mine/laborcamp) "gpM" = ( /obj/effect/turf_decal/siding/wood{ dir = 4 @@ -22782,15 +22522,6 @@ }, /turf/open/floor/iron, /area/station/commons/storage/tools) -"gqh" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/sink/kitchen/directional/north{ - desc = "A sink used for washing one's hands and face. It looks rusty and home-made"; - name = "old sink" - }, -/obj/effect/turf_decal/tile/green/half/contrasted, -/turf/open/floor/iron/dark, -/area/mine/laborcamp) "gqj" = ( /obj/structure/railing/corner{ dir = 1 @@ -22860,6 +22591,11 @@ /obj/effect/turf_decal/box/white, /turf/open/floor/iron/dark/smooth_large, /area/station/engineering/storage/tech) +"gre" = ( +/obj/effect/spawner/random/trash/cigbutt, +/obj/effect/spawner/random/trash/cigbutt, +/turf/open/floor/plating, +/area/station/maintenance/department/security) "grk" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 1 @@ -23223,14 +22959,6 @@ /obj/structure/light_construct/directional/east, /turf/open/floor/iron, /area/station/construction) -"gwy" = ( -/obj/structure/window/reinforced/spawner/directional/south, -/obj/structure/flora/bush/sparsegrass/style_random, -/obj/machinery/light/warm/directional/north, -/turf/open/misc/ashplanet/wateryrock{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, -/area/station/security/prison/rec) "gwz" = ( /obj/effect/landmark/start/hangover, /obj/effect/turf_decal/tile/blue/opposingcorners{ @@ -23271,6 +22999,14 @@ }, /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/underground/explored) +"gxb" = ( +/obj/machinery/power/apc/auto_name/directional/south, +/obj/structure/cable, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 1 + }, +/turf/open/floor/iron/dark, +/area/station/security/prison/rec) "gxg" = ( /obj/structure/cable, /turf/open/floor/stone, @@ -23290,10 +23026,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central) -"gxx" = ( -/obj/item/radio/intercom/prison/directional/south, -/turf/open/floor/iron/dark, -/area/station/security/prison/rec) "gxO" = ( /obj/structure/table/reinforced, /obj/item/hand_labeler{ @@ -23365,6 +23097,15 @@ /obj/machinery/newscaster/directional/north, /turf/open/floor/iron/dark, /area/station/hallway/secondary/entry) +"gyK" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/disposalpipe/segment, +/obj/effect/spawner/random/engineering/tracking_beacon, +/obj/machinery/light/floor, +/turf/open/floor/iron, +/area/station/security/brig/upper) "gyO" = ( /obj/structure/table, /obj/item/book/manual/wiki/cytology{ @@ -23395,6 +23136,10 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/ai/satellite/interior) +"gzB" = ( +/obj/machinery/firealarm/directional/east, +/turf/open/floor/iron/sepia, +/area/station/security/prison/rec) "gzH" = ( /obj/machinery/door/firedoor/heavy, /obj/machinery/door/airlock/research{ @@ -23424,15 +23169,6 @@ }, /turf/open/floor/iron/smooth, /area/station/engineering/lobby) -"gzV" = ( -/obj/structure/mineral_door/paperframe{ - name = "Meditation Room" - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/sepia, -/area/station/security/prison/rec) "gzY" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, @@ -23471,11 +23207,6 @@ /obj/structure/girder, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) -"gAu" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/security/prison/visit) "gAz" = ( /obj/machinery/computer/mech_bay_power_console{ dir = 4 @@ -23577,6 +23308,12 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/service/bar) +"gBT" = ( +/obj/effect/spawner/random/trash/moisture_trap, +/obj/effect/mapping_helpers/broken_floor, +/obj/effect/turf_decal/siding/wood, +/turf/open/floor/wood, +/area/station/maintenance/fore) "gBX" = ( /obj/structure/cable, /obj/effect/spawner/structure/window/hollow/reinforced/middle{ @@ -23635,6 +23372,10 @@ }, /turf/open/floor/iron, /area/station/engineering/lobby) +"gCO" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/turf/open/floor/iron/dark, +/area/station/security/prison/rec) "gCQ" = ( /obj/structure/rack, /obj/item/storage/box/evidence, @@ -23672,6 +23413,19 @@ /obj/structure/cable, /turf/open/floor/wood, /area/station/security/courtroom) +"gDg" = ( +/obj/effect/mapping_helpers/airlock/access/all/security/general, +/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, +/obj/machinery/door/airlock/maintenance{ + name = "Security Maintenance" + }, +/turf/open/floor/plating, +/area/station/security/brig/upper) "gDh" = ( /obj/structure/rack, /obj/item/pickaxe, @@ -23808,6 +23562,22 @@ }, /turf/open/floor/iron/cafeteria, /area/station/hallway/secondary/exit/departure_lounge) +"gFc" = ( +/obj/machinery/conveyor_switch/oneway{ + id = "mining_internal"; + name = "mining conveyor"; + pixel_x = 1; + pixel_y = 8 + }, +/obj/structure/railing{ + dir = 4 + }, +/obj/structure/railing/corner/end/flip{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/iron, +/area/mine/production) "gFj" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 4 @@ -23835,6 +23605,11 @@ "gFX" = ( /turf/closed/wall, /area/icemoon/underground/explored) +"gGh" = ( +/obj/effect/turf_decal/bot, +/obj/structure/ore_box, +/turf/open/floor/iron, +/area/mine/laborcamp) "gGs" = ( /obj/structure/closet/secure_closet/engineering_welding, /obj/machinery/newscaster/directional/west, @@ -23893,6 +23668,20 @@ dir = 8 }, /area/mine/eva) +"gGV" = ( +/obj/machinery/door/poddoor/preopen{ + id = "Prison Gate"; + name = "Prison Blast Door" + }, +/obj/machinery/door/firedoor, +/obj/structure/cable, +/obj/effect/turf_decal/stripes/red/line, +/obj/effect/turf_decal/stripes/red/line{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron/dark/textured, +/area/station/security/brig) "gGZ" = ( /obj/machinery/computer/bank_machine, /obj/effect/turf_decal/bot_white, @@ -23904,10 +23693,6 @@ /obj/effect/turf_decal/tile/blue, /turf/open/floor/iron, /area/station/hallway/primary/central) -"gHg" = ( -/obj/machinery/mineral/processing_unit_console, -/turf/closed/wall, -/area/mine/laborcamp) "gHl" = ( /obj/machinery/atmospherics/pipe/smart/simple/dark/visible/layer1{ dir = 8 @@ -23940,14 +23725,6 @@ dir = 1 }, /area/station/hallway/secondary/exit/departure_lounge) -"gHF" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/red/line{ - dir = 1 - }, -/obj/effect/turf_decal/trimline/red/line, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) "gHN" = ( /obj/effect/turf_decal/trimline/green/filled/corner{ dir = 1 @@ -24058,11 +23835,6 @@ /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) -"gJI" = ( -/mob/living/simple_animal/bot/secbot/beepsky/armsky, -/obj/machinery/airalarm/directional/east, -/turf/open/floor/iron/dark/textured, -/area/station/security/armory) "gJK" = ( /obj/effect/spawner/structure/window/hollow/reinforced/middle{ dir = 4 @@ -24227,6 +23999,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/wood, /area/station/commons/vacant_room/office) +"gMJ" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/rack, +/obj/item/door_seal, +/obj/item/door_seal, +/obj/item/door_seal, +/turf/open/floor/plating, +/area/station/maintenance/department/security) "gMK" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -24294,6 +24075,17 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/aft/greater) +"gNV" = ( +/obj/machinery/camera/directional/south{ + c_tag = "Security - Visitation South"; + network = list("ss13","prison") + }, +/obj/machinery/airalarm/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, +/area/station/security/prison/visit) "gOa" = ( /obj/structure/cable, /obj/effect/turf_decal/box/red/corners{ @@ -24429,6 +24221,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/science/breakroom) +"gQc" = ( +/obj/machinery/door/poddoor/preopen{ + id = "lawyer_blast"; + name = "Privacy Door" + }, +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/firedoor, +/turf/open/floor/plating, +/area/station/security/prison/rec) "gQe" = ( /obj/structure/railing{ dir = 8 @@ -24467,15 +24268,6 @@ /obj/effect/turf_decal/tile/yellow/opposingcorners, /turf/open/floor/iron/white, /area/station/maintenance/port/fore) -"gQE" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/obj/effect/turf_decal/siding/wideplating/dark{ - dir = 10 - }, -/turf/open/floor/iron/dark/textured, -/area/station/security/prison/rec) "gQI" = ( /obj/machinery/door/airlock{ id_tag = "Dorm4"; @@ -24502,6 +24294,13 @@ /obj/effect/mapping_helpers/airlock/access/all/service/chapel_office, /turf/open/floor/iron/dark, /area/station/service/chapel/office) +"gQS" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/station/maintenance/department/security) "gRg" = ( /obj/machinery/light/small/directional/north, /obj/structure/window/reinforced/spawner/directional/east, @@ -24544,6 +24343,12 @@ }, /turf/open/floor/iron, /area/station/engineering/engine_smes) +"gRw" = ( +/obj/effect/turf_decal/tile/red/half/contrasted, +/obj/machinery/airalarm/directional/east, +/obj/item/kirbyplants/random, +/turf/open/floor/iron, +/area/station/security/brig/upper) "gRA" = ( /obj/effect/turf_decal/trimline/purple/filled/warning{ dir = 8 @@ -24576,6 +24381,16 @@ /obj/effect/decal/cleanable/blood/oil, /turf/open/floor/iron/dark/textured_large, /area/station/cargo/bitrunning/den) +"gSj" = ( +/obj/structure/table, +/obj/item/radio/off, +/obj/item/screwdriver{ + pixel_y = 5 + }, +/turf/open/floor/iron/dark/textured_half{ + dir = 1 + }, +/area/station/security/office) "gSl" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 9 @@ -24657,6 +24472,11 @@ /obj/structure/closet/crate, /turf/open/floor/plating, /area/station/construction) +"gTh" = ( +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/tile/purple/half/contrasted, +/turf/open/floor/iron/white, +/area/station/science/genetics) "gTi" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, /obj/effect/decal/cleanable/dirt, @@ -24746,18 +24566,6 @@ /obj/item/trash/sosjerky, /turf/open/floor/plating, /area/station/maintenance/fore) -"gUs" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red/anticorner/contrasted, -/turf/open/floor/iron/dark/corner{ - dir = 1 - }, -/area/station/security/processing) "gUv" = ( /obj/machinery/holopad, /obj/effect/spawner/random/engineering/tracking_beacon, @@ -24807,6 +24615,13 @@ /obj/effect/turf_decal/bot, /turf/open/floor/iron/large, /area/station/engineering/storage/tech) +"gVr" = ( +/obj/structure/chair{ + dir = 8 + }, +/obj/item/radio/intercom/interrogation/inside/directional/east, +/turf/open/floor/iron/dark, +/area/station/security/interrogation) "gVt" = ( /obj/item/radio/intercom/directional/west, /obj/effect/turf_decal/tile/red{ @@ -24891,6 +24706,11 @@ /obj/effect/turf_decal/bot, /turf/open/floor/iron/dark, /area/station/engineering/circuit_workshop) +"gWe" = ( +/obj/structure/chair/stool/directional/east, +/obj/structure/cable, +/turf/open/floor/iron/dark, +/area/station/security/execution/education) "gWf" = ( /obj/item/storage/box/lights/mixed, /obj/structure/table, @@ -24945,6 +24765,23 @@ }, /turf/open/floor/iron/dark, /area/station/security/checkpoint/engineering) +"gWO" = ( +/obj/structure/table, +/obj/item/reagent_containers/condiment/peppermill{ + pixel_x = 3 + }, +/obj/item/reagent_containers/condiment/saltshaker{ + pixel_x = -3; + pixel_y = 5 + }, +/turf/open/floor/iron, +/area/mine/laborcamp) +"gWU" = ( +/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/fore) "gWV" = ( /obj/structure/chair/stool/directional/north, /obj/effect/decal/cleanable/dirt/dust, @@ -25016,21 +24853,17 @@ /obj/machinery/airalarm/directional/south, /turf/open/floor/plating, /area/station/maintenance/port/greater) -"gXy" = ( -/obj/machinery/door/airlock/public/glass{ - id_tag = "gulag2"; - name = "Cell 2" - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/mine/laborcamp) "gXD" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/mine/eva) +"gXF" = ( +/obj/structure/sign/departments/genetics/directional/north, +/obj/structure/chair/stool/directional/west, +/obj/effect/landmark/start/geneticist, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "gXJ" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -25126,6 +24959,11 @@ }, /turf/open/floor/iron/grimy, /area/station/service/theater) +"gYy" = ( +/obj/machinery/processor, +/obj/structure/table, +/turf/open/floor/iron/kitchen_coldroom/freezerfloor, +/area/station/security/prison/mess) "gYz" = ( /obj/structure/table/wood, /obj/item/paper_bin{ @@ -25239,14 +25077,6 @@ }, /turf/open/floor/engine, /area/station/engineering/supermatter/room) -"han" = ( -/obj/structure/table, -/obj/item/plate, -/obj/item/kitchen/fork, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron, -/area/mine/laborcamp) "hap" = ( /turf/open/floor/vault, /area/station/security/prison/rec) @@ -25291,14 +25121,6 @@ /obj/effect/turf_decal/siding/white, /turf/open/floor/iron/white/smooth_large, /area/station/service/kitchen) -"haX" = ( -/obj/structure/cable, -/obj/structure/table/glass, -/obj/item/stack/medical/wrap/sticky_tape/surgical, -/obj/item/stack/medical/bone_gel, -/obj/effect/turf_decal/tile/blue/half/contrasted, -/turf/open/floor/iron/white, -/area/station/medical/surgery/fore) "hbt" = ( /obj/effect/decal/cleanable/cobweb, /obj/effect/spawner/random/clothing/mafia_outfit, @@ -25411,14 +25233,6 @@ /obj/structure/reagent_dispensers/fueltank, /turf/open/floor/plating, /area/station/maintenance/port/fore) -"hdn" = ( -/obj/structure/cable, -/obj/effect/turf_decal/tile/red/half/contrasted{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/dark/textured, -/area/station/security/office) "hdp" = ( /obj/effect/turf_decal/stripes/asteroid/line{ dir = 10 @@ -25440,17 +25254,6 @@ }, /turf/open/floor/iron/white, /area/station/science/xenobiology) -"hdV" = ( -/obj/structure/table, -/obj/item/reagent_containers/condiment/saltshaker{ - pixel_x = -3; - pixel_y = 5 - }, -/obj/item/reagent_containers/condiment/peppermill{ - pixel_x = 3 - }, -/turf/open/floor/iron, -/area/mine/laborcamp) "heg" = ( /obj/effect/spawner/random/engineering/canister, /turf/open/floor/plating, @@ -25487,6 +25290,11 @@ }, /turf/open/floor/plating/snowed/icemoon, /area/icemoon/surface/outdoors/less_spawns) +"heL" = ( +/obj/effect/spawner/structure/window/hollow/reinforced/middle, +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/security/prison/safe) "heX" = ( /obj/structure/cable, /turf/open/floor/wood, @@ -25521,13 +25329,6 @@ /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/iron/textured, /area/station/maintenance/starboard/fore) -"hfo" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 8 - }, -/obj/machinery/status_display/evac/directional/east, -/turf/open/floor/iron/smooth, -/area/station/engineering/lobby) "hfs" = ( /obj/structure/table/wood, /obj/effect/turf_decal/siding/wood, @@ -25535,12 +25336,6 @@ /obj/item/instrument/harmonica, /turf/open/floor/iron/grimy, /area/station/commons/lounge) -"hfv" = ( -/obj/machinery/processor{ - pixel_y = 6 - }, -/turf/open/floor/iron/showroomfloor, -/area/station/security/prison/mess) "hfy" = ( /obj/structure/window/reinforced/spawner/directional/north, /obj/structure/window/reinforced/spawner/directional/west, @@ -25551,16 +25346,10 @@ }, /turf/open/floor/circuit, /area/station/ai/satellite/chamber) -"hfA" = ( -/obj/structure/window/reinforced/spawner/directional/north{ - pixel_y = 2 - }, -/obj/structure/chair{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron/smooth, -/area/station/security/holding_cell) +"hfz" = ( +/obj/structure/table, +/turf/open/floor/iron/kitchen_coldroom/freezerfloor, +/area/station/security/prison/mess) "hgc" = ( /obj/structure/table, /turf/open/floor/plating, @@ -25568,6 +25357,24 @@ "hgh" = ( /turf/closed/wall, /area/station/medical/medbay/lobby) +"hgi" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/light/small/directional/east, +/obj/machinery/camera/directional/east{ + c_tag = "Mining Ore Smeltery"; + network = list("ss13", "mine") + }, +/obj/machinery/conveyor{ + dir = 10; + id = "mining_internal" + }, +/turf/open/floor/iron, +/area/mine/production) "hgr" = ( /turf/open/floor/glass/reinforced, /area/station/hallway/secondary/entry) @@ -25642,6 +25449,12 @@ dir = 1 }, /area/station/service/chapel/office) +"hhE" = ( +/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/sepia, +/area/station/security/prison/rec) "hhO" = ( /obj/structure/table/reinforced, /obj/machinery/door/firedoor, @@ -25733,6 +25546,22 @@ }, /turf/open/floor/iron, /area/station/science/explab) +"hjq" = ( +/obj/structure/cable, +/obj/effect/turf_decal/siding/dark_red, +/obj/effect/turf_decal/siding/dark_red{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear{ + dir = 1 + }, +/obj/machinery/door/poddoor/shutters/window{ + name = "Security Mech Bay Shutters"; + id = "secmechbay"; + dir = 1 + }, +/turf/open/floor/iron/dark/textured_half, +/area/station/security/mechbay) "hjt" = ( /obj/effect/spawner/random/trash/grille_or_waste, /turf/open/floor/plating, @@ -25774,12 +25603,6 @@ "hjM" = ( /turf/closed/wall/r_wall, /area/station/maintenance/department/medical/morgue) -"hjQ" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/turf/open/floor/sepia, -/area/station/security/prison/rec) "hjR" = ( /obj/machinery/atmospherics/pipe/smart/simple/scrubbers/hidden, /obj/effect/spawner/structure/window/reinforced, @@ -25864,16 +25687,6 @@ }, /turf/open/floor/iron, /area/station/cargo/office) -"hkY" = ( -/obj/structure/table, -/obj/machinery/recharger, -/obj/machinery/light_switch/directional/east, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/turf/open/floor/iron/smooth_edge{ - dir = 1 - }, -/area/station/security/lockers) "hll" = ( /obj/structure/cable, /turf/open/floor/plating, @@ -25909,12 +25722,6 @@ /obj/item/bikehorn/rubberducky, /turf/open/floor/iron/freezer, /area/station/commons/toilet/locker) -"hlE" = ( -/obj/machinery/portable_atmospherics/canister/oxygen, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/light/small/directional/west, -/turf/open/floor/iron, -/area/mine/laborcamp) "hmb" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -25966,18 +25773,6 @@ dir = 8 }, /area/station/commons/storage/mining) -"hmA" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red/anticorner/contrasted{ - dir = 8 - }, -/obj/machinery/light/small/directional/south, -/obj/machinery/newscaster/directional/south, -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/security/prison/visit) "hmE" = ( /obj/structure/chair, /obj/effect/turf_decal/tile/blue/half/contrasted{ @@ -26024,6 +25819,13 @@ }, /turf/open/floor/iron, /area/station/cargo/lobby) +"hnM" = ( +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 8 + }, +/obj/item/radio/intercom/directional/west, +/turf/open/floor/iron, +/area/station/security/brig/upper) "hnN" = ( /obj/machinery/camera/directional/west{ c_tag = "Xenobiology Pens Observation - Port Aft"; @@ -26114,6 +25916,12 @@ /obj/machinery/atmospherics/pipe/bridge_pipe/green/visible, /turf/open/floor/plating, /area/station/engineering/atmos/pumproom) +"hoX" = ( +/obj/effect/turf_decal/tile/red/anticorner/contrasted{ + dir = 1 + }, +/turf/open/floor/iron/dark/textured, +/area/station/security/armory/upper) "hoZ" = ( /obj/effect/spawner/random/entertainment/arcade{ dir = 4 @@ -26139,11 +25947,6 @@ /obj/machinery/light/small/dim/directional/south, /turf/open/floor/iron/dark/textured, /area/station/maintenance/starboard/lesser) -"hpl" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/light/small/directional/north, -/turf/open/floor/iron, -/area/mine/laborcamp) "hpm" = ( /obj/machinery/camera/directional/north{ c_tag = "Starboard Primary Hallway East" @@ -26153,6 +25956,15 @@ dir = 4 }, /area/station/hallway/primary/starboard) +"hpn" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/chair/pew{ + dir = 8 + }, +/turf/open/floor/wood/large, +/area/station/security/prison/rec) "hpp" = ( /obj/structure/sign/departments/chemistry/directional/south, /obj/effect/turf_decal/trimline/blue/filled/warning{ @@ -26247,13 +26059,6 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron/dark, /area/station/science/genetics) -"hqi" = ( -/obj/machinery/door/window/brigdoor/left/directional/north{ - name = "Security Delivery"; - req_access = list("brig") - }, -/turf/open/floor/plating, -/area/station/security/processing) "hqm" = ( /obj/structure/table, /obj/item/storage/crayons, @@ -26268,6 +26073,10 @@ dir = 1 }, /area/station/commons/storage/art) +"hqo" = ( +/obj/structure/chair/stool/directional/north, +/turf/open/floor/iron, +/area/mine/laborcamp) "hqx" = ( /obj/effect/landmark/start/assistant, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -26329,6 +26138,24 @@ /obj/effect/turf_decal/tile/red/anticorner/contrasted, /turf/open/floor/iron/dark, /area/station/security/checkpoint/engineering) +"hrA" = ( +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 4 + }, +/turf/open/floor/iron/smooth, +/area/station/security/brig/upper) +"hrE" = ( +/obj/effect/turf_decal/stripes/red/line{ + dir = 8 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/surface/outdoors/nospawn) "hrS" = ( /obj/item/trash/raisins, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -26344,19 +26171,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/virology) -"hsb" = ( -/obj/structure/cable, -/obj/structure/table/glass, -/obj/item/stack/medical/wrap/sticky_tape/surgical, -/obj/item/stack/medical/bone_gel, -/obj/effect/turf_decal/tile/blue/half/contrasted, -/obj/machinery/camera/directional/south{ - c_tag = "Surgery B"; - network = list("ss13","medbay") - }, -/obj/machinery/newscaster/directional/south, -/turf/open/floor/iron/white, -/area/station/medical/surgery/aft) "hsh" = ( /obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, @@ -26378,12 +26192,6 @@ /obj/effect/turf_decal/weather/snow, /turf/open/floor/plating/icemoon, /area/icemoon/surface/outdoors/less_spawns) -"hsr" = ( -/obj/structure/table/wood, -/obj/item/newspaper, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/wood, -/area/station/security/prison/rec) "hsy" = ( /obj/effect/turf_decal/stripes/asteroid/line{ dir = 1 @@ -26504,6 +26312,10 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/carpet, /area/station/command/meeting_room) +"huf" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/turf/open/floor/iron/dark/side, +/area/station/security/range) "hui" = ( /obj/effect/landmark/generic_maintenance_landmark, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -26627,6 +26439,15 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/cargo/drone_bay) +"hwf" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/security/prison/mess) "hwm" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 1 @@ -26669,26 +26490,23 @@ }, /turf/open/floor/iron, /area/station/cargo/office) -"hwR" = ( -/obj/machinery/camera/directional/west{ - c_tag = "Security - Equipment Room" +"hwJ" = ( +/obj/structure/cable, +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 6 }, -/obj/structure/reagent_dispensers/wall/peppertank/directional/west, -/turf/open/floor/glass/reinforced, -/area/station/security/lockers) +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron/dark/side{ + dir = 6 + }, +/area/mine/laborcamp/security) "hwW" = ( /obj/machinery/light_switch/directional/south{ pixel_x = -9 }, /turf/open/floor/iron/dark, /area/station/service/chapel/office) -"hwZ" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment, -/turf/open/floor/iron, -/area/station/security/brig/upper) "hxa" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -26972,13 +26790,6 @@ }, /turf/open/floor/iron, /area/station/security/brig/upper) -"hAQ" = ( -/obj/item/kirbyplants/random, -/obj/effect/turf_decal/tile/red/anticorner/contrasted{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/security/brig/upper) "hAT" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -27029,10 +26840,6 @@ /obj/effect/decal/cleanable/blood/old, /turf/open/floor/iron, /area/station/maintenance/starboard/fore) -"hBB" = ( -/obj/effect/spawner/random/structure/girder, -/turf/open/floor/plating, -/area/station/security/prison/safe) "hBE" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/camera/directional/west{ @@ -27042,12 +26849,6 @@ /obj/machinery/firealarm/directional/west, /turf/open/floor/iron, /area/station/maintenance/disposal/incinerator) -"hBF" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/station/security/prison/workout) "hBG" = ( /obj/effect/turf_decal/siding/green{ dir = 8 @@ -27072,13 +26873,6 @@ dir = 4 }, /area/mine/eva) -"hCv" = ( -/obj/structure/table, -/obj/item/storage/bag/tray, -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable, -/turf/open/floor/iron/cafeteria, -/area/station/security/prison/mess) "hCC" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 1 @@ -27092,6 +26886,18 @@ /obj/structure/cable, /turf/open/floor/catwalk_floor/iron_smooth, /area/station/commons/storage/mining) +"hCK" = ( +/obj/effect/turf_decal/stripes/red/corner, +/obj/effect/turf_decal/stripes/red/corner{ + dir = 8 + }, +/obj/machinery/door/poddoor/shutters/window/preopen{ + name = "Firing Range Shutters"; + dir = 1; + id = "firingrangeshuttersoutside" + }, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/surface/outdoors/nospawn) "hCV" = ( /obj/structure/table/wood, /obj/item/hand_tele{ @@ -27203,16 +27009,20 @@ "hDU" = ( /turf/closed/wall/r_wall, /area/station/command/gateway) -"hDV" = ( -/obj/structure/plasticflaps, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/plating, -/area/station/maintenance/fore) "hEm" = ( /obj/structure/closet/emcloset, /turf/open/floor/iron/dark, /area/mine/eva) +"hEs" = ( +/obj/effect/turf_decal/tile/red/half/contrasted, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 1 + }, +/obj/structure/sign/poster/official/random/directional/south, +/turf/open/floor/iron/dark/textured_edge{ + dir = 1 + }, +/area/station/security/prison) "hEv" = ( /obj/structure/chair/stool/directional/west, /obj/effect/spawner/random/trash/cigbutt, @@ -27280,14 +27090,6 @@ /obj/structure/grille/broken, /turf/open/floor/plating, /area/station/maintenance/fore) -"hFC" = ( -/obj/structure/window/reinforced/spawner/directional/north{ - pixel_y = 2 - }, -/obj/structure/rack, -/obj/item/storage/crayons, -/turf/open/floor/iron, -/area/station/security/processing) "hFD" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, @@ -27473,6 +27275,18 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/command/heads_quarters/hos) +"hIQ" = ( +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 1 + }, +/obj/structure/extinguisher_cabinet/directional/north, +/turf/open/floor/iron, +/area/station/security/brig/upper) +"hIR" = ( +/obj/structure/flora/grass/green/style_random, +/obj/structure/sign/warning/directional/south, +/turf/open/misc/asteroid/snow/icemoon, +/area/icemoon/surface/outdoors/nospawn) "hIT" = ( /obj/machinery/door/airlock{ id_tag = "Toilet1"; @@ -27499,12 +27313,6 @@ /obj/structure/sign/calendar/directional/north, /turf/open/floor/iron, /area/station/commons/dorms/laundry) -"hJe" = ( -/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/fore) "hJi" = ( /obj/machinery/door/window/left/directional/east{ name = "Containment Pen 6"; @@ -27579,6 +27387,15 @@ dir = 8 }, /area/station/engineering/lobby) +"hKr" = ( +/obj/machinery/door/window/brigdoor/left/directional/north{ + req_access = list("security"); + name = "Firing Range Access" + }, +/turf/open/floor/iron/dark/side{ + dir = 1 + }, +/area/station/security/range) "hKu" = ( /obj/structure/sign/poster/official/cleanliness/directional/east, /obj/structure/closet/secure_closet/medical2, @@ -27603,32 +27420,27 @@ /obj/structure/plasticflaps/opaque, /turf/open/floor/iron/dark, /area/station/maintenance/department/medical/central) -"hLf" = ( -/obj/machinery/door/firedoor/border_only{ - dir = 8 - }, -/obj/effect/turf_decal/tile/red/half/contrasted, -/turf/open/floor/iron, -/area/station/security/brig/upper) -"hLk" = ( -/obj/structure/table, -/obj/item/paper, -/obj/item/pen, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/camera/directional/west{ - c_tag = "Labor Camp Cell 2"; - network = list("labor") - }, -/obj/machinery/flasher/directional/west{ - id = "GulagCell 2" - }, -/turf/open/floor/iron, -/area/mine/laborcamp) +"hLb" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/mapping_helpers/turn_off_lights_with_lightswitch, +/obj/structure/cable, +/turf/open/floor/iron/dark, +/area/station/security/mechbay) "hLw" = ( /obj/structure/flora/grass/both/style_3, /obj/structure/sign/warning/electric_shock/directional/north, /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/surface/outdoors/nospawn) +"hLH" = ( +/obj/structure/cable, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/station/security/prison/mess) "hLS" = ( /obj/machinery/computer/atmos_control/nitrous_tank{ dir = 8 @@ -27666,12 +27478,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/carpet, /area/station/service/chapel) -"hMv" = ( -/obj/structure/railing{ - dir = 4 - }, -/turf/open/floor/plating/snowed/smoothed/icemoon, -/area/icemoon/underground/explored) "hMw" = ( /obj/structure/bookcase/random/fiction, /turf/open/floor/plating, @@ -27714,13 +27520,6 @@ }, /turf/open/floor/iron/dark, /area/station/medical/paramedic) -"hMJ" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 1 - }, -/turf/open/floor/iron/smooth, -/area/mine/laborcamp/security) "hMM" = ( /obj/structure/marker_beacon/burgundy, /obj/effect/turf_decal/weather/snow/corner{ @@ -27732,14 +27531,6 @@ /obj/structure/sign/warning/xeno_mining/directional/east, /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/surface/outdoors/less_spawns) -"hMS" = ( -/obj/machinery/light/small/directional/south, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 4 - }, -/obj/effect/turf_decal/trimline/red/filled/line, -/turf/open/floor/iron/white, -/area/station/security/prison/safe) "hMZ" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -27776,6 +27567,16 @@ /obj/structure/railing, /turf/open/floor/iron/white, /area/station/medical/chemistry) +"hNs" = ( +/obj/structure/window/reinforced/spawner/directional/east{ + pixel_x = 3 + }, +/obj/structure/steps{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/red/line, +/turf/open/floor/iron/dark/textured, +/area/station/security/range) "hNx" = ( /obj/machinery/camera/directional/south{ c_tag = "Holodeck - South"; @@ -27899,16 +27700,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/command/vault) -"hPk" = ( -/obj/machinery/door/airlock/security{ - name = "Permabrig Chapel" - }, -/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, -/turf/open/floor/wood, -/area/station/security/prison/rec) "hPs" = ( /turf/closed/wall/r_wall, /area/station/security/prison/work) @@ -27982,18 +27773,18 @@ }, /turf/open/floor/plating, /area/station/maintenance/port/fore) -"hQi" = ( -/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/security/brig/upper) "hQj" = ( /obj/structure/filingcabinet/chestdrawer, /obj/machinery/light/small/directional/south, /obj/machinery/status_display/evac/directional/south, /turf/open/floor/iron, /area/station/tcommsat/computer) +"hQl" = ( +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 4 + }, +/turf/open/floor/iron/dark/textured, +/area/station/security/prison) "hQt" = ( /obj/structure/cable, /obj/effect/spawner/structure/window/hollow/reinforced/middle{ @@ -28025,13 +27816,6 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/aft/greater) -"hQP" = ( -/obj/structure/cable, -/obj/machinery/airalarm/directional/east, -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/tile/red/half, -/turf/open/floor/iron/smooth_half, -/area/station/security/brig/upper) "hQQ" = ( /obj/docking_port/stationary/escape_pod{ dir = 4 @@ -28056,6 +27840,10 @@ "hRA" = ( /turf/closed/wall, /area/station/medical/psychology) +"hRB" = ( +/obj/structure/cable/multilayer/multiz, +/turf/open/floor/plating, +/area/station/maintenance/department/security) "hRC" = ( /obj/machinery/door/window/left/directional/east{ name = "Test Chamber"; @@ -28127,6 +27915,15 @@ /obj/structure/railing/corner, /turf/open/floor/iron, /area/mine/eva) +"hSi" = ( +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/security/brig/upper) "hSm" = ( /obj/structure/table, /obj/item/paper/crumpled{ @@ -28168,14 +27965,13 @@ }, /turf/open/floor/plating, /area/station/medical/virology) -"hSJ" = ( -/obj/structure/chair/comfy{ - dir = 8 +"hSM" = ( +/obj/effect/turf_decal/loading_area{ + dir = 1 }, -/obj/machinery/light/directional/east, -/obj/machinery/newscaster/directional/south, +/obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, -/area/station/security/processing) +/area/mine/laborcamp) "hSZ" = ( /obj/structure/cable, /obj/effect/turf_decal/trimline/dark_blue/line{ @@ -28360,6 +28156,16 @@ /obj/structure/table, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) +"hVt" = ( +/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, +/obj/effect/spawner/random/trash/cigbutt, +/turf/open/floor/plating, +/area/station/maintenance/fore) "hVu" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -28372,10 +28178,6 @@ /obj/structure/closet/crate, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) -"hVB" = ( -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron/dark, -/area/mine/laborcamp) "hVI" = ( /obj/structure/reagent_dispensers/watertank, /obj/machinery/firealarm/directional/west, @@ -28436,6 +28238,14 @@ /obj/structure/window/reinforced/spawner/directional/north, /turf/open/floor/iron, /area/station/science/xenobiology) +"hWv" = ( +/obj/structure/curtain/cloth, +/obj/effect/turf_decal/siding/dark{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/showroomfloor, +/area/mine/laborcamp) "hWz" = ( /obj/machinery/camera/directional/south{ c_tag = "Ordnance Lower Mix Lab"; @@ -28473,17 +28283,20 @@ /obj/structure/extinguisher_cabinet/directional/west, /turf/open/floor/plating, /area/station/medical/virology) -"hXC" = ( -/obj/structure/chair{ - dir = 8 +"hXe" = ( +/obj/structure/steps{ + dir = 1 }, -/obj/item/radio/intercom/directional/east, -/obj/effect/landmark/start/hangover, -/obj/effect/turf_decal/tile/purple/half/contrasted{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/hallway/primary/starboard) +/obj/effect/turf_decal/stripes/red/line, +/turf/open/floor/iron/dark/textured, +/area/station/security/range) +"hXg" = ( +/obj/machinery/holopad, +/obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/turf/open/floor/iron/dark, +/area/station/engineering/circuit_workshop) "hXE" = ( /obj/effect/turf_decal/tile/blue/full, /obj/machinery/suit_storage_unit/medical, @@ -28491,6 +28304,11 @@ /obj/machinery/firealarm/directional/east, /turf/open/floor/iron/dark/smooth_large, /area/station/medical/paramedic) +"hXL" = ( +/obj/structure/closet/secure_closet/freezer/kitchen/maintenance, +/obj/effect/spawner/random/contraband/prison, +/turf/open/floor/iron/kitchen_coldroom/freezerfloor, +/area/station/security/prison/mess) "hXU" = ( /obj/machinery/newscaster/directional/east, /obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible, @@ -28516,14 +28334,6 @@ /obj/effect/mapping_helpers/airlock/access/any/service/maintenance, /turf/open/floor/plating, /area/station/maintenance/port/aft) -"hYy" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/obj/machinery/airalarm/directional/west, -/obj/item/kirbyplants/random, -/turf/open/floor/wood, -/area/station/security/prison/rec) "hYD" = ( /obj/effect/turf_decal/tile/neutral/half/contrasted{ dir = 8 @@ -28577,6 +28387,11 @@ /obj/structure/sign/poster/official/help_others/directional/north, /turf/open/openspace/icemoon/keep_below, /area/icemoon/underground/explored) +"hYN" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/machinery/firealarm/directional/west, +/turf/open/floor/iron/smooth, +/area/station/security/eva) "hYP" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -28589,6 +28404,12 @@ }, /turf/open/floor/plating/snowed/icemoon, /area/icemoon/underground/explored) +"hYQ" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/wood/large, +/area/station/command/heads_quarters/hos) "hZb" = ( /obj/structure/curtain/cloth/fancy/mechanical/start_closed{ id = "cantena_curtains" @@ -28705,11 +28526,6 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/science/xenobiology) -"iav" = ( -/obj/structure/closet/secure_closet/labor_camp_security, -/obj/effect/turf_decal/tile/red/half/contrasted, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "iay" = ( /obj/effect/spawner/random/engineering/tracking_beacon, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -28827,17 +28643,13 @@ }, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) -"ibz" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/table/wood, -/obj/effect/spawner/random/entertainment/gambling, -/obj/effect/turf_decal/siding/wood{ - dir = 1 +"ibJ" = ( +/obj/item/radio/intercom/directional/east, +/obj/effect/spawner/random/entertainment/slot_machine{ + name = "two-armed bandit" }, -/turf/open/floor/wood, -/area/station/security/prison/rec) +/turf/open/floor/wood/large, +/area/station/commons/lounge) "ibM" = ( /obj/effect/spawner/structure/window/hollow/reinforced/middle{ dir = 4 @@ -28912,19 +28724,11 @@ }, /turf/open/floor/iron, /area/station/maintenance/disposal/incinerator) -"icQ" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron, -/area/station/security/prison/visit) -"icS" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/obj/effect/turf_decal/trimline/red/line{ - dir = 8 - }, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) +"icJ" = ( +/obj/structure/tank_holder/oxygen, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, +/turf/open/floor/vault, +/area/station/security/prison/rec) "icU" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -28984,17 +28788,6 @@ /obj/effect/spawner/random/trash/mess, /turf/open/floor/plating, /area/station/maintenance/starboard/upper) -"idv" = ( -/obj/structure/chair{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/light/small/directional/west, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/turf/open/floor/iron/smooth, -/area/station/security/holding_cell) "idI" = ( /turf/open/floor/stone, /area/station/commons/lounge) @@ -29059,14 +28852,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/starboard) -"ifa" = ( -/obj/structure/chair/comfy/brown{ - dir = 8 - }, -/obj/structure/cable, -/obj/effect/turf_decal/tile/red/half/contrasted, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "ife" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -29136,10 +28921,6 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos) -"igB" = ( -/obj/machinery/firealarm/directional/west, -/turf/open/floor/glass, -/area/station/security/lockers) "igG" = ( /obj/structure/sign/warning/cold_temp/directional/north, /obj/structure/closet/emcloset/anchored, @@ -29168,13 +28949,6 @@ /obj/structure/rack, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) -"ihb" = ( -/obj/structure/chair{ - dir = 8 - }, -/obj/machinery/firealarm/directional/east, -/turf/open/floor/iron/dark, -/area/station/security/interrogation) "ihc" = ( /obj/effect/decal/cleanable/dirt/dust, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -29225,6 +28999,30 @@ /obj/structure/cable, /turf/open/floor/iron/dark/textured, /area/station/security/execution/transfer) +"ihS" = ( +/obj/machinery/light/small/directional/south, +/obj/structure/closet/secure_closet/brig{ + id = "Cell 1"; + name = "Cell 1 locker" + }, +/obj/structure/cable, +/obj/machinery/flasher/directional/south{ + id = "Cell 1" + }, +/turf/open/floor/iron/smooth, +/area/station/security/brig) +"iie" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Equipment Room"; + security_level = 1 + }, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/access/all/security/brig, +/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_edge, +/area/station/security/lockers) "iih" = ( /obj/effect/spawner/xmastree, /obj/effect/turf_decal/tile/neutral{ @@ -29388,13 +29186,6 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/iron, /area/station/engineering/engine_smes) -"ikb" = ( -/obj/item/door_seal, -/obj/item/door_seal, -/obj/item/door_seal, -/obj/structure/rack, -/turf/open/floor/plating, -/area/station/security/prison/safe) "ikd" = ( /obj/structure/extinguisher_cabinet/directional/east, /obj/effect/turf_decal/stripes/asteroid/corner{ @@ -29448,18 +29239,6 @@ /obj/machinery/light/directional/east, /turf/open/floor/iron, /area/station/hallway/primary/central) -"ikI" = ( -/obj/item/gun/energy/laser/carbine/practice{ - pixel_y = 5 - }, -/obj/item/gun/energy/laser/practice, -/obj/item/gun/energy/laser/practice{ - pixel_y = -5 - }, -/obj/structure/rack, -/obj/structure/reagent_dispensers/wall/peppertank/directional/south, -/turf/open/floor/iron/dark/textured, -/area/station/security/office) "ikL" = ( /obj/machinery/status_display/ai/directional/west, /obj/effect/turf_decal/siding/wood{ @@ -29475,6 +29254,14 @@ }, /turf/open/floor/plating, /area/station/command/heads_quarters/qm) +"ikS" = ( +/obj/structure/cable, +/obj/structure/table/glass, +/obj/item/stack/medical/wrap/sticky_tape/surgical, +/obj/item/stack/medical/bone_gel, +/obj/effect/turf_decal/tile/blue/half/contrasted, +/turf/open/floor/iron/white, +/area/station/medical/surgery/fore) "ikW" = ( /obj/structure/railing/corner{ dir = 8 @@ -29559,6 +29346,20 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/science/robotics/mechbay) +"imq" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/light/small/directional/south, +/obj/structure/railing/corner/end{ + dir = 8 + }, +/obj/structure/railing/corner/end/flip{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/mine/production) "imH" = ( /obj/structure/rack, /obj/effect/spawner/random/clothing/gloves, @@ -29596,6 +29397,15 @@ }, /turf/open/floor/iron/dark, /area/station/commons/storage/mining) +"imY" = ( +/obj/machinery/door/airlock/security{ + name = "Permanent Cell 2" + }, +/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/textured, +/area/station/security/prison/safe) "ini" = ( /obj/structure/falsewall, /turf/open/floor/plating, @@ -29733,17 +29543,6 @@ /obj/structure/sign/departments/engineering/directional/south, /turf/open/floor/iron, /area/station/hallway/primary/central) -"ipd" = ( -/obj/machinery/light/small/directional/south, -/obj/machinery/camera/directional/south{ - c_tag = "Labor Camp Showers"; - network = list("labor") - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/turf/open/floor/iron/freezer, -/area/mine/laborcamp) "ipf" = ( /turf/open/genturf, /area/icemoon/underground/unexplored/rivers/deep/shoreline) @@ -29863,6 +29662,14 @@ dir = 8 }, /area/station/service/chapel) +"irU" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/firealarm/directional/east, +/obj/machinery/light/floor, +/turf/open/floor/iron/dark, +/area/station/security/prison/rec) "isb" = ( /obj/machinery/atmospherics/components/binary/pump/off{ dir = 1; @@ -29878,16 +29685,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/engineering/atmos/mix) -"isc" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/mineral/labor_points_checker{ - pixel_y = 25 - }, -/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/mine/laborcamp) "ise" = ( /obj/machinery/airalarm/directional/north, /turf/open/floor/iron, @@ -29997,12 +29794,23 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/iron, /area/station/command/heads_quarters/rd) +"itu" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light_switch/directional/north, +/obj/machinery/gizmo/toggle/tucker_tubes, +/turf/open/floor/iron, +/area/station/science/explab) "itE" = ( /obj/effect/turf_decal/weather/snow/corner{ dir = 10 }, /turf/open/floor/glass/reinforced/icemoon, /area/icemoon/surface/outdoors/nospawn) +"itH" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron/smooth, +/area/station/security/eva) "itN" = ( /obj/item/toy/snowball{ pixel_x = 6; @@ -30089,6 +29897,15 @@ /obj/machinery/airalarm/directional/north, /turf/open/floor/glass/reinforced, /area/station/security/armory/upper) +"iuW" = ( +/obj/effect/turf_decal/tile/red/half/contrasted, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 1 + }, +/turf/open/floor/iron/dark/textured_edge{ + dir = 1 + }, +/area/station/security/prison) "ivi" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/yellow, @@ -30106,20 +29923,11 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron, /area/station/hallway/primary/central) -"ivq" = ( -/obj/structure/cable, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/turf/open/floor/iron, -/area/mine/laborcamp/security) -"ivw" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/obj/machinery/newscaster/directional/north, -/turf/open/floor/iron, -/area/station/security/prison/visit) +"ivv" = ( +/obj/effect/turf_decal/stripes/line, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/underground/explored) "ivB" = ( /obj/structure/closet/emcloset, /turf/open/floor/iron, @@ -30269,13 +30077,6 @@ /obj/effect/turf_decal/tile/red/half/contrasted, /turf/open/floor/iron, /area/station/hallway/secondary/exit/departure_lounge) -"ixw" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 - }, -/turf/open/floor/sepia, -/area/station/security/prison/rec) "ixG" = ( /obj/effect/turf_decal/bot{ dir = 1 @@ -30294,6 +30095,13 @@ /obj/effect/mapping_helpers/airlock/access/all/science/ordnance, /turf/open/floor/iron/white, /area/station/science/ordnance/office) +"ixN" = ( +/obj/structure/chair/sofa/corp/right{ + dir = 8 + }, +/obj/effect/landmark/start/prisoner, +/turf/open/floor/carpet/blue, +/area/station/security/prison/work) "ixZ" = ( /obj/machinery/door/airlock/command/glass{ name = "Chief Engineer" @@ -30318,6 +30126,11 @@ }, /turf/open/floor/iron, /area/station/commons/fitness) +"iyp" = ( +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/power/port_gen/pacman/pre_loaded, +/turf/open/floor/plating, +/area/station/maintenance/fore) "iyE" = ( /obj/effect/spawner/structure/window/hollow/reinforced/end{ dir = 4 @@ -30357,10 +30170,6 @@ /obj/effect/spawner/structure/window/reinforced/tinted, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) -"izn" = ( -/obj/effect/spawner/random/decoration/generic, -/turf/open/floor/plating, -/area/station/security/prison) "izp" = ( /obj/structure/disposalpipe/segment{ dir = 10 @@ -30377,6 +30186,20 @@ /obj/effect/mapping_helpers/airlock/access/all/engineering/general, /turf/open/floor/plating, /area/station/maintenance/solars/port/fore) +"izz" = ( +/obj/structure/cable, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/door/poddoor/shutters/window{ + id = "labordoor"; + name = "Labor Camp Emergency Entrance Shutters" + }, +/obj/machinery/door/airlock/public/glass{ + name = "Labor Camp Emergency Entrance" + }, +/turf/open/floor/iron/textured, +/area/mine/laborcamp/security) "izA" = ( /obj/machinery/door/window/right/directional/west{ name = "Containment Pen 8"; @@ -30419,11 +30242,6 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating, /area/station/medical/chemistry) -"izY" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/station/security/prison/visit) "iAc" = ( /obj/effect/turf_decal/tile/yellow/half/contrasted{ dir = 8 @@ -30441,6 +30259,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/ai/satellite/interior) +"iAp" = ( +/obj/effect/mapping_helpers/broken_floor, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/fore) "iAu" = ( /obj/structure/closet/emcloset, /turf/open/floor/plating, @@ -30503,6 +30326,10 @@ /obj/effect/turf_decal/tile/blue/fourcorners, /turf/open/floor/iron/dark/textured, /area/station/medical/treatment_center) +"iBt" = ( +/obj/effect/turf_decal/bot, +/turf/open/floor/iron, +/area/mine/laborcamp) "iBF" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/disposalpipe/segment, @@ -30516,24 +30343,6 @@ dir = 4 }, /area/station/science/explab) -"iBZ" = ( -/obj/structure/table/glass, -/obj/item/book/manual/wiki/medicine{ - pixel_x = 1; - pixel_y = 5 - }, -/obj/item/book/manual/wiki/surgery{ - pixel_x = -4; - pixel_y = 3 - }, -/obj/effect/turf_decal/tile/blue/full, -/obj/item/tgui_book/manual/idc{ - pixel_y = 3; - pixel_x = 3 - }, -/obj/item/tgui_book/manual/dsm, -/turf/open/floor/iron/large, -/area/station/medical/treatment_center) "iCg" = ( /obj/effect/turf_decal/stripes/corner{ dir = 1 @@ -30598,6 +30407,15 @@ }, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) +"iCI" = ( +/obj/structure/closet/secure_closet/security/sec, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/turf_decal/bot, +/turf/open/floor/iron/smooth_edge{ + dir = 1 + }, +/area/station/security/lockers) "iCX" = ( /obj/machinery/power/solar_control{ dir = 4; @@ -30627,15 +30445,6 @@ "iDt" = ( /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/underground/explored) -"iDu" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 - }, -/obj/structure/cable, -/obj/machinery/power/apc/auto_name/directional/east, -/obj/item/kirbyplants/random, -/turf/open/floor/wood, -/area/station/security/prison/rec) "iDG" = ( /obj/machinery/door/window/left/directional/east{ name = "Containment Pen 3"; @@ -30652,6 +30461,16 @@ /obj/machinery/atmospherics/pipe/smart/simple/dark/visible, /turf/open/floor/iron, /area/station/maintenance/disposal/incinerator) +"iEd" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/trimline/red/warning{ + dir = 5 + }, +/obj/effect/turf_decal/stripes/red/line{ + dir = 10 + }, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/surface/outdoors/nospawn) "iEt" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -30674,16 +30493,6 @@ /obj/effect/turf_decal/tile/blue/full, /turf/open/floor/iron/large, /area/station/medical/treatment_center) -"iEN" = ( -/obj/structure/table, -/obj/item/electropack, -/obj/item/screwdriver, -/obj/item/wrench, -/obj/item/clothing/head/helmet, -/obj/item/assembly/signaler, -/obj/structure/cable, -/turf/open/floor/plating/icemoon, -/area/station/security/execution/education) "iEQ" = ( /obj/structure/chair{ pixel_y = -2 @@ -30771,17 +30580,12 @@ dir = 1 }, /area/station/hallway/secondary/entry) -"iGj" = ( +"iGn" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/door/airlock/security/glass{ - name = "Labor Camp Ultilities" - }, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/mapping_helpers/airlock/access/all/security/brig, -/obj/effect/turf_decal/tile/red/fourcorners, -/turf/open/floor/iron, -/area/mine/laborcamp/security) +/turf/open/floor/iron/dark, +/area/station/security/prison/rec) "iGH" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/disposalpipe/segment{ @@ -30830,12 +30634,26 @@ /obj/structure/cable, /turf/open/floor/carpet/red, /area/station/security/prison/work) +"iIa" = ( +/obj/machinery/door/airlock/public/glass{ + id_tag = "cellblock1"; + name = "Labor Camp Operations" + }, +/turf/open/floor/iron, +/area/mine/laborcamp) "iIe" = ( /obj/machinery/power/apc/auto_name/directional/west, /obj/structure/disposalpipe/segment, /obj/structure/cable, /turf/open/floor/iron/white, /area/station/science/robotics/lab) +"iIf" = ( +/obj/structure/table/wood, +/obj/item/pai_card, +/obj/effect/mapping_helpers/broken_floor, +/obj/effect/turf_decal/siding/wood, +/turf/open/floor/wood, +/area/station/maintenance/fore) "iIm" = ( /obj/effect/turf_decal/siding/wood{ dir = 4 @@ -30913,6 +30731,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/wood, /area/station/commons/vacant_room/office) +"iJu" = ( +/obj/structure/window/reinforced/spawner/directional/north, +/obj/structure/platform/iron, +/turf/open/floor/iron/dark/textured, +/area/station/security/range) "iJC" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 1 @@ -31021,11 +30844,23 @@ }, /turf/open/floor/iron/white, /area/station/medical/medbay/aft) +"iKn" = ( +/obj/effect/turf_decal/stripes/red/line, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/mine/laborcamp) "iKw" = ( /obj/item/kitchen/fork/plastic, /obj/structure/table, /turf/open/floor/iron, /area/station/security/prison/mess) +"iKx" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/security/brig/upper) "iKQ" = ( /obj/machinery/status_display/evac/directional/east, /turf/open/openspace, @@ -31046,6 +30881,12 @@ }, /turf/open/floor/plating, /area/station/maintenance/fore) +"iLb" = ( +/obj/machinery/camera/directional/west{ + c_tag = "Security - EVA Exterior" + }, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/surface/outdoors/nospawn) "iLf" = ( /obj/machinery/atmospherics/pipe/smart/simple/brown/visible, /turf/open/floor/iron, @@ -31076,27 +30917,6 @@ /obj/item/flashlight/lantern, /turf/open/floor/iron/dark, /area/station/service/chapel) -"iLv" = ( -/obj/item/book/manual/wiki/tcomms{ - pixel_x = 10; - pixel_y = -1 - }, -/obj/item/book/manual/wiki/ordnance{ - pixel_x = 10; - pixel_y = 3 - }, -/obj/item/book/manual/wiki/experimentor{ - pixel_x = 10; - pixel_y = 8 - }, -/obj/structure/table/wood, -/obj/item/book/manual/wiki/security_space_law{ - pixel_x = -7; - pixel_y = 5 - }, -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/security/processing) "iLy" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 8 @@ -31114,6 +30934,15 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/hallway/secondary/entry) +"iLD" = ( +/obj/effect/turf_decal/arrows/red, +/obj/effect/turf_decal/tile/blue/half{ + dir = 4 + }, +/turf/open/floor/iron/half{ + dir = 1 + }, +/area/station/hallway/primary/starboard) "iLE" = ( /obj/structure/railing{ dir = 1 @@ -31128,6 +30957,23 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/port/fore) +"iLR" = ( +/obj/structure/rack, +/obj/item/storage/bag/ore, +/obj/item/flashlight, +/obj/item/pickaxe, +/obj/item/clothing/glasses/meson, +/obj/item/mining_scanner, +/obj/effect/decal/cleanable/dirt, +/obj/item/clothing/suit/hooded/wintercoat, +/obj/machinery/camera/directional/east{ + c_tag = "Labor Camp - Hallway"; + network = list("labor","prison") + }, +/obj/item/clothing/mask/breath, +/obj/item/tank/internals/emergency_oxygen, +/turf/open/floor/iron, +/area/mine/laborcamp) "iLY" = ( /obj/machinery/atmospherics/pipe/heat_exchanging/simple{ dir = 4 @@ -31194,12 +31040,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/wood, /area/station/service/lawoffice) -"iME" = ( -/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/dark/textured, -/area/station/security/interrogation) "iMT" = ( /turf/open/floor/iron, /area/station/commons/storage/primary) @@ -31288,6 +31128,22 @@ }, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) +"iOe" = ( +/obj/machinery/light/small/directional/north, +/obj/structure/table, +/obj/item/electropack, +/obj/item/clothing/head/helmet, +/obj/item/wrench, +/obj/item/screwdriver, +/obj/item/assembly/signaler, +/obj/machinery/button/flasher{ + id = "executionflash"; + pixel_x = -6; + pixel_y = 24; + dir = 8 + }, +/turf/open/floor/iron/dark, +/area/station/security/execution/education) "iOh" = ( /obj/effect/turf_decal/weather/snow/corner{ dir = 8 @@ -31337,6 +31193,10 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/engineering/atmos/mix) +"iPd" = ( +/obj/machinery/status_display/ai/directional/west, +/turf/open/floor/iron/dark, +/area/station/security/range) "iPm" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -31435,6 +31295,17 @@ /obj/machinery/status_display/ai/directional/south, /turf/open/floor/iron, /area/station/cargo/miningdock) +"iQt" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/airalarm/directional/east, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/tile/purple/half/contrasted{ + dir = 1 + }, +/turf/open/floor/iron/white, +/area/station/science/genetics) "iQF" = ( /obj/effect/turf_decal/trimline/yellow/filled/line, /obj/machinery/airalarm/directional/south, @@ -31504,14 +31375,6 @@ "iRo" = ( /turf/closed/wall, /area/station/security/checkpoint/customs/auxiliary) -"iRp" = ( -/obj/machinery/conveyor{ - dir = 10; - id = "gulag" - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/mine/laborcamp) "iRr" = ( /obj/effect/landmark/start/depsec/engineering, /obj/structure/chair/office, @@ -31550,24 +31413,12 @@ }, /turf/open/floor/plating, /area/station/maintenance/port/aft) -"iRM" = ( -/obj/structure/rack, -/obj/item/stack/sheet/iron/twenty, -/obj/machinery/light/small/directional/south, -/turf/open/floor/iron/dark/textured, -/area/station/security/interrogation) "iRV" = ( /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/dark/textured, /area/station/security/prison) -"iSf" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/turf/open/floor/plating, -/area/mine/laborcamp/security) "iSl" = ( /obj/machinery/atmospherics/components/binary/pump{ name = "Mix to Port" @@ -31620,6 +31471,20 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/catwalk_floor/iron_smooth, /area/station/maintenance/port/fore) +"iTa" = ( +/obj/machinery/door/airlock/security{ + name = "Security Hallway" + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/access/all/security/general, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/iron/dark/textured, +/area/station/security/brig/upper) "iTb" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -31662,6 +31527,10 @@ /obj/machinery/light/small/directional/east, /turf/open/floor/engine/plasma, /area/station/engineering/atmos) +"iUg" = ( +/obj/structure/sign/nanotrasen/directional/east, +/turf/open/floor/wood, +/area/station/security/courtroom) "iUm" = ( /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/plating, @@ -31781,6 +31650,13 @@ }, /turf/open/floor/iron, /area/station/commons/storage/primary) +"iVs" = ( +/obj/machinery/power/apc/auto_name/directional/west, +/obj/structure/cable, +/obj/machinery/light/small/directional/west, +/obj/structure/closet, +/turf/open/floor/iron/dark/textured, +/area/station/security/prison/safe) "iVA" = ( /obj/effect/landmark/start/shaft_miner, /turf/open/floor/iron, @@ -31790,10 +31666,6 @@ /obj/structure/sign/poster/random/directional/north, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) -"iVN" = ( -/obj/machinery/vending/sustenance, -/turf/open/floor/iron/dark/textured, -/area/station/security/prison) "iVT" = ( /obj/machinery/computer/camera_advanced/xenobio, /turf/open/floor/iron, @@ -31817,6 +31689,14 @@ /obj/machinery/light/small/dim/directional/south, /turf/open/floor/plating, /area/station/maintenance/department/chapel) +"iWu" = ( +/obj/effect/landmark/event_spawn, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/holopad, +/turf/open/floor/wood/large, +/area/station/security/prison/rec) "iWA" = ( /obj/structure/closet, /obj/effect/spawner/random/clothing/gloves, @@ -31843,19 +31723,6 @@ /obj/machinery/light/directional/east, /turf/open/floor/iron/white, /area/station/medical/medbay/aft) -"iWS" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/door/window/brigdoor/left/directional/north{ - req_access = list("brig") - }, -/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/border_only{ - dir = 1 - }, -/turf/open/floor/iron/smooth, -/area/station/security/holding_cell) "iWW" = ( /turf/open/floor/iron/smooth, /area/station/engineering/lobby) @@ -31876,17 +31743,6 @@ }, /turf/open/floor/plating/snowed/icemoon, /area/icemoon/surface/outdoors/less_spawns) -"iXh" = ( -/obj/machinery/vending/cigarette, -/obj/machinery/firealarm/directional/east{ - pixel_y = 6 - }, -/obj/structure/cable, -/obj/machinery/light_switch/directional/east{ - pixel_y = -5 - }, -/turf/open/floor/iron, -/area/station/security/prison/visit) "iXk" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -31970,6 +31826,18 @@ /obj/structure/sign/warning/radiation/rad_area/directional/north, /turf/open/floor/iron/dark, /area/station/engineering/atmos/hfr_room) +"iYo" = ( +/obj/machinery/door/airlock/external{ + name = "Security External Access"; + security_level = 1 + }, +/obj/structure/cable, +/obj/effect/mapping_helpers/airlock/access/all/security/brig, +/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{ + cycle_id = "sec-external-upper" + }, +/turf/open/floor/iron/smooth, +/area/station/security/eva) "iYq" = ( /obj/structure/railing/corner{ dir = 4 @@ -32055,11 +31923,6 @@ /obj/machinery/electrolyzer, /turf/open/floor/iron, /area/station/maintenance/disposal/incinerator) -"iZs" = ( -/obj/structure/table, -/obj/item/kitchen/spoon/plastic, -/turf/open/floor/iron, -/area/station/security/prison/mess) "iZx" = ( /obj/machinery/portable_atmospherics/canister/anesthetic_mix, /obj/machinery/atmospherics/components/unary/portables_connector/visible{ @@ -32191,15 +32054,6 @@ }, /turf/open/floor/iron, /area/station/maintenance/disposal/incinerator) -"jaU" = ( -/obj/machinery/camera/directional/east{ - c_tag = "Service - Gambling Lounge" - }, -/obj/effect/spawner/random/entertainment/slot_machine{ - name = "two-armed bandit" - }, -/turf/open/floor/wood/large, -/area/station/commons/lounge) "jaW" = ( /obj/machinery/door/firedoor, /obj/effect/turf_decal/tile/red/half/contrasted, @@ -32223,22 +32077,10 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central) -"jbb" = ( -/obj/machinery/airalarm/directional/north, -/turf/open/floor/iron/dark/textured, -/area/station/security/prison/rec) "jbe" = ( /obj/structure/sign/warning/directional/north, /turf/open/openspace/icemoon/keep_below, /area/icemoon/surface/outdoors/nospawn) -"jbh" = ( -/obj/structure/closet/l3closet/janitor, -/obj/machinery/airalarm/directional/north, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/service/janitor) "jbj" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -32357,22 +32199,6 @@ }, /turf/open/floor/iron/grimy, /area/station/service/bar/backroom) -"jct" = ( -/obj/structure/disposalpipe/segment{ - dir = 10 - }, -/obj/machinery/camera/directional/north{ - c_tag = "Security - Upper Brig South" - }, -/obj/effect/turf_decal/tile/red/half/contrasted{ - dir = 1 - }, -/obj/structure/noticeboard/hos{ - pixel_y = 36; - dir = 1 - }, -/turf/open/floor/iron, -/area/station/security/brig/upper) "jcA" = ( /obj/machinery/light/small/directional/north, /obj/structure/sign/departments/cargo/directional/north, @@ -32405,11 +32231,6 @@ /obj/machinery/suit_storage_unit/captain, /turf/open/floor/wood, /area/station/command/heads_quarters/captain) -"jdf" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron, -/area/station/security/prison/mess) "jdA" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 4 @@ -32424,6 +32245,10 @@ }, /turf/open/floor/iron/white, /area/station/medical/medbay/aft) +"jdB" = ( +/obj/machinery/light/floor, +/turf/open/floor/iron/dark/side, +/area/station/security/range) "jdJ" = ( /obj/structure/chair/wood, /turf/open/floor/carpet, @@ -32487,6 +32312,17 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/tcommsat/computer) +"jem" = ( +/obj/effect/turf_decal/tile/blue/opposingcorners{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 1 + }, +/obj/structure/cable, +/turf/open/floor/iron/white, +/area/mine/laborcamp) "jer" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible{ dir = 8 @@ -32559,10 +32395,36 @@ /obj/machinery/light/small/dim/directional/south, /turf/open/floor/iron/dark, /area/station/medical/morgue) +"jfG" = ( +/obj/structure/table, +/obj/item/toy/cards/deck, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/mine/laborcamp) "jfR" = ( /obj/effect/turf_decal/stripes/line, /turf/open/floor/iron, /area/station/command/gateway) +"jfY" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/light_switch/directional/north{ + pixel_y = 28; + pixel_x = -4 + }, +/obj/machinery/button/door/directional/north{ + pixel_y = 32; + pixel_x = 24; + id = "secmechbaymaint"; + name = "Security Mech Garage Door Controls"; + req_access = list("security") + }, +/obj/machinery/firealarm/directional/north{ + pixel_x = 6 + }, +/turf/open/floor/iron/dark, +/area/station/security/mechbay) "jgl" = ( /obj/effect/turf_decal/trimline/dark_blue/corner{ dir = 1 @@ -32597,10 +32459,6 @@ /obj/effect/turf_decal/tile/yellow/opposingcorners, /turf/open/floor/iron/white, /area/station/maintenance/port/fore) -"jgG" = ( -/obj/structure/closet/secure_closet/security/sec, -/turf/open/floor/iron/smooth_edge, -/area/station/security/lockers) "jgL" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, @@ -32898,11 +32756,6 @@ /obj/item/radio/intercom/prison/directional/west, /turf/open/floor/iron, /area/station/security/prison/work) -"jlG" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/turf/open/floor/iron, -/area/mine/laborcamp) "jlJ" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating/icemoon, @@ -32922,21 +32775,6 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos) -"jlX" = ( -/obj/effect/turf_decal/stripes/red/line, -/obj/effect/turf_decal/trimline/red/line{ - dir = 1 - }, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) -"jmc" = ( -/obj/structure/table, -/obj/structure/bedsheetbin, -/obj/effect/turf_decal/tile/blue/opposingcorners{ - dir = 1 - }, -/turf/open/floor/iron/cafeteria, -/area/mine/laborcamp) "jms" = ( /obj/structure/cable, /obj/machinery/power/apc/auto_name/directional/west, @@ -32947,6 +32785,12 @@ /obj/structure/cable, /turf/open/floor/iron/white/textured, /area/station/security/medical) +"jmA" = ( +/obj/machinery/light/directional/north, +/obj/machinery/airalarm/directional/north, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/station/security/prison/visit) "jmC" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -33086,6 +32930,15 @@ /obj/machinery/power/apc/auto_name/directional/south, /turf/open/floor/plating, /area/station/maintenance/department/medical/morgue) +"joD" = ( +/obj/structure/closet/crate/bin, +/turf/open/floor/iron/dark/textured, +/area/station/security/interrogation) +"joP" = ( +/obj/machinery/firealarm/directional/west, +/obj/machinery/light/directional/west, +/turf/open/floor/glass, +/area/station/security/lockers) "jpd" = ( /obj/machinery/vending/coffee, /turf/open/floor/iron, @@ -33108,6 +32961,11 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/service/bar) +"jpn" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/turf/open/floor/iron, +/area/mine/laborcamp) "jpo" = ( /obj/machinery/door/poddoor/preopen{ id = "maint2" @@ -33139,11 +32997,6 @@ /obj/effect/spawner/structure/window/reinforced/tinted, /turf/open/floor/plating, /area/station/maintenance/port/lesser) -"jpE" = ( -/obj/structure/closet/l3closet/security, -/obj/machinery/airalarm/directional/north, -/turf/open/floor/iron/smooth, -/area/station/security/brig/upper) "jpH" = ( /obj/machinery/holopad/secure, /obj/effect/landmark/event_spawn, @@ -33197,25 +33050,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/commons/dorms) -"jqw" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/tile/blue/anticorner/contrasted{ - dir = 4 - }, -/obj/structure/sign/poster/official/random/directional/north, -/turf/open/floor/iron/white, -/area/station/science/genetics) "jqx" = ( /obj/structure/transit_tube/crossing/horizontal, /obj/effect/turf_decal/weather/snow/corner{ @@ -33242,6 +33076,11 @@ "jqT" = ( /turf/closed/wall/r_wall, /area/station/engineering/storage/tech) +"jrd" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/turf/open/floor/iron, +/area/mine/laborcamp) "jre" = ( /turf/closed/wall, /area/station/maintenance/starboard/lesser) @@ -33339,6 +33178,34 @@ dir = 1 }, /area/station/hallway/primary/port) +"jsI" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/training_machine, +/obj/effect/turf_decal/bot_red, +/obj/item/target, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/surface/outdoors/nospawn) +"jsN" = ( +/obj/machinery/camera/directional/west{ + c_tag = "Security - HoS Office" + }, +/obj/item/flashlight/lamp/green{ + pixel_x = -6; + pixel_y = 16; + start_on = 0 + }, +/obj/structure/table/wood, +/obj/machinery/recharger{ + pixel_x = -4; + pixel_y = -1 + }, +/obj/machinery/airalarm/directional/west, +/obj/item/phone{ + pixel_x = -9; + pixel_y = 7 + }, +/turf/open/floor/wood/large, +/area/station/command/heads_quarters/hos) "jsO" = ( /obj/effect/spawner/random/maintenance/three, /obj/structure/closet/crate/wooden, @@ -33501,6 +33368,9 @@ }, /turf/open/floor/iron/white, /area/station/medical/treatment_center) +"juA" = ( +/turf/open/floor/wood/large, +/area/station/security/prison/rec) "juH" = ( /obj/structure/filingcabinet/chestdrawer, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -33567,10 +33437,6 @@ }, /turf/open/floor/plating, /area/station/security/detectives_office) -"jvM" = ( -/obj/structure/cable, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "jvR" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/cable, @@ -33630,12 +33496,6 @@ initial_gas_mix = "ICEMOON_ATMOS" }, /area/icemoon/underground/explored/graveyard) -"jwx" = ( -/obj/effect/turf_decal/tile/red/half/contrasted{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/security/brig/upper) "jwz" = ( /obj/structure/flora/rock/icy/style_random, /obj/structure/sign/nanotrasen/directional/north, @@ -33673,21 +33533,6 @@ /obj/structure/cable, /turf/open/floor/iron/dark, /area/station/science/breakroom) -"jxc" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/tile/blue/half/contrasted{ - dir = 4 - }, -/turf/open/floor/iron/white/side{ - dir = 4 - }, -/area/station/science/genetics) "jxq" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -33710,6 +33555,16 @@ /obj/structure/table/wood, /turf/open/floor/iron/dark, /area/station/service/hydroponics/garden) +"jxK" = ( +/obj/structure/cable, +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, +/turf/open/floor/iron/dark/side{ + dir = 8 + }, +/area/mine/laborcamp/security) "jyl" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -33756,16 +33611,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply, /turf/open/floor/iron/white, /area/station/medical/virology) -"jyL" = ( -/obj/structure/cable, -/obj/machinery/power/terminal{ - dir = 8 - }, -/obj/structure/closet/crate/preopen, -/obj/item/stack/sheet/mineral/plasma/thirty, -/obj/machinery/light/small/directional/south, -/turf/open/floor/iron/smooth, -/area/mine/laborcamp/security) "jyR" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable, @@ -33779,6 +33624,18 @@ /obj/structure/closet/secure_closet/captains, /turf/open/floor/carpet, /area/station/command/heads_quarters/captain) +"jzv" = ( +/obj/structure/cable, +/obj/machinery/door/airlock/security/glass{ + name = "Permabrig Visitation" + }, +/obj/effect/mapping_helpers/airlock/access/any/security/brig, +/obj/effect/mapping_helpers/airlock/unres/delayed{ + dir = 4 + }, +/obj/machinery/door/firedoor, +/turf/open/floor/iron, +/area/station/security/brig) "jzy" = ( /obj/machinery/computer/exodrone_control_console{ dir = 1 @@ -33888,6 +33745,13 @@ /obj/structure/flora/grass/both/style_random, /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/underground/explored) +"jAA" = ( +/obj/structure/cable, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/smooth, +/area/station/engineering/lobby) "jAF" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -33942,17 +33806,6 @@ }, /turf/open/floor/plating, /area/station/science/xenobiology) -"jBn" = ( -/obj/docking_port/stationary{ - dir = 4; - dwidth = 2; - height = 5; - name = "labor camp"; - shuttle_id = "laborcamp_away"; - width = 9 - }, -/turf/open/misc/asteroid/snow/icemoon, -/area/icemoon/underground/explored) "jBB" = ( /obj/machinery/atmospherics/pipe/heat_exchanging/junction, /obj/effect/spawner/structure/window, @@ -34073,10 +33926,6 @@ }, /turf/open/floor/iron/dark, /area/station/medical/treatment_center) -"jDt" = ( -/obj/machinery/pdapainter/security, -/turf/open/floor/wood/large, -/area/station/command/heads_quarters/hos) "jDz" = ( /obj/machinery/light/small/directional/east, /obj/item/pickaxe, @@ -34145,13 +33994,6 @@ }, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/captain) -"jEs" = ( -/obj/machinery/conveyor_switch/oneway{ - id = "gulag"; - name = "labor camp conveyor" - }, -/turf/open/floor/iron, -/area/mine/laborcamp) "jED" = ( /obj/machinery/modular_computer/preset/civilian{ dir = 4 @@ -34240,12 +34082,6 @@ /obj/structure/sign/departments/chemistry/pharmacy/directional/west, /turf/open/floor/iron/white, /area/station/medical/medbay/central) -"jGg" = ( -/obj/effect/turf_decal/trimline/red/filled/line{ - dir = 10 - }, -/turf/open/floor/iron/white, -/area/station/security/prison/safe) "jGh" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -34256,6 +34092,15 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/port/lesser) +"jGC" = ( +/obj/effect/turf_decal/tile/red/anticorner/contrasted{ + dir = 1 + }, +/obj/structure/sign/poster/official/here_for_your_safety/directional/west, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/station/security/prison/visit) "jGJ" = ( /obj/structure/table/reinforced, /obj/structure/reagent_dispensers/wall/peppertank/directional/east, @@ -34553,6 +34398,15 @@ /obj/machinery/light/directional/south, /turf/open/floor/iron/white, /area/station/medical/chemistry) +"jKH" = ( +/obj/structure/cable, +/obj/effect/spawner/structure/window/hollow/reinforced/middle, +/obj/machinery/door/poddoor/preopen{ + id = "labor"; + name = "Labor Camp Blast Door" + }, +/turf/open/floor/plating, +/area/mine/laborcamp/security) "jKI" = ( /obj/effect/turf_decal/stripes/line{ dir = 6 @@ -34577,6 +34431,18 @@ /obj/effect/turf_decal/tile/green, /turf/open/floor/iron/dark, /area/station/ai/upload/chamber) +"jKM" = ( +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue, +/turf/open/floor/iron/corner{ + dir = 1 + }, +/area/station/hallway/primary/starboard) "jKN" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -34644,14 +34510,11 @@ }, /turf/open/floor/iron/dark/corner, /area/station/engineering/atmos/storage/gas) -"jLo" = ( -/obj/structure/table, +"jLq" = ( +/obj/machinery/airalarm/directional/west, /obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, /turf/open/floor/iron, -/area/mine/laborcamp) +/area/mine/production) "jLt" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -34806,6 +34669,21 @@ /obj/effect/mapping_helpers/airlock/access/all/supply/general, /turf/open/floor/plating, /area/station/cargo/storage) +"jMJ" = ( +/obj/structure/closet/crate{ + name = "Firing Range Supplies Set" + }, +/obj/item/target/clown, +/obj/item/target/alien, +/obj/item/target/clown, +/obj/item/target/alien, +/obj/item/target, +/obj/effect/turf_decal/bot_red, +/obj/effect/turf_decal/tile/red/half/contrasted, +/obj/machinery/status_display/evac/directional/east, +/obj/machinery/airalarm/directional/south, +/turf/open/floor/iron/dark, +/area/station/security/range) "jMO" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 1 @@ -34840,6 +34718,13 @@ /obj/effect/mapping_helpers/airlock/access/any/command/general, /turf/open/floor/iron/dark, /area/station/tcommsat/computer) +"jNn" = ( +/obj/structure/cable, +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/mine/laborcamp) "jNo" = ( /turf/open/floor/stone, /area/station/service/bar/atrium) @@ -34868,40 +34753,16 @@ /obj/effect/spawner/random/structure/steam_vent, /turf/open/floor/plating, /area/station/maintenance/aft/lesser) +"jOq" = ( +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/tile/red/half/contrasted, +/turf/open/floor/iron, +/area/station/security/brig/upper) "jOt" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable, /turf/open/floor/plating, /area/station/hallway/primary/port) -"jOw" = ( -/obj/structure/table/glass, -/obj/item/book/manual/wiki/infections{ - pixel_x = 5; - pixel_y = 3 - }, -/obj/item/book/manual/wiki/surgery{ - pixel_x = -4; - pixel_y = 3 - }, -/obj/item/book/manual/wiki/medicine{ - pixel_x = -4; - pixel_y = 7 - }, -/obj/item/book/manual/wiki/chemistry{ - pixel_x = 5; - pixel_y = 8 - }, -/obj/effect/turf_decal/tile/blue/full, -/obj/item/tgui_book/manual/dsm{ - pixel_x = -4; - pixel_y = 12 - }, -/obj/item/tgui_book/manual/idc{ - pixel_x = 4; - pixel_y = 13 - }, -/turf/open/floor/iron/dark/smooth_large, -/area/station/command/heads_quarters/cmo) "jOy" = ( /obj/machinery/camera/directional/east{ c_tag = "Central Hallway West" @@ -34975,13 +34836,6 @@ }, /turf/open/floor/iron, /area/station/cargo/storage) -"jPf" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 1 - }, -/obj/effect/landmark/start/hangover, -/turf/open/floor/iron/dark, -/area/station/engineering/circuit_workshop) "jPh" = ( /obj/structure/grille/broken, /obj/structure/disposalpipe/segment, @@ -35121,15 +34975,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron/white, /area/station/medical/medbay/aft) -"jQE" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/security/prison/mess) "jQS" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, @@ -35176,15 +35021,6 @@ }, /turf/open/floor/iron/smooth_large, /area/station/science/cytology) -"jRu" = ( -/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/wideplating/dark{ - dir = 4 - }, -/turf/open/floor/iron/dark/textured, -/area/station/security/prison/rec) "jRA" = ( /turf/open/openspace, /area/station/service/bar/atrium) @@ -35203,10 +35039,6 @@ /obj/item/kirbyplants/random, /turf/open/floor/iron/white, /area/station/medical/chemistry) -"jRP" = ( -/obj/machinery/light/small/directional/west, -/turf/open/floor/iron/dark/textured, -/area/station/security/interrogation) "jRS" = ( /obj/effect/turf_decal/weather/snow/corner{ dir = 8 @@ -35280,6 +35112,30 @@ }, /turf/open/floor/plastic, /area/station/commons/dorms/laundry) +"jSO" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/structure/sign/poster/official/random/directional/north, +/obj/effect/turf_decal/tile/purple/anticorner/contrasted{ + dir = 4 + }, +/turf/open/floor/iron/white, +/area/station/science/genetics) +"jST" = ( +/obj/item/radio/intercom/directional/south, +/obj/machinery/gulag_teleporter, +/turf/open/floor/iron/dark, +/area/mine/laborcamp/security) "jTf" = ( /obj/structure/fence{ dir = 1 @@ -35300,19 +35156,21 @@ }, /turf/open/floor/iron/white, /area/station/science/lab) -"jTw" = ( -/obj/machinery/power/port_gen/pacman/pre_loaded, -/turf/open/floor/plating, -/area/station/maintenance/fore) -"jTG" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/door/poddoor/shutters/preopen{ - dir = 8; - id = "gene_shutters"; - name = "Genetics Shutters" +"jTr" = ( +/obj/structure/closet/crate{ + name = "Firing Range Supplies Set" }, -/turf/open/floor/plating, -/area/station/science/genetics) +/obj/item/target/syndicate, +/obj/item/target/syndicate, +/obj/item/target, +/obj/effect/turf_decal/bot_red, +/obj/effect/turf_decal/tile/red/half/contrasted, +/obj/item/radio/intercom/directional/south, +/obj/machinery/camera/directional/south{ + c_tag = "Security - Firing Range" + }, +/turf/open/floor/iron/dark, +/area/station/security/range) "jTT" = ( /obj/structure/chair/stool/directional/east, /obj/machinery/light/floor, @@ -35415,12 +35273,6 @@ /obj/effect/spawner/random/maintenance, /turf/open/floor/plating, /area/station/maintenance/aft/lesser) -"jVb" = ( -/obj/machinery/space_heater, -/obj/machinery/light/small/directional/north, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/wood, -/area/station/maintenance/fore) "jVp" = ( /obj/item/kirbyplants/fern, /turf/open/floor/plating, @@ -35441,6 +35293,10 @@ /obj/structure/window/reinforced/spawner/directional/west, /turf/open/floor/iron, /area/station/science/xenobiology) +"jVy" = ( +/obj/structure/sign/warning/directional/east, +/turf/open/misc/asteroid/snow/icemoon, +/area/icemoon/surface/outdoors/nospawn) "jVE" = ( /obj/effect/turf_decal/box/white, /turf/open/floor/engine, @@ -35530,17 +35386,6 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on, /turf/open/floor/iron, /area/station/maintenance/disposal/incinerator) -"jXH" = ( -/obj/machinery/conveyor{ - dir = 8; - id = "mining_internal" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/iron, -/area/mine/production) "jXL" = ( /obj/machinery/newscaster/directional/south, /obj/structure/disposalpipe/trunk{ @@ -35558,27 +35403,18 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/command/gateway) -"jXY" = ( -/obj/machinery/door/airlock/public/glass{ - id_tag = "gulag1"; - name = "Cell 1" - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/mine/laborcamp) "jYc" = ( /obj/effect/spawner/random/trash/grille_or_waste, /turf/open/floor/plating, /area/station/maintenance/starboard/upper) -"jYj" = ( -/obj/structure/sign/warning/secure_area/directional/north, -/obj/effect/turf_decal/stripes/red/line{ - dir = 1 +"jYm" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 8 }, -/obj/effect/turf_decal/trimline/red/line, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) +/turf/open/floor/iron/smooth, +/area/station/security/holding_cell) "jYy" = ( /obj/structure/sink/directional/south, /obj/effect/decal/cleanable/dirt, @@ -35636,16 +35472,6 @@ }, /turf/open/floor/catwalk_floor/iron_smooth, /area/station/maintenance/fore/lesser) -"jZi" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/door/airlock/public/glass{ - id_tag = "cellblock1"; - name = "Labor Camp Operations" - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/mine/laborcamp) "jZj" = ( /obj/effect/turf_decal/siding/wood{ dir = 4 @@ -35735,13 +35561,6 @@ /obj/item/radio/intercom/directional/north, /turf/open/floor/iron, /area/station/cargo/office) -"kaO" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/loading_area{ - dir = 8 - }, -/turf/open/floor/iron, -/area/mine/laborcamp) "kaW" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -35758,12 +35577,6 @@ /obj/item/clothing/shoes/workboots, /turf/open/floor/plating, /area/station/maintenance/port/fore) -"kbm" = ( -/obj/machinery/mech_bay_recharge_port{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/security/mechbay) "kbn" = ( /obj/effect/decal/cleanable/food/pie_smudge, /turf/open/floor/iron, @@ -35784,14 +35597,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/port/aft) -"kbx" = ( -/obj/structure/table, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/microwave{ - pixel_y = 6 - }, -/turf/open/floor/iron, -/area/mine/laborcamp) "kbJ" = ( /obj/machinery/field/generator, /turf/open/floor/plating, @@ -35809,27 +35614,16 @@ }, /turf/open/floor/iron, /area/station/maintenance/starboard/fore) -"kbN" = ( -/obj/structure/table/wood, -/obj/item/storage/box/matches, -/obj/item/toy/cards/deck{ - pixel_y = 4 +"kbX" = ( +/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/stripes/red/line{ + dir = 1 }, -/obj/item/reagent_containers/cup/glass/drinkingglass{ - pixel_x = 14; - pixel_y = 12 - }, -/obj/item/reagent_containers/cup/glass/drinkingglass{ - pixel_x = -18; - pixel_y = 10 - }, -/obj/item/reagent_containers/cup/glass/drinkingglass{ - pixel_x = -10; - pixel_y = 2 - }, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/wood, -/area/station/maintenance/fore) +/obj/effect/turf_decal/tile/red, +/turf/open/floor/iron, +/area/mine/laborcamp/security) "kcc" = ( /obj/machinery/camera/directional/west{ c_tag = "Security - Infirmary" @@ -35848,20 +35642,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/aft/lesser) -"kcf" = ( -/obj/machinery/light/small/directional/north, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/mine/laborcamp) -"kcC" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/obj/item/radio/intercom/prison/directional/west, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/security/prison/mess) "kcD" = ( /obj/effect/turf_decal/stripes/line{ dir = 5 @@ -35923,16 +35703,6 @@ dir = 8 }, /area/station/science/ordnance) -"kdy" = ( -/obj/machinery/door/poddoor/shutters{ - id = "secmechbay"; - name = "Security Mech Bay Shutters" - }, -/obj/structure/cable, -/obj/effect/turf_decal/caution/stand_clear, -/obj/effect/turf_decal/box, -/turf/open/floor/iron/dark, -/area/station/security/mechbay) "kdA" = ( /obj/machinery/door/firedoor{ dir = 8 @@ -36022,11 +35792,6 @@ }, /turf/open/floor/plating/snowed/icemoon, /area/icemoon/underground/explored) -"keD" = ( -/obj/structure/easel, -/obj/item/canvas/nineteen_nineteen, -/turf/open/floor/sepia, -/area/station/security/prison/rec) "keP" = ( /turf/closed/wall, /area/station/engineering/atmos/storage/gas) @@ -36059,13 +35824,6 @@ /obj/machinery/air_sensor/air_tank, /turf/open/floor/engine/air, /area/station/engineering/atmos) -"kfc" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/turf/open/floor/iron/smooth, -/area/station/security/brig/upper) "kfe" = ( /obj/item/trash/energybar, /turf/open/floor/plating, @@ -36099,6 +35857,22 @@ "kfs" = ( /turf/closed/wall/r_wall, /area/station/engineering/atmos) +"kfu" = ( +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/obj/machinery/camera/directional/north{ + c_tag = "Security - Upper Brig Center" + }, +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 1 + }, +/obj/structure/noticeboard/hos{ + pixel_y = 36; + dir = 1 + }, +/turf/open/floor/iron, +/area/station/security/brig/upper) "kfy" = ( /obj/structure/cable, /turf/open/floor/iron, @@ -36203,15 +35977,6 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/iron/cafeteria, /area/station/commons/dorms/laundry) -"khb" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 1 - }, -/obj/effect/turf_decal/siding/wideplating/dark{ - dir = 4 - }, -/turf/open/floor/iron/dark/textured, -/area/station/security/prison/rec) "khe" = ( /obj/machinery/atmospherics/components/trinary/filter/atmos/n2o{ dir = 1 @@ -36250,6 +36015,11 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/wood, /area/station/maintenance/port/fore) +"khY" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/plasticflaps, +/turf/open/floor/plating, +/area/station/maintenance/fore) "kig" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 8 @@ -36257,6 +36027,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) +"kih" = ( +/obj/machinery/shower/directional/south, +/obj/structure/curtain, +/turf/open/floor/iron/showroomfloor, +/area/mine/laborcamp) "kii" = ( /obj/effect/spawner/random/trash/food_packaging, /turf/open/floor/plating, @@ -36458,6 +36233,12 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/command/eva) +"kkd" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/plating, +/area/station/maintenance/department/security) "kke" = ( /obj/machinery/door/airlock/maintenance, /obj/structure/cable, @@ -36469,19 +36250,6 @@ /obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance, /turf/open/floor/plating, /area/station/maintenance/port/fore) -"kki" = ( -/obj/structure/table/wood, -/obj/item/rag, -/obj/item/clothing/head/collectable/tophat{ - pixel_x = 6; - pixel_y = 5 - }, -/obj/effect/spawner/random/entertainment/gambling{ - pixel_x = -13 - }, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/wood, -/area/station/maintenance/fore) "kkl" = ( /turf/closed/wall, /area/station/security/interrogation) @@ -36489,15 +36257,6 @@ /obj/machinery/power/port_gen/pacman/pre_loaded, /turf/open/floor/plating, /area/station/maintenance/port/fore) -"kkB" = ( -/obj/machinery/light/small/directional/south, -/obj/structure/closet/secure_closet/brig{ - id = "Cell 2"; - name = "Cell 2 locker" - }, -/obj/structure/cable, -/turf/open/floor/iron/smooth, -/area/station/security/brig) "kkD" = ( /obj/effect/spawner/random/trash/grille_or_waste, /turf/open/floor/plating, @@ -36567,28 +36326,21 @@ dir = 1 }, /area/station/medical/chemistry) -"klv" = ( -/obj/structure/chair/sofa/corp/corner{ - dir = 8 +"klU" = ( +/obj/effect/mapping_helpers/airlock/access/all/security/general, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/security/glass{ + name = "Security Mech Bay" }, -/obj/effect/spawner/random/contraband/prison, -/turf/open/floor/carpet/blue, -/area/station/security/prison/work) +/turf/open/floor/iron/dark, +/area/station/security/mechbay) "klW" = ( /obj/structure/window/reinforced/spawner/directional/south, /turf/open/floor/iron, /area/station/science/xenobiology) -"klX" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/door/airlock/public/glass{ - id_tag = "cellblock1"; - name = "Labor Camp Cellblock" - }, -/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/mine/laborcamp) "kmi" = ( /obj/effect/landmark/blobstart, /obj/structure/cable, @@ -36622,23 +36374,6 @@ }, /turf/open/floor/iron, /area/station/engineering/lobby) -"kmA" = ( -/obj/structure/bed/medical/anchored{ - dir = 4 - }, -/obj/item/bedsheet/medical, -/obj/machinery/camera/directional/east{ - c_tag = "Labor Camp Infirmary"; - network = list("labor") - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 1 - }, -/obj/effect/turf_decal/tile/blue/opposingcorners{ - dir = 1 - }, -/turf/open/floor/iron/white, -/area/mine/laborcamp) "kmG" = ( /obj/machinery/defibrillator_mount/directional/north, /obj/effect/turf_decal/tile/blue/full, @@ -36648,11 +36383,6 @@ }, /turf/open/floor/iron/large, /area/station/medical/treatment_center) -"kmH" = ( -/obj/effect/spawner/random/entertainment/cigar, -/obj/structure/table, -/turf/open/floor/plating/snowed/icemoon, -/area/icemoon/underground/explored) "kmM" = ( /obj/effect/decal/cleanable/generic, /turf/open/floor/plating, @@ -36693,11 +36423,31 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/security/prison/workout) +"knB" = ( +/obj/machinery/door/airlock/external{ + name = "Escape Pod Three"; + space_dir = 1 + }, +/turf/open/floor/iron/dark/textured, +/area/station/security/brig/upper) "knX" = ( /obj/machinery/status_display/evac/directional/east, /obj/effect/turf_decal/tile/yellow/opposingcorners, /turf/open/floor/iron/dark, /area/station/engineering/atmos/project) +"koa" = ( +/obj/machinery/light/cold/directional/north, +/obj/effect/turf_decal/trimline/purple/filled/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/power/apc/auto_name/directional/north, +/obj/structure/cable, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/iron/dark, +/area/station/engineering/circuit_workshop) "kod" = ( /obj/item/kirbyplants/random, /obj/effect/turf_decal/tile/blue{ @@ -36709,6 +36459,14 @@ dir = 8 }, /area/station/hallway/secondary/entry) +"kot" = ( +/obj/structure/table, +/obj/effect/turf_decal/tile/blue/opposingcorners{ + dir = 1 + }, +/obj/structure/cable, +/turf/open/floor/iron/white, +/area/mine/laborcamp) "koH" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 4 @@ -36735,19 +36493,6 @@ /obj/effect/mapping_helpers/airlock/access/any/engineering/external, /turf/open/floor/plating, /area/station/service/chapel) -"kpj" = ( -/obj/structure/window/reinforced/spawner/directional/north{ - pixel_y = 2 - }, -/obj/structure/rack, -/obj/effect/decal/cleanable/dirt, -/obj/item/clothing/mask/muzzle, -/obj/machinery/flasher/directional/east{ - id = "cell4"; - pixel_y = -7 - }, -/turf/open/floor/iron/smooth, -/area/station/security/holding_cell) "kpn" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/sink/kitchen/directional/east, @@ -36776,13 +36521,6 @@ /obj/item/radio/intercom/directional/west, /turf/open/floor/iron/dark, /area/station/engineering/atmos/hfr_room) -"kpH" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 8 - }, -/turf/open/floor/iron, -/area/mine/laborcamp) "kpX" = ( /obj/structure/bed/medical{ dir = 4 @@ -36800,15 +36538,6 @@ /obj/effect/spawner/random/decoration/ornament, /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) -"kqh" = ( -/obj/structure/chair/wood{ - dir = 8 - }, -/obj/effect/turf_decal/siding/wood{ - dir = 4 - }, -/turf/open/floor/wood, -/area/station/security/prison/rec) "kql" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/visible, @@ -36850,11 +36579,6 @@ }, /turf/open/floor/iron/white/corner, /area/station/engineering/atmos) -"kqs" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/vending/sustenance/labor_camp, -/turf/open/floor/iron, -/area/mine/laborcamp) "kqt" = ( /obj/effect/turf_decal/tile/brown/anticorner/contrasted{ dir = 4 @@ -36866,16 +36590,6 @@ dir = 5 }, /area/station/commons/storage/mining) -"kqG" = ( -/obj/structure/table/reinforced, -/obj/machinery/light/small/directional/east, -/obj/effect/spawner/random/engineering/tool{ - pixel_x = 1; - pixel_y = 3 - }, -/obj/machinery/airalarm/directional/east, -/turf/open/floor/iron, -/area/station/security/mechbay) "kqK" = ( /obj/effect/spawner/random/trash/mess, /obj/effect/decal/cleanable/dirt, @@ -36892,12 +36606,6 @@ /obj/machinery/duct, /turf/open/floor/iron/textured, /area/station/commons/toilet) -"kqR" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/sepia, -/area/station/security/prison/rec) "kqS" = ( /obj/machinery/atmospherics/components/binary/pump/off{ dir = 1; @@ -36918,6 +36626,21 @@ dir = 10 }, /area/station/science/xenobiology) +"kre" = ( +/obj/structure/table, +/obj/item/storage/backpack/duffelbag/sec/surgery, +/obj/item/taperecorder{ + pixel_x = -3 + }, +/obj/item/razor, +/obj/machinery/button/door/directional/north{ + pixel_y = 24; + pixel_x = 6; + id = "executionshutters"; + name = "Shutter Control" + }, +/turf/open/floor/iron/dark, +/area/station/security/execution/education) "krn" = ( /obj/structure/reagent_dispensers/watertank, /turf/open/floor/plating, @@ -36935,18 +36658,6 @@ }, /turf/closed/wall, /area/station/hallway/primary/central) -"kry" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/landmark/start/prisoner, -/turf/open/floor/vault, -/area/station/security/prison/rec) -"krC" = ( -/obj/machinery/atmospherics/components/tank/air{ - dir = 8 - }, -/turf/open/floor/plating, -/area/mine/laborcamp/security) "krJ" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/decal/cleanable/dirt, @@ -37194,15 +36905,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/general/visible, /turf/open/floor/engine/xenobio, /area/station/science/xenobiology) -"kuV" = ( -/obj/effect/turf_decal/arrows/red, -/obj/effect/turf_decal/tile/purple/half{ - dir = 4 - }, -/turf/open/floor/iron/half{ - dir = 1 - }, -/area/station/hallway/primary/starboard) "kuZ" = ( /obj/effect/spawner/structure/window/hollow/reinforced/middle{ dir = 1 @@ -37296,6 +36998,28 @@ /obj/machinery/gibber, /turf/open/misc/asteroid/snow/coldroom, /area/station/service/kitchen/coldroom) +"kwI" = ( +/obj/structure/rack, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/blood/old, +/obj/item/restraints/handcuffs{ + pixel_y = 5 + }, +/obj/item/restraints/handcuffs{ + pixel_y = 1 + }, +/obj/item/restraints/handcuffs{ + pixel_x = 1; + pixel_y = -4 + }, +/obj/machinery/camera/directional/south{ + c_tag = "Security - Holding Cells" + }, +/obj/structure/cable, +/obj/machinery/power/apc/auto_name/directional/south, +/obj/item/radio/intercom/directional/east, +/turf/open/floor/iron/smooth, +/area/station/security/holding_cell) "kwK" = ( /obj/effect/turf_decal/tile/purple/half, /turf/open/floor/iron/half, @@ -37306,14 +37030,6 @@ /obj/machinery/light/small/directional/west, /turf/open/floor/iron/dark, /area/station/science/ordnance) -"kwU" = ( -/obj/machinery/computer/records/security, -/obj/structure/cable, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "kwX" = ( /obj/structure/grille, /turf/open/floor/plating, @@ -37419,6 +37135,11 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/security/warden) +"kyD" = ( +/obj/structure/sink/directional/east, +/obj/structure/mirror/directional/west, +/turf/open/floor/iron/showroomfloor, +/area/mine/laborcamp) "kyL" = ( /obj/effect/turf_decal/tile/neutral{ dir = 4 @@ -37492,9 +37213,6 @@ /obj/effect/spawner/random/bedsheet/any, /turf/open/floor/plating, /area/station/maintenance/department/medical/morgue) -"kzw" = ( -/turf/closed/wall/r_wall, -/area/station/security/medical) "kzx" = ( /obj/structure/closet/crate, /obj/item/food/breadslice/plain, @@ -37580,12 +37298,6 @@ /obj/effect/decal/cleanable/cobweb/cobweb2, /turf/open/floor/plating, /area/station/maintenance/aft/greater) -"kAG" = ( -/obj/structure/table, -/obj/item/cigbutt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "kAH" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -37714,6 +37426,10 @@ dir = 1 }, /area/mine/eva/lower) +"kCb" = ( +/obj/structure/fence/door, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/surface/outdoors/nospawn) "kCg" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/turf_decal/siding/wood/corner{ @@ -37786,16 +37502,6 @@ /obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/dark, /area/station/engineering/lobby) -"kCH" = ( -/obj/machinery/door/airlock/security/glass{ - name = "Labor Camp Airlock" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 1 - }, -/obj/effect/mapping_helpers/airlock/access/all/security/brig, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "kCI" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/frame/machine/secured, @@ -37888,6 +37594,16 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/commons/locker) +"kEe" = ( +/obj/machinery/conveyor_switch/oneway{ + id = "gulag"; + name = "labor camp conveyor"; + pixel_y = 15; + pixel_x = -8 + }, +/obj/item/radio/intercom/prison/directional/north, +/turf/open/floor/iron, +/area/mine/laborcamp) "kEj" = ( /obj/machinery/computer/libraryconsole/bookmanagement, /obj/structure/table, @@ -37895,15 +37611,6 @@ /obj/structure/cable, /turf/open/floor/carpet/red, /area/station/security/prison/work) -"kEn" = ( -/obj/machinery/camera/directional/south{ - c_tag = "Security - Visitation South"; - network = list("ss13","prison") - }, -/obj/machinery/airalarm/directional/south, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron, -/area/station/security/prison/visit) "kEq" = ( /obj/effect/spawner/random/structure/crate, /turf/open/floor/plating, @@ -37990,18 +37697,6 @@ /obj/structure/sign/nanotrasen/directional/north, /turf/open/floor/iron, /area/station/command/heads_quarters/hop) -"kGc" = ( -/obj/structure/table/wood, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/fax{ - fax_name = "Head of Security's Office"; - name = "Head of Security's Fax Machine" - }, -/obj/effect/landmark/event_spawn, -/turf/open/floor/wood/large, -/area/station/command/heads_quarters/hos) "kGe" = ( /obj/machinery/door/poddoor/preopen{ dir = 4; @@ -38050,15 +37745,6 @@ dir = 1 }, /area/station/commons/storage/art) -"kGP" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/machinery/power/apc/auto_name/directional/west, -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/security/prison/mess) "kGQ" = ( /obj/structure/table, /obj/item/stamp/head/qm, @@ -38102,26 +37788,31 @@ /obj/structure/sign/poster/official/random/directional/west, /turf/open/floor/stone, /area/mine/eva/lower) -"kHn" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/firealarm/directional/south, -/turf/open/floor/iron/showroomfloor, -/area/station/security/prison/toilet) +"kHl" = ( +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 8 + }, +/obj/machinery/status_display/ai/directional/south, +/turf/open/floor/iron/smooth, +/area/station/security/brig/upper) "kHr" = ( /turf/closed/wall/r_wall, /area/station/engineering/atmos/project) +"kHt" = ( +/obj/structure/cable, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/light/floor, +/turf/open/floor/iron, +/area/station/security/brig/upper) "kHI" = ( /obj/item/radio/intercom/directional/south, /obj/effect/turf_decal/tile/blue, /turf/open/floor/iron, /area/station/hallway/primary/starboard) -"kHL" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/airalarm/directional/south, -/turf/open/floor/iron/cafeteria, -/area/station/security/prison/mess) "kHN" = ( /obj/machinery/firealarm/directional/north, /turf/open/openspace, @@ -38190,12 +37881,6 @@ /obj/effect/mapping_helpers/mail_sorting/service/library, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) -"kIo" = ( -/obj/structure/rack, -/obj/item/clothing/suit/hooded/wintercoat, -/obj/item/clothing/suit/hooded/wintercoat, -/turf/open/floor/vault, -/area/station/security/prison/rec) "kIr" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 8 @@ -38281,14 +37966,6 @@ }, /turf/open/floor/stone, /area/station/service/bar/atrium) -"kJw" = ( -/obj/machinery/atmospherics/pipe/layer_manifold/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/sign/poster/official/random/directional/north, -/turf/open/floor/iron/smooth, -/area/mine/laborcamp/security) "kJF" = ( /obj/machinery/atmospherics/pipe/smart/simple/purple/visible{ dir = 4 @@ -38363,6 +38040,10 @@ "kKL" = ( /turf/closed/wall, /area/station/maintenance/starboard/fore) +"kKO" = ( +/obj/effect/landmark/event_spawn, +/turf/open/floor/carpet/royalblue, +/area/station/command/heads_quarters/hos) "kKT" = ( /obj/effect/turf_decal/siding/wood{ dir = 1 @@ -38416,10 +38097,6 @@ }, /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/underground/explored) -"kLo" = ( -/obj/structure/window/reinforced/spawner/directional/west, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) "kLr" = ( /obj/structure/table/wood, /obj/effect/spawner/random/maintenance, @@ -38527,6 +38204,12 @@ /obj/structure/grille, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) +"kNB" = ( +/obj/machinery/conveyor{ + id = "mining_internal" + }, +/turf/open/floor/iron, +/area/mine/production) "kNC" = ( /obj/structure/railing, /obj/effect/turf_decal/siding/thinplating, @@ -38553,11 +38236,6 @@ /obj/effect/spawner/random/structure/crate, /turf/open/floor/plating, /area/station/maintenance/port/aft) -"kOc" = ( -/obj/structure/chair, -/obj/structure/sign/warning/directional/north, -/turf/open/floor/plating/snowed/icemoon, -/area/icemoon/underground/explored) "kOd" = ( /obj/effect/turf_decal/tile/brown/half/contrasted{ dir = 4 @@ -38626,23 +38304,13 @@ }, /turf/open/floor/plating, /area/station/service/hydroponics) -"kON" = ( -/obj/structure/rack, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/blood/old, -/obj/item/restraints/handcuffs{ - pixel_y = 5 +"kOP" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 1 }, -/obj/item/restraints/handcuffs{ - pixel_y = 1 - }, -/obj/item/restraints/handcuffs{ - pixel_x = 1; - pixel_y = -4 - }, -/obj/structure/cable, -/turf/open/floor/iron/showroomfloor, -/area/station/security/processing) +/obj/effect/landmark/start/hangover, +/turf/open/floor/iron/dark, +/area/station/engineering/circuit_workshop) "kOR" = ( /obj/structure/railing/wooden_fence, /obj/item/flashlight/lantern/on, @@ -38709,6 +38377,17 @@ }, /turf/open/floor/iron, /area/station/service/hydroponics/garden) +"kPG" = ( +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 9 + }, +/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/dark/side{ + dir = 9 + }, +/area/station/security/prison) "kPH" = ( /obj/structure/stairs/south{ dir = 8 @@ -38802,10 +38481,6 @@ /obj/machinery/status_display/ai/directional/west, /turf/open/floor/iron, /area/station/commons/locker) -"kRd" = ( -/obj/structure/bookcase, -/turf/open/floor/iron, -/area/mine/laborcamp) "kRp" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/cable, @@ -38871,10 +38546,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) -"kSv" = ( -/obj/effect/turf_decal/tile/red/half/contrasted, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "kSw" = ( /obj/structure/sign/warning/secure_area/directional/north, /turf/open/misc/asteroid/snow/icemoon, @@ -38909,6 +38580,12 @@ }, /turf/open/floor/plating, /area/station/engineering/supermatter) +"kSN" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 4 + }, +/turf/open/floor/iron/smooth, +/area/station/security/brig) "kSR" = ( /obj/effect/turf_decal/tile/blue, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -38920,17 +38597,20 @@ dir = 4 }, /area/station/hallway/secondary/entry) -"kSU" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 - }, -/turf/open/floor/iron, -/area/mine/laborcamp) "kTk" = ( /turf/open/floor/iron/dark/textured_half{ dir = 1 }, /area/station/service/chapel/office) +"kTs" = ( +/obj/machinery/door/poddoor/preopen{ + id = "labor"; + name = "Labor Camp Blast Door" + }, +/obj/machinery/mineral/stacking_machine/laborstacker, +/obj/structure/cable, +/turf/open/floor/plating, +/area/mine/laborcamp) "kTy" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 8 @@ -38961,6 +38641,10 @@ /obj/effect/spawner/random/structure/steam_vent, /turf/open/floor/plating, /area/mine/eva/lower) +"kTJ" = ( +/obj/structure/sign/nanotrasen/directional/south, +/turf/open/misc/asteroid/snow/icemoon, +/area/icemoon/surface/outdoors/nospawn) "kUb" = ( /obj/effect/turf_decal/stripes/red/line{ dir = 8 @@ -38995,12 +38679,12 @@ }, /turf/open/floor/iron/freezer, /area/station/service/kitchen/coldroom) -"kUt" = ( -/obj/machinery/atmospherics/pipe/multiz/scrubbers/visible/layer2, -/obj/machinery/atmospherics/pipe/multiz/supply/visible/layer4, -/obj/structure/sign/poster/contraband/random/directional/north, -/turf/open/floor/plating, -/area/station/security/prison/safe) +"kUq" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 4 + }, +/turf/open/floor/iron/smooth, +/area/station/security/lockers) "kUu" = ( /obj/machinery/atmospherics/pipe/smart/simple/orange/visible{ dir = 4 @@ -39016,6 +38700,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/purple/visible, /turf/open/floor/engine, /area/station/engineering/supermatter/room) +"kUC" = ( +/obj/structure/table/wood, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/item/storage/fancy/candle_box, +/turf/open/floor/iron/dark, +/area/station/security/prison/rec) "kUD" = ( /turf/open/openspace, /area/mine/eva) @@ -39056,12 +38747,6 @@ /obj/structure/extinguisher_cabinet/directional/west, /turf/open/floor/iron/dark, /area/station/commons/storage/mining) -"kVe" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/obj/effect/landmark/generic_maintenance_landmark, -/turf/open/floor/plating, -/area/station/maintenance/fore) "kVg" = ( /obj/item/stack/sheet/animalhide/carbon/monkey, /obj/effect/decal/cleanable/blood, @@ -39158,6 +38843,18 @@ /obj/machinery/light/directional/south, /turf/open/floor/iron, /area/station/hallway/primary/starboard) +"kWp" = ( +/obj/machinery/conveyor{ + id = "gulag"; + dir = 4 + }, +/obj/machinery/mineral/processing_unit/gulag{ + dir = 1; + input_dir = 8; + output_dir = 4 + }, +/turf/open/floor/iron, +/area/mine/laborcamp) "kWr" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 4 @@ -39165,6 +38862,16 @@ /obj/effect/turf_decal/tile/yellow/opposingcorners, /turf/open/floor/iron/white, /area/station/maintenance/port/fore) +"kWu" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/structure/cable, +/obj/machinery/power/apc/auto_name/directional/north, +/turf/open/floor/iron, +/area/station/security/prison/mess) "kWw" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 4 @@ -39174,6 +38881,16 @@ }, /turf/open/floor/iron, /area/station/tcommsat/computer) +"kWG" = ( +/obj/structure/cable, +/obj/machinery/computer/prisoner/management, +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 1 + }, +/turf/open/floor/iron/dark/side{ + dir = 1 + }, +/area/mine/laborcamp/security) "kWL" = ( /obj/structure/rack, /obj/item/reagent_containers/cup/bottle/nitrogen{ @@ -39231,10 +38948,6 @@ dir = 1 }, /area/station/engineering/atmos/hfr_room) -"kXf" = ( -/obj/structure/sign/warning/electric_shock/directional/north, -/turf/open/misc/asteroid/snow/icemoon, -/area/icemoon/underground/explored) "kXm" = ( /obj/effect/turf_decal/loading_area{ dir = 1 @@ -39350,22 +39063,10 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/tcommsat/computer) -"kYw" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/mine/laborcamp) "kYF" = ( /mob/living/basic/goose/vomit, /turf/open/floor/wood, /area/station/maintenance/port/aft) -"kYI" = ( -/turf/open/floor/iron/showroomfloor, -/area/station/security/processing) "kYL" = ( /obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -39414,20 +39115,10 @@ }, /turf/open/floor/iron/smooth_large, /area/station/science/cytology) -"kZh" = ( -/obj/structure/cable, -/obj/structure/sign/poster/contraband/random/directional/west, -/turf/open/floor/plating, -/area/station/security/prison/safe) "kZi" = ( /obj/machinery/space_heater, /turf/open/floor/iron/dark/textured, /area/station/security/prison) -"kZn" = ( -/obj/structure/cable, -/obj/machinery/light/floor, -/turf/open/floor/iron/dark, -/area/station/security/prison/rec) "kZt" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 4 @@ -39437,12 +39128,6 @@ "kZu" = ( /turf/closed/wall, /area/mine/production) -"kZI" = ( -/obj/structure/rack, -/obj/effect/spawner/random/contraband/permabrig_weapon, -/obj/machinery/light/small/directional/east, -/turf/open/floor/vault, -/area/station/security/prison/rec) "kZL" = ( /obj/item/target, /obj/structure/window/reinforced/spawner/directional/south, @@ -39481,18 +39166,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark/textured, /area/station/hallway/secondary/exit/departure_lounge) -"law" = ( -/obj/machinery/door/airlock/security/glass{ - name = "Security Vestibule" - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/disposalpipe/segment, -/obj/machinery/door/firedoor, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/mapping_helpers/airlock/access/all/security/general, -/turf/open/floor/iron/smooth, -/area/station/security/processing) "laB" = ( /obj/effect/spawner/random/engineering/atmospherics_portable, /turf/open/floor/plating, @@ -39594,13 +39267,15 @@ /obj/effect/decal/cleanable/confetti, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) -"lbF" = ( -/obj/effect/spawner/structure/window/hollow/reinforced/middle{ - dir = 4 +"lbP" = ( +/obj/structure/window/reinforced/spawner/directional/south, +/obj/structure/flora/bush/jungle/a/style_random, +/obj/structure/flora/bush/sparsegrass/style_random, +/obj/structure/window/reinforced/spawner/directional/east, +/turf/open/misc/ashplanet/wateryrock{ + initial_gas_mix = "o2=22;n2=82;TEMP=293.15" }, -/obj/structure/cable, -/turf/open/floor/plating, -/area/station/engineering/lobby) +/area/station/security/prison/rec) "lch" = ( /obj/machinery/computer/monitor{ dir = 1; @@ -39613,16 +39288,6 @@ /obj/machinery/gateway/centerstation, /turf/open/floor/iron/dark/smooth_large, /area/station/command/gateway) -"lco" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/disposalpipe/segment, -/obj/structure/railing/corner/end/flip{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/smooth, -/area/station/engineering/lobby) "lcs" = ( /obj/structure/reagent_dispensers/plumbed{ dir = 4 @@ -39672,6 +39337,14 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/maintenance/disposal/incinerator) +"lds" = ( +/obj/effect/decal/cleanable/rubble, +/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/turf/open/floor/iron, +/area/mine/production) "ldw" = ( /obj/machinery/door/airlock/maintenance, /obj/effect/mapping_helpers/airlock/unres/delayed, @@ -39765,6 +39438,15 @@ /obj/structure/sign/warning/directional/north, /turf/open/floor/plating/snowed/icemoon, /area/icemoon/underground/explored) +"leV" = ( +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/stripes/white/line{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/white/line, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron/dark/textured, +/area/station/security/brig) "leW" = ( /obj/machinery/power/apc/auto_name/directional/north, /obj/structure/cable, @@ -39898,6 +39580,13 @@ /obj/effect/turf_decal/tile/red/full, /turf/open/floor/iron/dark/textured_large, /area/station/security/brig/entrance) +"lgB" = ( +/obj/machinery/shower/directional/south, +/obj/item/soap/nanotrasen, +/obj/item/bikehorn/rubberducky/plasticducky, +/obj/structure/curtain, +/turf/open/floor/iron/showroomfloor, +/area/mine/laborcamp) "lgD" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -39915,9 +39604,6 @@ }, /turf/open/floor/iron, /area/station/cargo/miningdock) -"lgK" = ( -/turf/closed/wall, -/area/station/security/prison/visit) "lgO" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -40052,6 +39738,20 @@ }, /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/surface/outdoors/less_spawns) +"ljj" = ( +/obj/structure/table/wood, +/obj/item/rag, +/obj/item/clothing/head/collectable/tophat{ + pixel_x = 6; + pixel_y = 5 + }, +/obj/effect/spawner/random/entertainment/gambling{ + pixel_x = -13 + }, +/obj/effect/mapping_helpers/broken_floor, +/obj/effect/turf_decal/siding/wood, +/turf/open/floor/wood, +/area/station/maintenance/fore) "ljl" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -40155,17 +39855,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron/textured, /area/station/commons/storage/primary) -"lkb" = ( -/obj/structure/table, -/obj/item/paper_bin{ - pixel_x = -3; - pixel_y = 7 - }, -/obj/item/inspector, -/turf/open/floor/iron/dark/textured_half{ - dir = 1 - }, -/area/station/security/office) "lkj" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -40181,6 +39870,19 @@ /obj/structure/cable, /turf/open/floor/wood/parquet, /area/station/service/bar/backroom) +"lkp" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/trimline/red/warning{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/red/line{ + dir = 1 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/surface/outdoors/nospawn) "lkr" = ( /obj/structure/closet/firecloset, /turf/open/floor/iron, @@ -40237,6 +39939,13 @@ /obj/structure/extinguisher_cabinet/directional/west, /turf/open/floor/iron/white, /area/station/medical/psychology) +"llS" = ( +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/turf/open/floor/iron/dark/textured_edge, +/area/station/security/prison) "llT" = ( /obj/effect/turf_decal/weather/snow/corner{ dir = 1 @@ -40259,16 +39968,10 @@ }, /turf/open/floor/plating, /area/station/maintenance/aft/greater) -"lmf" = ( -/obj/effect/turf_decal/trimline/red/warning{ - dir = 9 - }, -/obj/effect/turf_decal/stripes/red/line{ - dir = 1 - }, -/obj/machinery/airalarm/directional/north, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) +"lmp" = ( +/obj/machinery/light/small/directional/north, +/turf/open/floor/iron/smooth, +/area/station/engineering/lobby) "lms" = ( /obj/structure/reagent_dispensers/watertank, /turf/open/floor/plating, @@ -40304,20 +40007,13 @@ /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/plating, /area/station/maintenance/port/aft) -"lmK" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/mine/laborcamp) -"lmM" = ( -/obj/structure/cable, -/obj/effect/turf_decal/stripes/line{ +"lmE" = ( +/obj/effect/turf_decal/tile/red{ dir = 1 }, -/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/security/mechbay) +/obj/machinery/firealarm/directional/west, +/turf/open/floor/iron, +/area/station/security/prison/mess) "lmQ" = ( /obj/effect/turf_decal/tile/bar{ dir = 4 @@ -40380,11 +40076,29 @@ /obj/structure/closet/crate/preopen, /turf/open/floor/plating/snowed/icemoon, /area/icemoon/underground/explored) +"lnz" = ( +/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/textured, +/area/station/security/interrogation) "lnC" = ( /obj/machinery/firealarm/directional/south, /obj/effect/turf_decal/trimline/blue/filled/line, /turf/open/floor/iron/white, /area/station/medical/medbay/aft) +"lnF" = ( +/obj/effect/turf_decal/tile/red, +/turf/open/floor/iron/dark/textured_edge{ + dir = 1 + }, +/area/station/security/prison) +"lnH" = ( +/obj/structure/cable, +/obj/effect/mapping_helpers/broken_floor, +/obj/effect/turf_decal/siding/wood, +/turf/open/floor/wood, +/area/station/maintenance/fore) "lnL" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/iron/large, @@ -40406,15 +40120,6 @@ "log" = ( /turf/closed/wall/r_wall, /area/station/maintenance/central/lesser) -"lok" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red/anticorner/contrasted{ - dir = 1 - }, -/turf/open/floor/iron/dark/textured, -/area/station/security/armory/upper) "lom" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -40427,17 +40132,6 @@ /obj/structure/cable, /turf/open/floor/iron/dark/smooth_large, /area/station/command/eva) -"loy" = ( -/obj/effect/turf_decal/tile/red/anticorner/contrasted, -/obj/machinery/button/door/directional/east{ - id = "secmechbay"; - name = "Security Mech Garage Door Controls"; - req_access = list("security") - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/station/security/brig/upper) "loF" = ( /obj/structure/table/wood, /obj/item/toy/mecha/honk{ @@ -40482,6 +40176,13 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos) +"lph" = ( +/obj/item/kirbyplants/organic/plant10, +/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/sepia, +/area/station/security/prison/rec) "lpj" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -40547,11 +40248,6 @@ "lpM" = ( /turf/closed/wall/r_wall, /area/station/command/heads_quarters/captain) -"lpQ" = ( -/obj/effect/landmark/start/hangover, -/obj/structure/cable, -/turf/open/floor/iron/smooth, -/area/station/engineering/lobby) "lpS" = ( /obj/machinery/disposal/bin, /obj/structure/disposalpipe/trunk, @@ -40779,6 +40475,14 @@ }, /turf/open/floor/iron/dark, /area/station/ai/satellite/service) +"lsV" = ( +/obj/machinery/door/poddoor/shutters/preopen{ + id = "gene_shutters"; + name = "Genetics Shutters" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/station/science/genetics) "ltk" = ( /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 8 @@ -40796,10 +40500,6 @@ /obj/structure/cable, /turf/open/floor/iron/textured, /area/station/medical/chem_storage) -"ltH" = ( -/obj/structure/sign/warning/electric_shock/directional/north, -/turf/open/floor/plating/snowed/smoothed/icemoon, -/area/icemoon/underground/explored) "ltP" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 8 @@ -40907,6 +40607,13 @@ }, /turf/open/floor/iron, /area/station/service/hydroponics) +"lvd" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/mine/laborcamp) "lvk" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -41030,6 +40737,9 @@ }, /turf/open/floor/glass/reinforced, /area/station/engineering/atmos/pumproom) +"lwA" = ( +/turf/open/floor/catwalk_floor/iron, +/area/mine/laborcamp) "lwF" = ( /obj/structure/lattice/catwalk, /obj/structure/railing, @@ -41047,6 +40757,15 @@ /obj/effect/spawner/random/structure/steam_vent, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) +"lwK" = ( +/obj/effect/turf_decal/tile/red/half/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/textured_edge, +/area/station/security/prison) "lwO" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -41093,6 +40812,10 @@ /obj/machinery/atmospherics/pipe/bridge_pipe/cyan/visible, /turf/open/floor/iron, /area/station/engineering/atmos) +"lxD" = ( +/obj/structure/sign/nanotrasen/directional/west, +/turf/open/floor/plating/snowed/smoothed/icemoon, +/area/icemoon/surface/outdoors/nospawn) "lxR" = ( /obj/effect/spawner/random/structure/crate_abandoned, /turf/open/floor/plating, @@ -41104,11 +40827,6 @@ /obj/machinery/meter, /turf/open/floor/iron, /area/station/engineering/atmos) -"lxY" = ( -/obj/structure/closet/crate, -/obj/effect/mapping_helpers/no_atoms_ontop, -/turf/open/misc/asteroid/snow/icemoon, -/area/icemoon/surface/outdoors/labor_camp) "lye" = ( /obj/effect/turf_decal/bot_white/right, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ @@ -41284,6 +41002,10 @@ }, /turf/open/floor/iron/dark, /area/station/engineering/lobby) +"lAt" = ( +/obj/structure/flora/rock/icy/style_random, +/turf/open/misc/asteroid/snow/icemoon, +/area/icemoon/surface/outdoors/labor_camp) "lAu" = ( /obj/effect/turf_decal/stripes/corner{ dir = 1 @@ -41431,17 +41153,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/command/bridge) -"lCh" = ( -/obj/machinery/door/airlock/medical/glass{ - id_tag = "MedbayFoyer"; - name = "Medbay" - }, -/obj/effect/mapping_helpers/airlock/access/all/medical/general, -/obj/effect/turf_decal/tile/blue/full, -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/unres/delayed, -/turf/open/floor/iron/large, -/area/station/medical/medbay/lobby) "lCi" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/iron, @@ -41537,16 +41248,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/port/aft) -"lDD" = ( -/obj/machinery/light/small/directional/south, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/button/door/directional/north{ - id = "labor"; - name = "Labor Camp Lockdown"; - req_access = list("brig") - }, -/turf/open/floor/iron, -/area/mine/laborcamp) "lDF" = ( /obj/structure/table, /obj/item/wrench, @@ -41575,11 +41276,12 @@ /obj/machinery/light/directional/west, /turf/open/floor/iron/white, /area/station/science/xenobiology) -"lEa" = ( -/obj/structure/chair/sofa/corner/brown, -/obj/structure/cable, -/turf/open/floor/carpet/blue, -/area/station/security/prison/work) +"lEf" = ( +/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/showroomfloor, +/area/mine/laborcamp) "lEg" = ( /obj/structure/cable, /obj/machinery/door/window/brigdoor/right/directional/north{ @@ -41588,9 +41290,6 @@ }, /turf/open/floor/circuit, /area/station/ai/satellite/chamber) -"lEj" = ( -/turf/open/floor/iron/dark/textured, -/area/station/security/processing) "lEo" = ( /obj/effect/turf_decal/trimline/blue/filled/line, /obj/structure/disposalpipe/segment{ @@ -41662,10 +41361,6 @@ }, /turf/open/floor/iron/dark/textured, /area/station/hallway/primary/starboard) -"lFe" = ( -/obj/structure/bookcase/random/adult, -/turf/open/floor/iron/dark/textured, -/area/station/security/prison/safe) "lFg" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/iron/large, @@ -41692,11 +41387,16 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/solars/starboard/fore) -"lFL" = ( -/obj/effect/turf_decal/trimline/red/warning, -/obj/effect/turf_decal/stripes/red/line, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) +"lFM" = ( +/obj/structure/cable, +/obj/effect/turf_decal/tile/red/anticorner/contrasted{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 1 + }, +/turf/open/floor/iron/dark, +/area/station/security/mechbay) "lFW" = ( /obj/effect/spawner/xmastree/rdrod, /turf/open/floor/iron/white/corner{ @@ -41790,27 +41490,41 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/aft/greater) -"lGK" = ( -/obj/machinery/vending/cigarette, -/obj/machinery/button/door{ - id = "Interrogation"; - name = "Interrogation Shutters"; - pixel_x = -22; - dir = 8 - }, -/turf/open/floor/iron/dark/textured, -/area/station/security/interrogation) "lGN" = ( /obj/effect/landmark/start/botanist, /obj/structure/chair/office/light, /turf/open/floor/glass, /area/station/service/hydroponics) -"lHu" = ( -/obj/structure/closet/secure_closet/brig, +"lGX" = ( +/obj/structure/window/reinforced/spawner/directional/north{ + pixel_y = 2 + }, +/obj/structure/chair, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/siding/red{ + dir = 1 + }, +/turf/open/floor/iron/smooth, +/area/station/security/holding_cell) +"lHa" = ( +/obj/machinery/button/door/directional/north{ + id = "secmechbay"; + name = "Security Mech Garage Door Controls"; + req_access = list("security") + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/cable, -/obj/machinery/firealarm/directional/north, -/turf/open/floor/iron/showroomfloor, -/area/station/security/processing) +/turf/open/floor/iron/dark, +/area/station/security/mechbay) +"lHx" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/structure/sign/warning/cold_temp/directional/north, +/turf/open/floor/iron/smooth, +/area/station/security/eva) "lHA" = ( /obj/effect/landmark/blobstart, /turf/open/floor/iron/smooth, @@ -41834,19 +41548,6 @@ }, /turf/open/floor/iron/dark/corner, /area/station/engineering/atmos/storage/gas) -"lHL" = ( -/obj/structure/cable, -/obj/effect/turf_decal/stripes/corner{ - dir = 1 - }, -/obj/machinery/button/door/directional/north{ - id = "secmechbay"; - name = "Security Mech Garage Door Controls"; - req_access = list("security") - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/dark, -/area/station/security/mechbay) "lHV" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/smartfridge/organ, @@ -42044,11 +41745,6 @@ /obj/machinery/camera/autoname/directional/south, /turf/open/floor/catwalk_floor/iron_dark, /area/station/cargo/bitrunning/den) -"lLN" = ( -/obj/effect/turf_decal/delivery, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/mine/laborcamp) "lLY" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/recharge_floor, @@ -42097,12 +41793,21 @@ /obj/machinery/light/small/directional/south, /turf/open/floor/engine/o2, /area/station/engineering/atmos) -"lMC" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ +"lMI" = ( +/obj/machinery/door/window/brigdoor/left/directional/north{ + req_access = list("brig") + }, +/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/border_only{ dir = 1 }, -/turf/open/floor/iron, -/area/mine/laborcamp/security) +/obj/effect/turf_decal/siding/red{ + dir = 1 + }, +/turf/open/floor/iron/smooth, +/area/station/security/holding_cell) "lNa" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, @@ -42130,6 +41835,14 @@ /obj/machinery/wall_healer/directional/east, /turf/open/floor/iron, /area/station/hallway/primary/fore) +"lNx" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/smooth, +/area/station/engineering/lobby) "lNy" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -42244,20 +41957,6 @@ /obj/structure/cable, /turf/open/floor/wood/parquet, /area/station/service/theater) -"lOP" = ( -/obj/structure/table, -/obj/item/paper, -/obj/item/pen, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/camera/directional/west{ - c_tag = "Labor Camp Cell 1"; - network = list("labor") - }, -/obj/machinery/flasher/directional/west{ - id = "GulagCell 1" - }, -/turf/open/floor/iron, -/area/mine/laborcamp) "lOT" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -42279,13 +41978,11 @@ /obj/structure/window/spawner/directional/west, /turf/open/floor/iron/white, /area/station/medical/medbay/aft) -"lPb" = ( -/obj/structure/railing/corner, -/obj/structure/railing/corner{ - dir = 8 - }, -/turf/open/floor/plating/icemoon, -/area/station/security/execution/education) +"lOW" = ( +/obj/machinery/door/airlock/freezer, +/obj/structure/plasticflaps/kitchen, +/turf/open/floor/iron/kitchen_coldroom/freezerfloor, +/area/station/security/prison/mess) "lPc" = ( /obj/machinery/ai_slipper{ uses = 10 @@ -42294,6 +41991,10 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/dark, /area/station/ai/satellite/service) +"lPe" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/station/security/prison/visit) "lPh" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/public/glass{ @@ -42478,6 +42179,16 @@ /obj/structure/mineral_door/wood, /turf/open/floor/wood, /area/station/maintenance/space_hut/cabin) +"lRb" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/obj/structure/railing{ + dir = 1 + }, +/obj/effect/turf_decal/tile/brown/opposingcorners, +/turf/open/floor/iron, +/area/mine/production) "lRc" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable, @@ -42532,19 +42243,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/storage) -"lRE" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/light/directional/north, -/turf/open/floor/iron, -/area/mine/laborcamp/security) -"lRF" = ( -/obj/structure/rack, -/obj/machinery/syndicatebomb/training, -/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/dark/smooth_half, -/area/station/security/office) "lRI" = ( /obj/machinery/door/airlock/external{ glass = 1; @@ -42622,13 +42320,6 @@ }, /turf/open/floor/iron/dark/smooth_half, /area/station/medical/morgue) -"lTa" = ( -/obj/effect/turf_decal/trimline/red/warning{ - dir = 10 - }, -/obj/effect/turf_decal/stripes/red/line, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) "lTl" = ( /obj/structure/closet/crate/grave, /turf/open/misc/dirt{ @@ -42659,6 +42350,20 @@ dir = 10 }, /area/station/science/research) +"lUo" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/mineral/labor_points_checker{ + pixel_x = 32; + pixel_y = -2 + }, +/obj/structure/cable, +/obj/machinery/camera/directional/east{ + c_tag = "Labor Camp - Operations"; + network = list("labor","prison") + }, +/turf/open/floor/iron, +/area/mine/laborcamp) "lUw" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -42848,16 +42553,6 @@ /obj/machinery/mining_weather_monitor/directional/north, /turf/open/floor/iron/dark, /area/station/hallway/secondary/entry) -"lXJ" = ( -/obj/structure/railing{ - dir = 1 - }, -/obj/structure/rack, -/obj/item/storage/medkit/brute, -/turf/open/floor/iron/dark/side{ - dir = 9 - }, -/area/station/security/prison/workout) "lYd" = ( /obj/machinery/computer/order_console/mining, /obj/effect/decal/cleanable/dirt, @@ -42944,18 +42639,17 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/iron, /area/station/commons/dorms) -"maM" = ( -/obj/machinery/hydroponics/constructable, -/obj/item/seeds/soya, -/obj/effect/turf_decal/tile/green/half/contrasted{ - dir = 4 - }, -/obj/machinery/light/directional/east, -/obj/effect/turf_decal/siding/green{ - dir = 4 +"maK" = ( +/obj/machinery/door/airlock/security{ + name = "Labor Camp Monitoring" }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/mapping_helpers/airlock/access/all/security/brig, +/obj/effect/turf_decal/tile/red/fourcorners, /turf/open/floor/iron/dark, -/area/mine/laborcamp) +/area/mine/laborcamp/security) "maO" = ( /obj/machinery/disposal/bin, /obj/structure/window/reinforced/spawner/directional/south, @@ -42994,15 +42688,6 @@ /obj/structure/rack, /turf/open/floor/iron/dark, /area/station/engineering/supermatter/room) -"mbe" = ( -/obj/structure/toilet/greyscale{ - cistern_open = 1; - dir = 1 - }, -/obj/effect/spawner/random/entertainment/cigar, -/obj/machinery/light/small/directional/south, -/turf/open/floor/iron/showroomfloor, -/area/station/security/prison/toilet) "mbk" = ( /obj/effect/landmark/start/hangover, /obj/effect/turf_decal/tile/blue{ @@ -43028,20 +42713,11 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/secondary/exit/departure_lounge) -"mbp" = ( -/obj/structure/chair/wood{ - dir = 4 - }, -/obj/effect/turf_decal/siding/wood{ - dir = 8 - }, -/obj/effect/landmark/start/prisoner, -/turf/open/floor/wood, -/area/station/security/prison/rec) -"mbq" = ( -/obj/structure/closet/crate, -/turf/open/floor/plating/snowed/smoothed/icemoon, -/area/icemoon/surface/outdoors/labor_camp) +"mbs" = ( +/obj/effect/turf_decal/tile/red/half/contrasted, +/obj/item/radio/intercom/directional/south, +/turf/open/floor/iron, +/area/station/security/brig/upper) "mbt" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -43147,16 +42823,6 @@ /obj/machinery/iv_drip, /turf/open/floor/iron/white, /area/station/medical/treatment_center) -"mcr" = ( -/obj/structure/cable, -/obj/machinery/door/airlock/security/glass{ - name = "Labor Camp Monitoring" - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/mapping_helpers/airlock/access/all/security/brig, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "mct" = ( /obj/machinery/light/small/directional/west, /obj/effect/turf_decal/tile/brown/half/contrasted{ @@ -43166,12 +42832,6 @@ dir = 1 }, /area/mine/eva/lower) -"mcF" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, -/turf/open/floor/carpet/black, -/area/station/security/prison/safe) "mcH" = ( /obj/structure/chair{ dir = 1 @@ -43364,6 +43024,12 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) +"mfQ" = ( +/obj/structure/cable, +/obj/machinery/space_heater, +/obj/effect/mapping_helpers/broken_floor, +/turf/open/floor/wood, +/area/station/maintenance/fore) "mfV" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, @@ -43439,6 +43105,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, /turf/open/floor/engine, /area/station/maintenance/disposal/incinerator) +"mgN" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/mine/laborcamp) "mgS" = ( /obj/effect/spawner/structure/window/hollow/reinforced/middle{ dir = 4 @@ -43485,6 +43158,11 @@ /obj/effect/turf_decal/tile/red/half/contrasted, /turf/open/floor/iron/dark/textured_half, /area/station/security/office) +"mhN" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/sign/warning/directional/west, +/turf/open/floor/plating, +/area/station/maintenance/fore) "mhQ" = ( /turf/closed/wall/r_wall, /area/station/command/teleporter) @@ -43523,6 +43201,35 @@ /obj/structure/railing/corner, /turf/open/floor/plating, /area/station/maintenance/port/aft) +"miM" = ( +/obj/structure/table/glass, +/obj/item/book/manual/wiki/infections{ + pixel_x = 5; + pixel_y = 3 + }, +/obj/item/book/manual/wiki/surgery{ + pixel_x = -4; + pixel_y = 3 + }, +/obj/item/book/manual/wiki/medicine{ + pixel_x = -4; + pixel_y = 7 + }, +/obj/item/book/manual/wiki/chemistry{ + pixel_x = 5; + pixel_y = 8 + }, +/obj/effect/turf_decal/tile/blue/full, +/obj/item/tgui_book/manual/dsm{ + pixel_x = -4; + pixel_y = 12 + }, +/obj/item/tgui_book/manual/idc{ + pixel_x = 4; + pixel_y = 13 + }, +/turf/open/floor/iron/dark/smooth_large, +/area/station/command/heads_quarters/cmo) "miS" = ( /obj/structure/table, /obj/item/stack/cable_coil{ @@ -43599,11 +43306,15 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark, /area/station/maintenance/disposal/incinerator) -"mkb" = ( -/obj/structure/rack, -/obj/item/clothing/head/costume/fancy, -/turf/open/floor/iron/dark/textured, -/area/station/security/prison) +"mkj" = ( +/obj/structure/railing, +/obj/structure/cable, +/obj/machinery/door/poddoor/shutters/window{ + id = "executionshutters"; + name = "Exterior Shutters" + }, +/turf/open/floor/plating, +/area/station/security/execution/education) "mku" = ( /obj/effect/spawner/random/structure/grille, /obj/effect/decal/cleanable/glass, @@ -43657,17 +43368,12 @@ /obj/structure/sign/warning/electric_shock/directional/north, /turf/open/floor/iron/recharge_floor, /area/station/maintenance/department/electrical) -"mlO" = ( -/obj/structure/disposalpipe/segment, -/obj/machinery/airalarm/directional/east, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +"mlE" = ( +/obj/structure/fence/cut/medium{ + dir = 4 }, -/obj/effect/turf_decal/tile/blue/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron/white, -/area/station/science/genetics) +/turf/open/misc/asteroid/snow/icemoon, +/area/icemoon/surface/outdoors/nospawn) "mlR" = ( /obj/machinery/newscaster/directional/west, /obj/item/radio/intercom/directional/west{ @@ -43898,14 +43604,6 @@ /obj/machinery/computer/quantum_console, /turf/open/floor/iron/dark/smooth_corner, /area/station/cargo/bitrunning/den) -"mpf" = ( -/obj/structure/cable, -/obj/structure/table/wood, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/wood, -/area/station/security/prison/rec) "mpg" = ( /obj/machinery/door/airlock/grunge{ name = "Mining Aux Mechbay" @@ -43916,6 +43614,11 @@ /obj/effect/mapping_helpers/airlock/access/all/supply/mining, /turf/open/floor/plating, /area/mine/mechbay) +"mpi" = ( +/obj/structure/cable, +/obj/effect/spawner/structure/window/hollow/reinforced/middle, +/turf/open/floor/plating, +/area/mine/laborcamp) "mpl" = ( /obj/structure/cable, /obj/machinery/power/apc/auto_name/directional/north, @@ -44155,13 +43858,6 @@ /obj/effect/turf_decal/siding/wood, /turf/open/floor/wood, /area/station/security/courtroom) -"mts" = ( -/obj/effect/turf_decal/loading_area{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/mine/laborcamp) "mtx" = ( /obj/machinery/door/poddoor/massdriver_ordnance, /obj/machinery/atmos_shield_gen/active{ @@ -44201,9 +43897,22 @@ }, /turf/open/floor/iron, /area/station/service/hydroponics) +"mtA" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable, +/obj/machinery/door/firedoor, +/turf/open/floor/plating, +/area/station/security/lockers) "mtI" = ( /turf/closed/wall, /area/station/science/robotics/lab) +"mtQ" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, +/turf/open/floor/iron/dark, +/area/station/security/prison/rec) "mtS" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -44258,6 +43967,24 @@ /obj/item/stack/cable_coil, /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/surface/outdoors/nospawn) +"muL" = ( +/obj/machinery/computer/security/hos{ + dir = 4 + }, +/obj/machinery/requests_console/directional/north{ + department = "Head of Security's Desk"; + name = "Head of Security Requests Console" + }, +/obj/effect/mapping_helpers/requests_console/announcement, +/obj/effect/mapping_helpers/requests_console/information, +/obj/effect/mapping_helpers/requests_console/assistance, +/obj/item/radio/intercom/directional/west, +/obj/machinery/button/door/directional/north{ + id = "hosspace"; + name = "Icemoon Shutters Control" + }, +/turf/open/floor/carpet/royalblue, +/area/station/command/heads_quarters/hos) "muP" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -44277,9 +44004,12 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/wood, /area/station/command/heads_quarters/captain) -"mvl" = ( -/turf/closed/wall/r_wall, -/area/station/security/interrogation) +"mvn" = ( +/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/security/eva) "mvv" = ( /turf/open/floor/wood, /area/station/security/courtroom) @@ -44343,6 +44073,15 @@ /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) +"mwB" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/structure/fence/door{ + dir = 4 + }, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/surface/outdoors/nospawn) "mwF" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/shutters/preopen{ @@ -44434,6 +44173,11 @@ }, /turf/open/floor/iron/dark, /area/station/medical/morgue) +"myc" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/turf/open/floor/catwalk_floor/iron_smooth, +/area/station/security/eva) "mye" = ( /obj/machinery/door/airlock/maintenance, /obj/structure/disposalpipe/segment, @@ -44478,17 +44222,6 @@ /obj/effect/mapping_helpers/airlock/access/any/medical/maintenance, /turf/open/floor/plating, /area/station/maintenance/department/medical/morgue) -"myQ" = ( -/obj/structure/falsewall, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/plating, -/area/station/security/prison/safe) -"myW" = ( -/obj/structure/ore_box, -/turf/open/floor/plating/snowed/smoothed/icemoon, -/area/icemoon/surface/outdoors/labor_camp) "myX" = ( /obj/machinery/light/directional/north, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -44532,10 +44265,6 @@ /obj/effect/turf_decal/bot_red, /turf/open/floor/iron/dark, /area/station/science/ordnance/office) -"mzl" = ( -/obj/structure/railing, -/turf/open/misc/asteroid/snow/icemoon, -/area/icemoon/surface/outdoors/labor_camp) "mzr" = ( /obj/structure/table, /obj/item/exodrone{ @@ -44566,6 +44295,15 @@ dir = 8 }, /area/station/engineering/atmos/storage/gas) +"mzG" = ( +/obj/structure/railing{ + dir = 8 + }, +/obj/structure/stairs/south, +/turf/open/floor/iron/stairs/medium{ + dir = 1 + }, +/area/mine/laborcamp/security) "mzH" = ( /obj/effect/landmark/firealarm_sanity, /turf/open/openspace, @@ -44585,6 +44323,10 @@ /obj/effect/turf_decal/tile/red/full, /turf/open/floor/iron/dark/textured_large, /area/station/security/brig/entrance) +"mzR" = ( +/obj/effect/spawner/random/structure/grille, +/turf/open/floor/plating, +/area/station/maintenance/department/security) "mzX" = ( /obj/structure/disposalpipe/sorting/mail, /obj/effect/mapping_helpers/mail_sorting/service/bar, @@ -44648,6 +44390,13 @@ /obj/structure/cable, /turf/open/floor/carpet, /area/station/security/prison/rec) +"mAQ" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 1 + }, +/obj/structure/cable, +/turf/open/floor/iron/dark, +/area/station/security/execution/education) "mBa" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -44801,6 +44550,10 @@ /obj/machinery/light/small/directional/north, /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/underground/explored) +"mCF" = ( +/obj/machinery/camera/autoname/directional/north, +/turf/open/floor/iron/smooth, +/area/station/engineering/lobby) "mCP" = ( /obj/machinery/light/small/red/directional/south, /obj/structure/chair{ @@ -44816,12 +44569,6 @@ /obj/machinery/telecomms/server/presets/common, /turf/open/floor/iron/dark/telecomms, /area/station/tcommsat/server) -"mDo" = ( -/obj/structure/bed/double, -/obj/item/bedsheet/black/double, -/obj/structure/sign/poster/contraband/random/directional/east, -/turf/open/floor/carpet/black, -/area/station/security/prison/safe) "mDq" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/firealarm/directional/east, @@ -44841,6 +44588,12 @@ /obj/item/stamp/head/ce, /turf/open/floor/iron, /area/station/command/heads_quarters/ce) +"mDN" = ( +/obj/machinery/suit_storage_unit/security, +/obj/effect/turf_decal/tile/red/half/contrasted, +/obj/effect/turf_decal/bot/left, +/turf/open/floor/iron/smooth, +/area/station/security/eva) "mDS" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -44855,14 +44608,6 @@ "mDX" = ( /turf/open/floor/engine/n2, /area/station/engineering/atmos) -"mEb" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/button/flasher{ - id = "GulagCell 3"; - pixel_y = -30 - }, -/turf/open/floor/iron, -/area/mine/laborcamp) "mEg" = ( /obj/structure/cable, /obj/machinery/holopad/secure, @@ -44912,6 +44657,16 @@ "mEJ" = ( /turf/closed/wall/r_wall, /area/station/science/genetics) +"mEK" = ( +/obj/machinery/camera/directional/west{ + c_tag = "Security - Upper Brig West" + }, +/obj/machinery/firealarm/directional/west, +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/security/brig/upper) "mEL" = ( /obj/machinery/atmospherics/components/binary/valve/digital{ dir = 4 @@ -45008,15 +44763,6 @@ "mFE" = ( /turf/closed/wall, /area/station/medical/surgery/aft) -"mFQ" = ( -/obj/machinery/flasher/portable, -/obj/machinery/door/window/brigdoor/left/directional/north{ - name = "Flash Storage"; - req_access = list("brig") - }, -/obj/structure/cable, -/turf/open/floor/iron/smooth, -/area/station/security/brig/upper) "mFU" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -45102,19 +44848,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/general/visible, /turf/open/floor/iron/dark, /area/station/science/explab) -"mHe" = ( -/obj/machinery/conveyor{ - dir = 6; - id = "mining_internal" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 5 - }, -/obj/machinery/power/apc/auto_name/directional/north, -/obj/structure/cable, -/obj/machinery/brm, -/turf/open/floor/iron, -/area/mine/production) "mHn" = ( /obj/structure/cable, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -45247,6 +44980,19 @@ "mJz" = ( /turf/open/floor/iron/dark, /area/icemoon/underground/explored) +"mJK" = ( +/obj/item/kirbyplants/photosynthetic, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 1 + }, +/obj/machinery/light/small/directional/south, +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 4 + }, +/turf/open/floor/iron/dark/side{ + dir = 4 + }, +/area/mine/laborcamp/security) "mJM" = ( /obj/effect/turf_decal/tile/blue/half/contrasted{ dir = 1 @@ -45320,6 +45066,19 @@ }, /turf/open/floor/iron/large, /area/station/hallway/secondary/entry) +"mKL" = ( +/obj/item/kirbyplants/photosynthetic, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 1 + }, +/obj/machinery/light/small/directional/south, +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 8 + }, +/turf/open/floor/iron/dark/side{ + dir = 8 + }, +/area/mine/laborcamp/security) "mKO" = ( /obj/structure/cable, /turf/open/floor/iron/dark, @@ -45401,6 +45160,17 @@ /obj/machinery/telecomms/message_server/preset, /turf/open/floor/iron/dark/telecomms, /area/station/tcommsat/server) +"mMx" = ( +/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/red/half/contrasted{ + dir = 8 + }, +/turf/open/floor/iron/dark/side{ + dir = 8 + }, +/area/mine/laborcamp/security) "mMy" = ( /obj/machinery/camera/directional/south{ c_tag = "Security - Permabrig Upper Hallway South"; @@ -45416,6 +45186,18 @@ /obj/machinery/firealarm/directional/west, /turf/open/floor/carpet, /area/station/service/library) +"mML" = ( +/obj/effect/turf_decal/stripes/red/line{ + dir = 9 + }, +/obj/machinery/light/small/red/directional/east, +/obj/machinery/door/poddoor/shutters/window/preopen{ + name = "Firing Range Shutters"; + dir = 1; + id = "firingrangeshuttersoutside" + }, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/surface/outdoors/nospawn) "mMM" = ( /turf/closed/wall/r_wall, /area/station/security/prison) @@ -45493,6 +45275,11 @@ "mNY" = ( /turf/closed/wall/r_wall, /area/station/maintenance/port/aft) +"mOa" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/landmark/start/prisoner, +/turf/open/floor/iron, +/area/station/security/prison/mess) "mOc" = ( /obj/machinery/disposal/bin, /obj/structure/disposalpipe/trunk{ @@ -45574,17 +45361,6 @@ /obj/effect/turf_decal/siding/wood, /turf/open/floor/iron/dark/textured_half, /area/station/service/hydroponics) -"mPp" = ( -/obj/structure/table, -/obj/item/paper_bin{ - pixel_x = -3; - pixel_y = 7 - }, -/obj/item/pen, -/obj/machinery/light/small/directional/north, -/obj/structure/sign/poster/official/report_crimes/directional/north, -/turf/open/floor/iron, -/area/mine/laborcamp) "mPq" = ( /obj/machinery/light/small/directional/north, /turf/open/floor/plating/snowed/smoothed/icemoon, @@ -45654,12 +45430,6 @@ }, /turf/open/floor/plating/snowed/coldroom, /area/station/service/kitchen/coldroom) -"mQq" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 1 - }, -/turf/open/floor/iron/smooth, -/area/mine/laborcamp/security) "mQx" = ( /obj/structure/rack, /obj/item/controller, @@ -45684,6 +45454,12 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron/white, /area/station/science/xenobiology) +"mRq" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/mine/laborcamp) "mRr" = ( /obj/structure/cable, /obj/effect/decal/cleanable/dirt, @@ -45694,6 +45470,34 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/iron, /area/station/hallway/primary/starboard) +"mRD" = ( +/obj/structure/chair/pew/left{ + dir = 8 + }, +/turf/open/floor/wood/large, +/area/station/security/prison/rec) +"mRE" = ( +/obj/structure/closet/secure_closet/labor_camp_security, +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 9 + }, +/obj/item/clothing/suit/hooded/wintercoat/security, +/obj/item/megaphone/sec{ + pixel_y = 6 + }, +/obj/item/bodybag/environmental/prisoner{ + pixel_y = 5 + }, +/obj/item/bodybag/environmental/prisoner{ + pixel_y = 5 + }, +/obj/item/bodybag/environmental/prisoner{ + pixel_y = 5 + }, +/turf/open/floor/iron/dark/side{ + dir = 9 + }, +/area/mine/laborcamp/security) "mRG" = ( /obj/structure/table, /obj/item/book/manual/wiki/atmospherics, @@ -45782,14 +45586,6 @@ }, /turf/open/floor/engine/air, /area/station/engineering/atmos) -"mTI" = ( -/obj/structure/sink/kitchen/directional/south{ - desc = "A sink used for washing one's hands and face. It looks rusty and home-made"; - name = "old sink" - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/turf/open/floor/iron/freezer, -/area/mine/laborcamp) "mTS" = ( /obj/effect/turf_decal/tile/blue/half/contrasted{ dir = 4 @@ -45837,6 +45633,14 @@ /obj/structure/cable, /turf/open/floor/catwalk_floor/iron_dark, /area/station/ai/upload/chamber) +"mVr" = ( +/obj/structure/flora/grass/jungle/b/style_random, +/obj/structure/window/reinforced/spawner/directional/south, +/obj/item/throwing_star/toy, +/turf/open/misc/ashplanet/wateryrock{ + initial_gas_mix = "o2=22;n2=82;TEMP=293.15" + }, +/area/station/security/prison/rec) "mVw" = ( /obj/machinery/requests_console/directional/west{ department = "Captain's Desk"; @@ -45952,6 +45756,16 @@ /obj/structure/cable, /turf/open/floor/iron/dark/smooth_large, /area/station/security/checkpoint/customs/auxiliary) +"mWL" = ( +/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/red{ + dir = 1 + }, +/obj/machinery/airalarm/directional/north, +/turf/open/floor/iron, +/area/station/security/prison/mess) "mWM" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -46004,17 +45818,6 @@ }, /turf/open/floor/iron/white, /area/station/science/ordnance/office) -"mXi" = ( -/obj/machinery/ai_slipper{ - uses = 10 - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable/layer3, -/mob/living/simple_animal/bot/secbot/pingsky, -/turf/open/floor/iron/dark, -/area/station/ai/satellite/interior) "mXj" = ( /obj/machinery/door/airlock/external{ name = "External Access" @@ -46026,14 +45829,6 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/port/fore) -"mXl" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/camera/directional/east{ - c_tag = "Labor Camp Library"; - network = list("labor") - }, -/turf/open/floor/iron, -/area/mine/laborcamp) "mXA" = ( /obj/effect/landmark/blobstart, /obj/effect/mapping_helpers/burnt_floor, @@ -46059,20 +45854,20 @@ }, /turf/open/floor/plating, /area/station/hallway/secondary/entry) +"mXX" = ( +/obj/machinery/atmospherics/pipe/multiz/scrubbers/visible/layer2, +/obj/machinery/atmospherics/pipe/multiz/supply/visible/layer4, +/obj/structure/sign/poster/contraband/random/directional/north, +/turf/open/floor/plating, +/area/station/maintenance/department/security) +"mXY" = ( +/obj/machinery/airalarm/directional/west, +/obj/structure/table, +/turf/open/floor/iron, +/area/mine/laborcamp) "mYh" = ( /turf/open/floor/iron/dark, /area/station/ai/satellite/chamber) -"mYi" = ( -/obj/machinery/door/airlock/medical/glass{ - name = "Infirmary" - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/tile/blue/opposingcorners{ - dir = 1 - }, -/turf/open/floor/iron/white, -/area/mine/laborcamp) "mYp" = ( /obj/machinery/door/firedoor/heavy, /obj/machinery/door/poddoor/preopen{ @@ -46198,11 +45993,6 @@ /obj/structure/sign/warning/biohazard/directional/north, /turf/open/floor/plating, /area/station/maintenance/aft/lesser) -"mZJ" = ( -/obj/effect/decal/cleanable/dirt, -/obj/item/radio/intercom/directional/north, -/turf/open/floor/iron, -/area/mine/laborcamp) "mZT" = ( /obj/structure/table/wood, /obj/item/cigarette/cigar{ @@ -46244,6 +46034,24 @@ }, /turf/open/floor/wood, /area/station/service/library) +"naR" = ( +/obj/machinery/door/airlock/maintenance{ + name = "Genetics Lab Maintenance" + }, +/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/mapping_helpers/airlock/access/all/science/genetics, +/obj/machinery/door/poddoor/shutters/preopen{ + dir = 4; + id = "gene_desk_shutters"; + name = "Genetics Shutters" + }, +/turf/open/floor/plating, +/area/station/maintenance/starboard/upper) "naU" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -46304,16 +46112,6 @@ }, /turf/open/floor/stone, /area/mine/eva/lower) -"nbw" = ( -/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/red/half/contrasted{ - dir = 4 - }, -/obj/item/kirbyplants/random, -/turf/open/floor/iron/dark/textured, -/area/station/security/office) "nbz" = ( /obj/structure/chair/wood, /obj/effect/mapping_helpers/no_atoms_ontop, @@ -46742,14 +46540,6 @@ }, /turf/open/floor/iron/white/corner, /area/mine/living_quarters) -"ngl" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/obj/effect/decal/cleanable/dirt, -/obj/effect/landmark/event_spawn, -/turf/open/floor/iron, -/area/mine/production) "ngn" = ( /obj/effect/spawner/random/structure/closet_empty/crate, /obj/effect/turf_decal/stripes/line, @@ -46767,6 +46557,16 @@ }, /turf/open/floor/iron/dark, /area/station/engineering/atmos/mix) +"ngE" = ( +/obj/machinery/conveyor{ + dir = 6; + id = "mining_internal" + }, +/obj/machinery/power/apc/auto_name/directional/north, +/obj/structure/cable, +/obj/machinery/brm, +/turf/open/floor/iron, +/area/mine/production) "ngM" = ( /obj/structure/lattice/catwalk, /obj/structure/fence/door{ @@ -46792,6 +46592,13 @@ /obj/structure/mirror/directional/west, /turf/open/floor/iron/showroomfloor, /area/station/security/prison/toilet) +"nhn" = ( +/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, +/turf/open/floor/iron, +/area/mine/laborcamp) "nhw" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -46823,17 +46630,6 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/iron, /area/station/maintenance/central/greater) -"nhT" = ( -/obj/machinery/door/airlock/external{ - glass = 1; - name = "Labor Camp External Airlock"; - opacity = 0 - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 1 - }, -/turf/open/floor/plating, -/area/mine/laborcamp) "nia" = ( /obj/machinery/door/poddoor/shutters/window{ dir = 8; @@ -46872,6 +46668,14 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/white, /area/station/medical/medbay/central) +"nix" = ( +/obj/machinery/mineral/labor_claim_console{ + pixel_x = 32; + pixel_y = -2 + }, +/obj/structure/cable, +/turf/open/floor/iron, +/area/mine/laborcamp) "niy" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, @@ -46997,12 +46801,6 @@ /obj/item/storage/fancy/cigarettes, /turf/open/floor/plating, /area/station/maintenance/port/aft) -"nkP" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/vault, -/area/station/security/prison/rec) "nli" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 8 @@ -47089,6 +46887,12 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/science/xenobiology) +"nmk" = ( +/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_edge, +/area/station/security/lockers) "nmm" = ( /obj/structure/window/reinforced/spawner/directional/south, /obj/structure/window/reinforced/spawner/directional/north, @@ -47105,19 +46909,6 @@ }, /turf/open/floor/iron, /area/station/commons/dorms) -"nmq" = ( -/obj/machinery/power/apc/auto_name/directional/north, -/obj/structure/cable, -/obj/structure/table/reinforced, -/obj/effect/spawner/random/engineering/tool{ - pixel_x = -11 - }, -/obj/effect/spawner/random/engineering/tool{ - pixel_x = 5; - pixel_y = 8 - }, -/turf/open/floor/iron, -/area/station/security/mechbay) "nmr" = ( /obj/machinery/hydroponics/soil, /obj/item/cultivator, @@ -47214,6 +47005,21 @@ }, /turf/open/floor/iron, /area/station/maintenance/disposal/incinerator) +"nnt" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/camera/directional/north{ + c_tag = "Security - Upper Permabrig Cafeteria"; + network = list("ss13","prison") + }, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/machinery/digital_clock/directional/north, +/obj/item/kirbyplants/organic/plant14, +/turf/open/floor/iron, +/area/station/security/prison/mess) "nnw" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/general/visible, /turf/closed/wall/r_wall, @@ -47261,6 +47067,17 @@ }, /turf/open/floor/plating, /area/station/maintenance/department/chapel) +"noz" = ( +/obj/structure/table, +/obj/item/paper_bin{ + pixel_x = -3; + pixel_y = 7 + }, +/obj/item/folder/red, +/turf/open/floor/iron/dark/textured_half{ + dir = 1 + }, +/area/station/security/office) "noJ" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -47378,11 +47195,6 @@ "npD" = ( /turf/closed/wall/r_wall, /area/station/maintenance/aft/greater) -"npH" = ( -/obj/effect/decal/cleanable/dirt, -/obj/item/reagent_containers/cup/bucket, -/turf/open/floor/iron/dark, -/area/mine/laborcamp) "npJ" = ( /obj/machinery/atmospherics/pipe/layer_manifold/violet/visible, /turf/open/floor/iron, @@ -47556,27 +47368,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/engine, /area/station/engineering/supermatter/room) -"nsL" = ( -/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, -/obj/effect/turf_decal/tile/red/half/contrasted, -/turf/open/floor/iron/dark/side{ - dir = 1 - }, -/area/station/security/processing) "nsM" = ( /obj/machinery/light/small/directional/west, /obj/structure/sign/warning/directional/west, /turf/open/openspace, /area/station/commons/storage/mining) -"nsO" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/dark/textured, -/area/station/security/interrogation) "nsQ" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable, @@ -47596,6 +47392,28 @@ }, /turf/open/floor/iron/dark, /area/station/security/checkpoint/science) +"nte" = ( +/obj/structure/table/reinforced, +/obj/item/gun/energy/laser/carbine/practice{ + pixel_x = 3; + pixel_y = -3 + }, +/obj/item/gun/energy/laser/practice, +/obj/machinery/power/apc/auto_name/directional/south, +/obj/effect/turf_decal/tile/red/half/contrasted, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/item/gun/energy/laser/carbine/practice{ + pixel_x = 3; + pixel_y = -3 + }, +/obj/item/gun/energy/laser/practice, +/obj/item/clothing/ears/earmuffs, +/obj/item/clothing/ears/earmuffs, +/obj/item/clothing/glasses/sunglasses, +/obj/item/clothing/glasses/sunglasses, +/turf/open/floor/iron/dark, +/area/station/security/range) "ntl" = ( /turf/closed/wall/r_wall, /area/station/service/lawoffice) @@ -47611,18 +47429,14 @@ /obj/machinery/light/small/directional/north, /turf/open/floor/iron/dark, /area/station/medical/morgue) -"ntq" = ( -/obj/machinery/door/window/brigdoor/left/directional/north{ - req_access = list("brig") +"ntA" = ( +/obj/machinery/mech_bay_recharge_port{ + dir = 8 }, /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/border_only{ - dir = 1 - }, +/obj/machinery/airalarm/directional/south, /turf/open/floor/iron, -/area/station/security/processing) +/area/station/security/mechbay) "ntE" = ( /obj/machinery/status_display/ai/directional/north, /obj/item/aquarium_kit, @@ -47654,11 +47468,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central) -"nub" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/landmark/event_spawn, -/turf/open/floor/iron/cafeteria, -/area/station/security/prison/mess) "nud" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/pink, @@ -47681,6 +47490,25 @@ }, /turf/open/floor/stone, /area/station/service/bar/atrium) +"nuE" = ( +/obj/effect/turf_decal/caution/stand_clear{ + dir = 1 + }, +/obj/effect/turf_decal/siding/dark_red, +/obj/effect/turf_decal/siding/dark_red{ + dir = 1 + }, +/obj/machinery/door/poddoor/shutters/window{ + name = "Security Mech Bay Shutters"; + id = "secmechbay"; + dir = 1 + }, +/turf/open/floor/iron/dark/textured_half, +/area/station/security/mechbay) +"nuH" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron/dark/textured, +/area/station/security/armory/upper) "nuN" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -47710,6 +47538,24 @@ /obj/machinery/light/small/directional/north, /turf/open/floor/plating/snowed/icemoon, /area/icemoon/underground/explored) +"nvw" = ( +/obj/structure/table/glass, +/obj/item/stack/medical/wrap/gauze{ + pixel_x = 1 + }, +/obj/item/stack/medical/mesh, +/obj/effect/turf_decal/stripes/corner{ + dir = 8 + }, +/obj/machinery/button/door/directional/west{ + id = "chemistry_access_shutters"; + name = "Chemistry Access Shutter Control"; + req_access = list("medical") + }, +/obj/item/stack/medical/suture, +/obj/effect/turf_decal/tile/blue/full, +/turf/open/floor/iron/large, +/area/station/medical/treatment_center) "nvx" = ( /obj/machinery/airalarm/directional/east, /obj/effect/landmark/event_spawn, @@ -47769,17 +47615,6 @@ /obj/machinery/duct, /turf/open/floor/iron, /area/station/engineering/atmos) -"nvY" = ( -/obj/structure/chair/stool/directional/west, -/obj/effect/landmark/start/geneticist, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/turf_decal/tile/blue/anticorner/contrasted{ - dir = 1 - }, -/turf/open/floor/iron/white, -/area/station/science/genetics) "nwn" = ( /obj/effect/turf_decal/siding/wood{ dir = 4 @@ -47943,16 +47778,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/aft/lesser) -"nyP" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 8 - }, -/obj/structure/sign/poster/official/random/directional/south, -/obj/effect/turf_decal/tile/red/half/contrasted, -/turf/open/floor/iron/dark/textured_edge{ - dir = 1 - }, -/area/station/security/prison) "nyQ" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -47976,6 +47801,13 @@ /obj/machinery/digital_clock/directional/north, /turf/open/floor/iron/grimy, /area/station/hallway/secondary/entry) +"nyV" = ( +/obj/item/cigbutt/roach{ + pixel_x = 4; + pixel_y = -2 + }, +/turf/open/floor/plating, +/area/station/security/prison) "nyX" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 8 @@ -48005,13 +47837,6 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/iron/smooth, /area/station/security/execution/transfer) -"nzl" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/obj/item/radio/intercom/directional/east{ - pixel_y = -6 - }, -/turf/open/floor/iron/smooth, -/area/station/security/execution/transfer) "nzn" = ( /obj/structure/cable, /obj/effect/decal/cleanable/dirt/dust, @@ -48290,14 +48115,6 @@ /obj/effect/turf_decal/stripes/corner, /turf/open/floor/plating, /area/station/maintenance/starboard/upper) -"nCh" = ( -/obj/structure/disposalpipe/segment, -/obj/machinery/light/directional/east, -/obj/effect/turf_decal/tile/red/half/contrasted{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/security/brig/upper) "nCi" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/turf_decal/tile/red/half{ @@ -48352,11 +48169,6 @@ }, /turf/open/floor/wood, /area/station/commons/dorms) -"nCQ" = ( -/obj/machinery/atmospherics/pipe/multiz/scrubbers/visible/layer2, -/obj/machinery/atmospherics/pipe/multiz/supply/visible/layer4, -/turf/open/floor/plating, -/area/station/security/prison/safe) "nCV" = ( /obj/effect/turf_decal/trimline/yellow/filled/line, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ @@ -48367,6 +48179,17 @@ }, /turf/open/floor/iron/white, /area/station/medical/treatment_center) +"nDc" = ( +/obj/structure/closet/secure_closet/injection, +/obj/item/soap/nanotrasen, +/obj/effect/turf_decal/stripes/red/line{ + dir = 4 + }, +/obj/machinery/airalarm/directional/west, +/obj/effect/mapping_helpers/airalarm/tlv_no_checks, +/obj/effect/mapping_helpers/airalarm/unlocked, +/turf/open/floor/iron/dark/textured_edge, +/area/station/security/execution/education) "nDd" = ( /obj/machinery/status_display/evac/directional/west, /obj/effect/turf_decal/stripes/corner, @@ -48467,11 +48290,6 @@ /obj/effect/spawner/random/trash/caution_sign, /turf/open/floor/plating, /area/station/maintenance/port/greater) -"nEs" = ( -/obj/item/kirbyplants/random, -/obj/machinery/light/small/directional/west, -/turf/open/floor/iron/dark/textured, -/area/station/security/processing) "nEA" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -48513,6 +48331,17 @@ /obj/effect/mapping_helpers/airlock/access/any/engineering/general, /turf/open/floor/iron/dark, /area/station/engineering/main) +"nFj" = ( +/obj/machinery/door/airlock/security{ + aiControlDisabled = 1; + name = "Prisoner Transfer Centre" + }, +/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/all/security/armory, +/turf/open/floor/iron/dark, +/area/station/security/execution/education) "nFk" = ( /obj/effect/landmark/start/cyborg, /obj/structure/cable, @@ -48605,12 +48434,6 @@ /obj/structure/sign/poster/official/work_for_a_future/directional/south, /turf/open/floor/iron, /area/station/security/prison/work) -"nGd" = ( -/obj/machinery/atmospherics/pipe/multiz/scrubbers/visible/layer2, -/obj/machinery/atmospherics/pipe/multiz/supply/visible/layer4, -/obj/structure/sign/warning/electric_shock/directional/north, -/turf/open/floor/plating, -/area/station/security/prison/safe) "nGo" = ( /obj/machinery/vending/games, /turf/open/floor/iron/dark/textured, @@ -48660,13 +48483,6 @@ /obj/effect/spawner/random/armory/barrier_grenades, /turf/open/floor/iron/dark/textured, /area/station/security/armory/upper) -"nGU" = ( -/obj/structure/closet/secure_closet/security/sec, -/obj/machinery/airalarm/directional/north, -/turf/open/floor/iron/smooth_edge{ - dir = 1 - }, -/area/station/security/lockers) "nGY" = ( /obj/structure/railing/corner{ dir = 4 @@ -48703,13 +48519,6 @@ dir = 4 }, /area/mine/eva) -"nHs" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 4 - }, -/turf/open/floor/iron/showroomfloor, -/area/station/security/prison/toilet) "nHQ" = ( /obj/structure/closet/firecloset, /obj/effect/mapping_helpers/broken_floor, @@ -48729,13 +48538,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/aft/lesser) -"nId" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/barricade/wooden, -/turf/open/floor/eighties/red, -/area/station/security/prison/safe) "nIl" = ( /obj/structure/chair/stool/directional/north, /obj/effect/turf_decal/tile/red/half/contrasted{ @@ -48743,6 +48545,12 @@ }, /turf/open/floor/iron/white, /area/station/science/robotics/lab) +"nIt" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron/smooth, +/area/station/security/lockers) "nIu" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -48806,6 +48614,15 @@ dir = 8 }, /area/station/service/chapel) +"nJE" = ( +/obj/item/lighter/empty, +/obj/item/match{ + pixel_x = 4; + pixel_y = -3 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/plating, +/area/station/security/prison) "nJH" = ( /obj/machinery/door/airlock{ id_tag = "Dorm2"; @@ -48889,11 +48706,6 @@ /obj/structure/chair/stool/directional/south, /turf/open/floor/iron, /area/station/security/prison/visit) -"nKR" = ( -/obj/structure/table, -/obj/item/flashlight/lamp, -/turf/open/floor/iron/dark, -/area/station/security/interrogation) "nKT" = ( /obj/effect/turf_decal/siding/wood{ dir = 8 @@ -49011,6 +48823,28 @@ /obj/structure/sign/warning/docking/directional/north, /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/surface/outdoors/less_spawns) +"nMn" = ( +/obj/machinery/door/airlock/external{ + glass = 1; + name = "Labor Camp External Airlock"; + opacity = 0 + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{ + cycle_id = "labour-exit" + }, +/turf/open/floor/iron, +/area/mine/laborcamp) +"nMo" = ( +/obj/item/storage/box/bodybags, +/obj/item/reagent_containers/syringe{ + name = "steel point" + }, +/obj/item/reagent_containers/cup/bottle/multiver, +/obj/item/reagent_containers/cup/bottle/epinephrine, +/obj/structure/table/glass, +/obj/structure/window/reinforced/spawner/directional/south, +/turf/open/floor/iron/white/textured, +/area/station/security/medical) "nMu" = ( /obj/effect/turf_decal/trimline/blue/filled/warning{ dir = 1 @@ -49083,14 +48917,6 @@ }, /turf/open/floor/wood, /area/station/service/library) -"nMZ" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/tile/red/half/contrasted, -/obj/effect/landmark/firealarm_sanity, -/turf/open/floor/iron/dark/textured_edge{ - dir = 1 - }, -/area/station/security/prison) "nNe" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -49194,15 +49020,6 @@ dir = 8 }, /area/station/science/research) -"nOb" = ( -/obj/machinery/door/airlock/external{ - name = "Labor Camp Shuttle Airlock" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 4 - }, -/turf/open/floor/iron/dark/smooth_large, -/area/station/security/processing) "nOj" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /obj/structure/noticeboard/staff{ @@ -49252,13 +49069,15 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/plating, /area/station/maintenance/port/aft) -"nOQ" = ( -/obj/machinery/suit_storage_unit/security, -/obj/machinery/camera/directional/north{ - c_tag = "Security - EVA" +"nOR" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 }, -/turf/open/floor/iron/smooth, -/area/station/security/brig/upper) +/obj/effect/turf_decal/tile/purple/anticorner/contrasted{ + dir = 1 + }, +/turf/open/floor/iron/white, +/area/station/science/genetics) "nOS" = ( /obj/effect/turf_decal/trimline/dark_blue/line{ dir = 6 @@ -49303,19 +49122,6 @@ /obj/structure/sign/warning/cold_temp/directional/north, /turf/open/floor/iron/smooth_large, /area/station/science/cytology) -"nPr" = ( -/obj/machinery/light/cold/directional/north, -/obj/effect/turf_decal/trimline/purple/filled/line{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/power/apc/auto_name/directional/north, -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/open/floor/iron/dark, -/area/station/engineering/circuit_workshop) "nPs" = ( /obj/structure/bodycontainer/morgue, /obj/machinery/camera/directional/south{ @@ -49509,6 +49315,16 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) +"nRM" = ( +/obj/structure/chair/wood{ + dir = 8 + }, +/obj/machinery/camera/directional/east{ + c_tag = "Security - Permabrig Meditation"; + network = list("ss13","prison") + }, +/turf/open/floor/iron/sepia, +/area/station/security/prison/rec) "nRV" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/extinguisher_cabinet/directional/south, @@ -49587,15 +49403,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/ai/satellite/interior) -"nSH" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/security/processing) "nSK" = ( /obj/structure/sign/departments/xenobio/directional/west, /obj/effect/spawner/random/structure/crate, @@ -49673,17 +49480,22 @@ /obj/effect/turf_decal/tile/red/full, /turf/open/floor/iron/dark/smooth_large, /area/station/security/checkpoint/medical) +"nTW" = ( +/obj/effect/spawner/structure/window/hollow/reinforced/middle{ + dir = 4 + }, +/obj/structure/cable, +/obj/machinery/door/poddoor/preopen{ + id = "labor"; + name = "Labor Camp Blast Door" + }, +/turf/open/floor/plating, +/area/mine/laborcamp) "nTX" = ( /obj/structure/flora/grass/both/style_random, /obj/structure/sign/nanotrasen/directional/north, /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/surface/outdoors/less_spawns) -"nUg" = ( -/obj/effect/turf_decal/tile/red/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron/dark/side, -/area/station/security/processing) "nUh" = ( /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/plating, @@ -49718,6 +49530,12 @@ }, /turf/open/floor/iron/dark/textured_edge, /area/station/security/prison) +"nUS" = ( +/obj/item/radio/intercom/prison/directional/east, +/obj/structure/gulag_beacon, +/obj/machinery/light/small/directional/east, +/turf/open/floor/iron, +/area/mine/laborcamp) "nVc" = ( /obj/structure/cable, /obj/effect/turf_decal/trimline/yellow/filled/corner{ @@ -49755,6 +49573,14 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/iron/white, /area/station/science/robotics/lab) +"nVH" = ( +/obj/machinery/light_switch/directional/south, +/obj/structure/disposalpipe/trunk{ + dir = 8 + }, +/obj/machinery/disposal/bin, +/turf/open/floor/iron/dark/smooth_large, +/area/station/command/heads_quarters/hos) "nVJ" = ( /obj/machinery/door/airlock/freezer{ desc = "The freezer where the chef keeps all the stuff that needs to be kept cold. Ice cold."; @@ -49810,6 +49636,13 @@ }, /turf/open/floor/plating, /area/station/maintenance/port/lesser) +"nWx" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/mine/laborcamp) "nWy" = ( /obj/effect/turf_decal/tile/brown/half/contrasted{ dir = 8 @@ -49835,20 +49668,12 @@ /obj/machinery/holopad, /turf/open/floor/iron/white, /area/station/science/xenobiology) -"nXb" = ( -/turf/closed/wall, -/area/icemoon/surface/outdoors/nospawn) "nXg" = ( /obj/machinery/atmospherics/components/unary/thermomachine/heater{ dir = 8 }, /turf/open/floor/plating, /area/station/maintenance/starboard/upper) -"nXj" = ( -/obj/machinery/vending/sovietsoda, -/obj/structure/cable, -/turf/open/floor/iron/dark/textured, -/area/station/security/prison/safe) "nXl" = ( /obj/effect/turf_decal/bot, /obj/machinery/portable_atmospherics/canister, @@ -49893,6 +49718,18 @@ /obj/machinery/door/firedoor, /turf/open/floor/iron/dark, /area/station/security/prison/visit) +"nXW" = ( +/obj/machinery/door/window/brigdoor/left/directional/north{ + req_access = list("security"); + name = "Firing Range Access" + }, +/obj/structure/platform/iron, +/turf/open/floor/iron/dark/textured, +/area/station/security/range) +"nXZ" = ( +/obj/structure/sign/nanotrasen/directional/east, +/turf/open/misc/asteroid/snow/icemoon, +/area/icemoon/surface/outdoors/nospawn) "nYl" = ( /obj/effect/turf_decal/trimline/purple/filled/warning{ dir = 1 @@ -49926,10 +49763,6 @@ /obj/structure/flora/rock/pile/icy/style_random, /turf/open/misc/asteroid/snow/coldroom, /area/icemoon/underground/explored) -"nYZ" = ( -/obj/item/storage/bag/trash, -/turf/open/floor/plating, -/area/station/security/prison/safe) "nZb" = ( /obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ @@ -49971,16 +49804,6 @@ }, /turf/open/floor/iron/dark, /area/station/hallway/secondary/entry) -"nZC" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/sign/warning/cold_temp/directional/north, -/turf/open/floor/iron, -/area/mine/laborcamp) "nZH" = ( /obj/structure/lattice/catwalk, /turf/open/openspace, @@ -50014,6 +49837,12 @@ }, /turf/open/floor/iron/freezer, /area/station/commons/toilet/locker) +"oaa" = ( +/obj/structure/sign/painting/large{ + dir = 1 + }, +/turf/open/floor/carpet, +/area/station/security/prison/rec) "oad" = ( /obj/structure/railing{ dir = 4 @@ -50040,6 +49869,12 @@ }, /turf/open/floor/iron/white/corner, /area/mine/living_quarters) +"oaM" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/iron/smooth, +/area/station/security/brig/upper) "oaP" = ( /obj/machinery/door/airlock/research{ name = "Crater Observation Room" @@ -50287,12 +50122,6 @@ /obj/effect/spawner/random/engineering/tracking_beacon, /turf/open/floor/iron, /area/station/cargo/storage) -"ody" = ( -/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/mine/laborcamp/security) "odz" = ( /obj/machinery/computer/arcade/orion_trail, /turf/open/floor/iron, @@ -50324,6 +50153,13 @@ }, /turf/open/floor/iron/dark, /area/station/science/robotics/lab) +"oef" = ( +/obj/effect/turf_decal/tile/red/anticorner/contrasted, +/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/security/prison/visit) "oeh" = ( /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 8 @@ -50335,6 +50171,14 @@ /obj/effect/mapping_helpers/airlock/access/all/security/general, /turf/open/floor/plating, /area/station/hallway/secondary/exit/departure_lounge) +"oek" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/newscaster/directional/west, +/obj/structure/chair/sofa/bench/right{ + dir = 4 + }, +/turf/open/floor/iron/smooth, +/area/station/security/holding_cell) "oev" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/turf_decal/trimline/yellow/filled/line{ @@ -50470,17 +50314,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/dark, /area/station/ai/satellite/chamber) -"ogL" = ( -/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/trimline/red/filled/line{ - dir = 9 - }, -/turf/open/floor/iron/dark/side{ - dir = 9 - }, -/area/station/security/prison) "oha" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/cable, @@ -50544,18 +50377,23 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) +"ohV" = ( +/obj/structure/sign/warning/gas_mask/directional/west, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/mine/laborcamp) "oic" = ( /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/smooth, /area/station/medical/chemistry) -"oie" = ( -/obj/effect/turf_decal/bot, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/mine/laborcamp) "oif" = ( /obj/effect/gibspawner/human/bodypartless, /obj/structure/sign/warning/secure_area/directional/south, @@ -50637,6 +50475,13 @@ }, /turf/open/floor/wood/parquet, /area/station/service/theater) +"oiN" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/vending/wardrobe/gene_wardrobe, +/turf/open/floor/iron/white, +/area/station/science/genetics) "oiO" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -50648,6 +50493,11 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/engineering/atmos/hfr_room) +"oiP" = ( +/obj/item/kirbyplants/random, +/obj/effect/turf_decal/tile/red/anticorner/contrasted, +/turf/open/floor/iron/dark/textured, +/area/station/security/prison) "oiT" = ( /obj/effect/spawner/random/trash/grille_or_waste, /turf/open/floor/plating, @@ -50727,6 +50577,13 @@ }, /turf/open/floor/iron/dark, /area/station/service/hydroponics) +"ojE" = ( +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 1 + }, +/obj/item/radio/intercom/directional/north, +/turf/open/floor/iron, +/area/station/security/brig/upper) "ojF" = ( /obj/machinery/rnd/production/protolathe/department/science, /turf/open/floor/iron/checker, @@ -50759,14 +50616,6 @@ /obj/effect/mapping_helpers/airlock/access/all/supply/mining, /turf/open/floor/iron/large, /area/mine/mechbay) -"okl" = ( -/obj/structure/chair{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/sign/poster/official/random/directional/north, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "okx" = ( /obj/structure/table/reinforced, /obj/machinery/door/window/brigdoor/left/directional/south{ @@ -50861,24 +50710,10 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/dark/visible, /turf/open/floor/iron/smooth, /area/station/maintenance/starboard/lesser) -"olV" = ( -/obj/machinery/light/small/directional/west, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/carpet/black, -/area/station/security/prison/safe) -"olY" = ( -/obj/machinery/door/airlock/security/glass{ - name = "Security EVA" - }, -/obj/effect/mapping_helpers/airlock/access/all/security/armory, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/red_alert_access, +"olZ" = ( +/obj/machinery/light/small/directional/north, /turf/open/floor/iron/smooth, -/area/station/security/processing) +/area/station/security/eva) "omg" = ( /obj/effect/spawner/random/clothing/wardrobe_closet_colored, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -50901,6 +50736,15 @@ "omk" = ( /turf/open/floor/glass/reinforced, /area/station/security/office) +"omw" = ( +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 10 + }, +/obj/machinery/light/small/directional/west, +/turf/open/floor/iron/dark/side{ + dir = 10 + }, +/area/mine/laborcamp/security) "omG" = ( /obj/structure/table, /obj/item/flashlight/lamp, @@ -50917,25 +50761,12 @@ }, /turf/open/floor/iron, /area/station/commons/locker) -"omJ" = ( -/obj/machinery/door/airlock{ - name = "Perma Overlook Closet" - }, -/obj/effect/mapping_helpers/airlock/abandoned, -/turf/open/floor/vault, -/area/station/security/prison/rec) "omL" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/department/cargo) -"omP" = ( -/obj/machinery/door/airlock{ - name = "Cleaning Closet" - }, -/turf/open/floor/plating, -/area/station/security/prison/safe) "omT" = ( /obj/structure/table, /obj/machinery/cell_charger, @@ -51097,13 +50928,6 @@ }, /turf/open/floor/iron/dark/textured, /area/station/hallway/primary/central) -"ooW" = ( -/obj/structure/cable, -/obj/effect/spawner/structure/window/hollow/reinforced/middle{ - dir = 4 - }, -/turf/open/floor/plating, -/area/station/security/prison/rec) "opc" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 4 @@ -51191,6 +51015,18 @@ "opP" = ( /turf/closed/wall/r_wall, /area/station/science/ordnance/burnchamber) +"opR" = ( +/obj/machinery/button/door/directional/south{ + name = "Security Mech Garage Door Controls"; + id = "secmechbay"; + req_access = list("security") + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 8 + }, +/obj/effect/turf_decal/tile/red/half/contrasted, +/turf/open/floor/iron, +/area/station/security/brig/upper) "opS" = ( /obj/effect/turf_decal/tile/red/half/contrasted{ dir = 1 @@ -51225,13 +51061,6 @@ }, /turf/open/floor/wood, /area/station/commons/dorms) -"oqu" = ( -/obj/item/radio/intercom/directional/east, -/obj/effect/spawner/random/entertainment/slot_machine{ - name = "two-armed bandit" - }, -/turf/open/floor/wood/large, -/area/station/commons/lounge) "oqz" = ( /obj/effect/turf_decal/tile/green{ dir = 4 @@ -51292,6 +51121,19 @@ /obj/effect/spawner/random/structure/closet_private, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) +"ore" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 1 + }, +/obj/structure/railing{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/iron, +/area/mine/production) "orq" = ( /obj/machinery/light/small/directional/west, /obj/machinery/button/door/directional/south{ @@ -51419,6 +51261,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/maintenance/port/aft) +"osN" = ( +/obj/structure/reagent_dispensers/wall/peppertank/directional/south, +/obj/structure/filingcabinet/chestdrawer, +/turf/open/floor/iron/dark/textured, +/area/station/security/office) "osO" = ( /obj/effect/turf_decal/tile/blue{ dir = 4 @@ -51458,16 +51305,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/security/courtroom) -"oty" = ( -/obj/structure/rack, -/obj/machinery/light/cold/directional/north, -/obj/item/storage/box/bandages{ - pixel_x = -6; - pixel_y = 6 - }, -/obj/item/healthanalyzer, -/turf/open/floor/iron/white/textured, -/area/station/security/medical) "otA" = ( /obj/machinery/door/window/left/directional/north{ name = "Public Mining" @@ -51509,13 +51346,6 @@ /obj/structure/sink/directional/east, /turf/open/floor/iron, /area/station/service/hydroponics) -"oua" = ( -/obj/structure/cable, -/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/south, -/turf/open/floor/plating, -/area/station/security/prison/safe) "ouc" = ( /obj/structure/table, /obj/item/clothing/mask/gas, @@ -51548,18 +51378,6 @@ /obj/machinery/light/small/directional/east, /turf/open/floor/iron, /area/mine/living_quarters) -"ous" = ( -/obj/machinery/door/airlock/security/glass{ - name = "N2O Storage" - }, -/obj/effect/mapping_helpers/airlock/access/all/security/armory, -/obj/effect/mapping_helpers/airlock/abandoned, -/obj/structure/cable, -/obj/effect/mapping_helpers/airlock/unres/delayed{ - dir = 8 - }, -/turf/open/floor/plating, -/area/station/maintenance/fore) "ouK" = ( /obj/machinery/space_heater, /obj/effect/mapping_helpers/broken_floor, @@ -51582,15 +51400,6 @@ /obj/effect/spawner/random/structure/musician/piano/random_piano, /turf/open/floor/wood, /area/station/maintenance/aft/greater) -"ouX" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/structure/closet/secure_closet/personal/patient{ - name = "test subject's closet" - }, -/turf/open/floor/iron/white, -/area/station/science/genetics) "ovm" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -51676,6 +51485,16 @@ /obj/machinery/light/cold/directional/west, /turf/open/floor/iron/white, /area/station/medical/treatment_center) +"oww" = ( +/obj/machinery/gulag_item_reclaimer{ + pixel_y = -32 + }, +/obj/effect/turf_decal/loading_area/red, +/obj/effect/turf_decal/tile/red{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/security/brig) "owC" = ( /turf/closed/wall/r_wall, /area/station/science/server) @@ -51725,6 +51544,11 @@ /obj/structure/cable, /turf/open/floor/iron/dark, /area/station/engineering/circuit_workshop) +"oxJ" = ( +/obj/effect/spawner/structure/window/reinforced/tinted, +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/security/interrogation) "oxO" = ( /turf/open/floor/plating, /area/station/maintenance/aft/lesser) @@ -51832,17 +51656,6 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/wood, /area/station/maintenance/aft/lesser) -"oyH" = ( -/obj/structure/sign/poster/contraband/random/directional/north, -/turf/open/floor/plating, -/area/station/security/prison/safe) -"oyL" = ( -/obj/effect/turf_decal/tile/red/half/contrasted, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 1 - }, -/turf/open/floor/iron/dark, -/area/station/security/mechbay) "oyM" = ( /obj/structure/railing/corner{ dir = 1 @@ -51850,6 +51663,14 @@ /obj/structure/lattice/catwalk, /turf/open/openspace/icemoon, /area/icemoon/underground/explored) +"oyV" = ( +/obj/machinery/door/window/brigdoor/right/directional/north{ + req_access = list("security"); + name = "Firing Range Access" + }, +/obj/structure/platform/iron, +/turf/open/floor/iron/dark/textured, +/area/station/security/range) "oyW" = ( /turf/open/floor/circuit, /area/station/ai/satellite/hallway) @@ -52053,20 +51874,20 @@ }, /turf/open/lava/plasma/ice_moon, /area/icemoon/underground/explored) -"oAP" = ( -/obj/machinery/portable_atmospherics/canister/bz, -/turf/open/floor/plating, -/area/station/security/prison/safe) -"oAY" = ( -/obj/machinery/camera/directional/north{ - c_tag = "Armory - Internal - Lower" +"oAO" = ( +/obj/structure/closet/secure_closet/security/sec, +/obj/structure/reagent_dispensers/wall/peppertank/directional/north, +/obj/effect/turf_decal/bot, +/turf/open/floor/iron/smooth_edge{ + dir = 1 }, -/obj/structure/rack, -/obj/item/storage/toolbox/drone, -/obj/effect/turf_decal/tile/red/half/contrasted, -/obj/machinery/light/small/directional/north, -/turf/open/floor/iron/dark/textured, -/area/station/security/armory) +/area/station/security/lockers) +"oAS" = ( +/obj/structure/table, +/obj/item/kitchen/fork/plastic, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/security/prison/mess) "oBg" = ( /obj/structure/table/wood, /obj/item/book/bible, @@ -52079,6 +51900,15 @@ }, /turf/open/floor/iron/dark, /area/mine/eva/lower) +"oBp" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/obj/structure/railing, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/iron, +/area/mine/production) "oBq" = ( /obj/machinery/atmospherics/pipe/smart/simple/dark/visible{ dir = 9 @@ -52109,6 +51939,15 @@ }, /turf/open/lava/plasma/ice_moon, /area/icemoon/underground/explored) +"oBC" = ( +/obj/structure/closet/secure_closet/freezer/gulag_fridge, +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 5 + }, +/turf/open/floor/iron/dark/side{ + dir = 5 + }, +/area/mine/laborcamp/security) "oBD" = ( /obj/effect/decal/cleanable/dirt, /obj/item/reagent_containers/cup/bucket{ @@ -52127,12 +51966,6 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/solars/starboard/fore) -"oBV" = ( -/obj/item/paper/fluff/jobs/security/beepsky_mom, -/obj/machinery/light/small/dim/directional/east, -/obj/effect/decal/cleanable/cobweb/cobweb2, -/turf/open/floor/plating, -/area/station/maintenance/fore) "oBZ" = ( /obj/effect/mapping_helpers/broken_floor, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -52144,20 +51977,6 @@ /obj/machinery/firealarm/directional/south, /turf/open/floor/iron/dark/side, /area/station/security/prison) -"oCo" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 8 - }, -/obj/structure/cable, -/obj/effect/turf_decal/tile/blue/opposingcorners{ - dir = 1 - }, -/obj/effect/turf_decal/siding/white{ - dir = 8 - }, -/turf/open/floor/iron/cafeteria, -/area/mine/laborcamp) "oCs" = ( /obj/structure/table, /obj/item/radio/headset/headset_med{ @@ -52221,13 +52040,6 @@ /obj/machinery/light/small/directional/west, /turf/open/floor/grass, /area/station/security/prison/safe) -"oCU" = ( -/obj/machinery/firealarm/directional/south, -/obj/effect/turf_decal/tile/red/half/contrasted, -/turf/open/floor/iron/dark/textured_edge{ - dir = 1 - }, -/area/station/security/prison) "oDb" = ( /obj/item/popsicle_stick{ pixel_x = -9; @@ -52304,10 +52116,6 @@ }, /turf/open/floor/iron/smooth_large, /area/station/science/cytology) -"oDB" = ( -/obj/machinery/light/small/directional/east, -/turf/open/floor/plating, -/area/mine/laborcamp) "oDD" = ( /obj/effect/turf_decal/trimline/green/filled/corner{ dir = 8 @@ -52324,6 +52132,17 @@ dir = 8 }, /area/station/maintenance/port/fore) +"oDL" = ( +/obj/effect/turf_decal/stripes/red/line{ + dir = 5 + }, +/obj/machinery/door/poddoor/shutters/window/preopen{ + name = "Firing Range Shutters"; + dir = 1; + id = "firingrangeshuttersoutside" + }, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/surface/outdoors/nospawn) "oDQ" = ( /obj/effect/turf_decal/stripes/corner{ dir = 8 @@ -52361,6 +52180,13 @@ /obj/machinery/requests_console/auto_name/directional/west, /turf/open/floor/iron/dark, /area/station/ai/satellite/chamber) +"oEr" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 8 + }, +/obj/machinery/light/small/dim/directional/south, +/turf/open/floor/iron/showroomfloor, +/area/mine/laborcamp) "oEt" = ( /obj/machinery/airalarm/directional/south, /turf/open/floor/iron, @@ -52430,6 +52256,14 @@ /obj/effect/turf_decal/stripes/end, /turf/open/floor/iron/dark/textured, /area/station/medical/medbay/aft) +"oET" = ( +/obj/structure/railing{ + dir = 8 + }, +/turf/open/floor/iron/stairs/medium{ + dir = 1 + }, +/area/mine/laborcamp/security) "oEX" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -52626,13 +52460,12 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/exit/departure_lounge) -"oGJ" = ( -/obj/machinery/camera/directional/west{ - c_tag = "Labor Camp External West"; - network = list("labor") - }, -/turf/open/misc/asteroid/snow/icemoon, -/area/icemoon/surface/outdoors/labor_camp) +"oGM" = ( +/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/execution/education) "oGN" = ( /obj/structure/reagent_dispensers/watertank, /obj/effect/decal/cleanable/dirt, @@ -52660,6 +52493,20 @@ }, /turf/open/floor/carpet, /area/station/command/heads_quarters/captain) +"oGW" = ( +/obj/machinery/door/poddoor/shutters{ + dir = 1; + id = "armory"; + name = "Armory Shutter" + }, +/obj/machinery/button/door/directional/east{ + id = "armory"; + name = "Armory Shutters"; + req_access = list("armory") + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/station/security/armory/upper) "oHf" = ( /obj/machinery/vending/autodrobe, /obj/machinery/airalarm/directional/north, @@ -52697,6 +52544,25 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/service/chapel) +"oHJ" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/cup/glass/bottle/vodka/badminka{ + pixel_x = 7; + pixel_y = 20 + }, +/obj/item/reagent_containers/cup/glass/drinkingglass/shotglass{ + pixel_x = 7; + pixel_y = 8 + }, +/obj/item/reagent_containers/cup/glass/drinkingglass/shotglass{ + pixel_x = 6 + }, +/obj/item/taperecorder{ + pixel_x = -5; + pixel_y = 1 + }, +/turf/open/floor/wood/large, +/area/station/command/heads_quarters/hos) "oHK" = ( /turf/closed/wall/r_wall, /area/station/science/lab) @@ -52730,13 +52596,6 @@ /obj/structure/sign/departments/cargo/directional/west, /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/underground/explored) -"oIv" = ( -/obj/machinery/camera/directional/south{ - c_tag = "Labor Camp External North"; - network = list("labor") - }, -/turf/open/floor/plating/snowed/smoothed/icemoon, -/area/icemoon/surface/outdoors/labor_camp) "oIy" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /obj/effect/decal/cleanable/dirt/dust, @@ -52896,13 +52755,6 @@ /obj/item/radio/intercom/directional/south, /turf/open/floor/iron, /area/station/service/hydroponics) -"oLj" = ( -/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, -/area/mine/laborcamp) "oLm" = ( /obj/machinery/camera/directional/east{ c_tag = "Garden" @@ -53002,6 +52854,10 @@ /obj/effect/spawner/random/trash/mess, /turf/open/floor/iron/grimy, /area/station/maintenance/aft/greater) +"oMP" = ( +/obj/effect/spawner/random/entertainment/slot_machine, +/turf/open/floor/wood, +/area/station/command/meeting_room) "oMR" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -53022,6 +52878,15 @@ "oMT" = ( /turf/open/floor/iron, /area/station/command/heads_quarters/rd) +"oNl" = ( +/obj/effect/turf_decal/trimline/red/warning{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/red/line{ + dir = 4 + }, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/surface/outdoors/nospawn) "oNA" = ( /obj/effect/turf_decal/bot, /turf/open/floor/plating/snowed/smoothed/icemoon, @@ -53061,18 +52926,6 @@ /obj/structure/sign/warning/fire/directional/north, /turf/open/floor/glass/reinforced, /area/station/science/ordnance/office) -"oOc" = ( -/obj/machinery/vending/wardrobe/gene_wardrobe, -/obj/structure/sign/departments/genetics/directional/north, -/turf/open/floor/iron/dark, -/area/station/science/genetics) -"oOg" = ( -/obj/effect/spawner/random/medical/patient_stretcher, -/obj/effect/decal/cleanable/blood/gibs/torso, -/obj/effect/mapping_helpers/burnt_floor, -/obj/structure/window/reinforced/tinted/spawner/directional/north, -/turf/open/floor/plating, -/area/station/security/prison/safe) "oOh" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -53137,6 +52990,16 @@ dir = 6 }, /area/station/science/research) +"oOT" = ( +/obj/item/kirbyplants/random, +/turf/open/floor/iron/dark/textured, +/area/station/security/interrogation) +"oPa" = ( +/obj/structure/chair/wood{ + dir = 4 + }, +/turf/open/floor/iron/sepia, +/area/station/security/prison/rec) "oPb" = ( /obj/effect/turf_decal/stripes/asteroid/line{ dir = 1 @@ -53165,18 +53028,22 @@ /obj/machinery/light/small/directional/east, /turf/open/floor/iron, /area/station/service/hydroponics) -"oPn" = ( -/obj/structure/closet/secure_closet/injection, -/obj/machinery/airalarm/directional/north, -/obj/item/soap/nanotrasen, -/turf/open/floor/iron/dark, -/area/station/security/execution/education) "oPr" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/brown/half/contrasted, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/dark/side, /area/mine/eva) +"oPs" = ( +/obj/item/bedsheet/red, +/obj/machinery/light/small/dim/directional/east, +/obj/item/paper/fluff/jobs/security/beepsky_mom{ + pixel_y = 4; + pixel_x = -5 + }, +/mob/living/basic/bot/secbot/beepsky, +/turf/open/floor/plating, +/area/station/maintenance/fore) "oPt" = ( /obj/structure/stairs/east, /turf/open/floor/iron/stairs/medium{ @@ -53327,16 +53194,6 @@ /obj/item/radio/intercom/directional/north, /turf/open/floor/iron/dark/textured, /area/station/security/armory) -"oSa" = ( -/obj/machinery/door/airlock/public/glass{ - id_tag = "gulag3"; - name = "Cell 3" - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/mine/laborcamp) "oSm" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -53355,6 +53212,12 @@ /obj/structure/cable, /turf/open/floor/iron/smooth, /area/station/security/lockers) +"oSG" = ( +/obj/structure/closet/crate/bin, +/obj/effect/turf_decal/tile/red/full, +/obj/machinery/firealarm/directional/south, +/turf/open/floor/iron/smooth_large, +/area/station/security/brig/upper) "oSK" = ( /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 4 @@ -53417,6 +53280,10 @@ /obj/structure/sign/warning/cold_temp/directional/east, /turf/open/floor/plating, /area/mine/mechbay) +"oTp" = ( +/obj/machinery/light/warm/dim/directional/east, +/turf/open/floor/iron/sepia, +/area/station/security/prison/rec) "oTr" = ( /obj/effect/turf_decal/tile/brown/anticorner/contrasted{ dir = 1 @@ -53553,6 +53420,26 @@ }, /turf/open/floor/circuit, /area/station/ai/satellite/chamber) +"oVE" = ( +/obj/structure/closet, +/obj/item/clothing/suit/hooded/wintercoat/security{ + pixel_x = 5 + }, +/obj/item/clothing/suit/hooded/wintercoat/security{ + pixel_x = 5 + }, +/obj/item/clothing/suit/hooded/wintercoat/security{ + pixel_x = 5 + }, +/obj/item/clothing/suit/hooded/wintercoat{ + pixel_x = -5 + }, +/obj/effect/turf_decal/stripes/red/line{ + dir = 4 + }, +/obj/machinery/power/apc/auto_name/directional/west, +/turf/open/floor/iron/dark/textured_edge, +/area/station/security/execution/education) "oVG" = ( /obj/machinery/door/airlock/public/glass{ name = "Art Storage" @@ -53584,10 +53471,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/catwalk_floor/iron_dark, /area/station/security/prison) -"oWe" = ( -/obj/machinery/firealarm/directional/north, -/turf/open/floor/iron/dark/textured, -/area/station/security/prison/rec) "oWk" = ( /obj/machinery/door/firedoor/border_only{ dir = 8 @@ -53634,17 +53517,6 @@ /obj/effect/turf_decal/tile/blue/fourcorners, /turf/open/floor/iron/dark/textured, /area/station/medical/medbay/lobby) -"oXd" = ( -/obj/machinery/light/small/directional/east, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/trimline/red/warning{ - dir = 5 - }, -/obj/effect/turf_decal/stripes/red/line{ - dir = 10 - }, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) "oXf" = ( /obj/structure/closet/secure_closet/medical1, /obj/effect/turf_decal/trimline/blue/filled/line{ @@ -53776,6 +53648,10 @@ /obj/structure/cable, /turf/open/floor/iron/white, /area/station/science/xenobiology) +"oYK" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/mine/laborcamp) "oYN" = ( /obj/structure/table, /obj/item/hand_tele{ @@ -53838,12 +53714,6 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos) -"oZR" = ( -/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/textured_edge, -/area/station/security/prison) "pac" = ( /obj/effect/turf_decal/tile/red/half/contrasted{ dir = 8 @@ -53861,14 +53731,15 @@ dir = 4 }, /area/station/medical/chem_storage) -"par" = ( -/obj/structure/toilet/greyscale, -/obj/machinery/airalarm/directional/east, -/obj/structure/cable, -/turf/open/floor/iron/smooth_half{ +"pap" = ( +/obj/machinery/door/window/brigdoor/right/directional/north{ + req_access = list("security"); + name = "Firing Range Access" + }, +/turf/open/floor/iron/dark/side{ dir = 1 }, -/area/station/security/prison/safe) +/area/station/security/range) "pau" = ( /obj/structure/table/wood, /obj/item/pai_card, @@ -53887,11 +53758,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/command/bridge) -"paL" = ( -/obj/machinery/light/small/directional/east, -/obj/structure/cable, -/turf/open/floor/plating/icemoon, -/area/station/security/execution/education) "paM" = ( /turf/closed/wall, /area/station/engineering/storage/tech) @@ -54008,6 +53874,21 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/ce) +"pcj" = ( +/obj/structure/bed/medical/anchored{ + dir = 4 + }, +/obj/item/bedsheet/medical, +/obj/effect/turf_decal/tile/blue/opposingcorners{ + dir = 1 + }, +/obj/machinery/camera/directional/east{ + c_tag = "Labor Camp - Infirmary"; + network = list("labor","prison") + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/white, +/area/mine/laborcamp) "pcr" = ( /obj/machinery/atmospherics/components/unary/vent_pump/siphon/monitored/nitrous_output{ dir = 8 @@ -54068,10 +53949,15 @@ /obj/structure/sign/warning/electric_shock/directional/north, /turf/open/floor/iron/dark/textured, /area/station/security/prison) -"pdc" = ( +"pcX" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/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/mine/laborcamp/security) +/area/mine/laborcamp) "pdd" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -54090,10 +53976,6 @@ /obj/structure/window/reinforced/spawner/directional/west, /turf/open/floor/iron/white/smooth_large, /area/station/medical/pharmacy) -"pdx" = ( -/obj/item/kirbyplants/organic/plant10, -/turf/open/floor/sepia, -/area/station/security/prison/rec) "pdy" = ( /obj/machinery/conveyor_switch/oneway{ id = "robo2" @@ -54122,25 +54004,10 @@ /obj/structure/sign/poster/random/directional/north, /turf/open/floor/iron/cafeteria, /area/station/hallway/secondary/exit/departure_lounge) -"pdK" = ( -/obj/effect/turf_decal/tile/red/anticorner/contrasted, -/turf/open/floor/iron/dark/textured, -/area/station/security/armory/upper) "pdO" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/general/visible, /turf/open/floor/engine, /area/station/science/explab) -"pdT" = ( -/obj/structure/chair/sofa/corp/right{ - dir = 8 - }, -/obj/machinery/camera/directional/east{ - c_tag = "Security - Permabrig Library Reading Room"; - network = list("ss13","prison") - }, -/obj/effect/landmark/start/prisoner, -/turf/open/floor/carpet/blue, -/area/station/security/prison/work) "pdV" = ( /obj/machinery/vending/coffee, /obj/machinery/firealarm/directional/east, @@ -54238,12 +54105,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) -"pfO" = ( -/obj/structure/chair/stool/directional/west, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron, -/area/mine/laborcamp) "pfP" = ( /obj/machinery/computer/mech_bay_power_console, /obj/structure/cable, @@ -54406,10 +54267,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) -"phK" = ( -/obj/effect/spawner/random/contraband/prison, -/turf/open/floor/plating, -/area/station/security/prison/safe) "phL" = ( /obj/structure/reflector/single/anchored{ dir = 9 @@ -54449,14 +54306,6 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/iron/white, /area/station/medical/treatment_center) -"piv" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/disposalpipe/segment, -/obj/effect/spawner/random/engineering/tracking_beacon, -/turf/open/floor/iron, -/area/station/security/brig/upper) "piB" = ( /obj/structure/sign/warning/electric_shock/directional/north, /obj/effect/turf_decal/stripes/corner{ @@ -54481,15 +54330,6 @@ /obj/item/pillow/random, /turf/open/floor/carpet, /area/station/commons/dorms) -"piD" = ( -/obj/machinery/computer/security/labor, -/obj/structure/cable, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/machinery/light/small/directional/north, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "piL" = ( /obj/machinery/door/window/brigdoor/security/cell/left/directional/west{ id = "Cell 2"; @@ -54727,14 +54567,6 @@ /obj/effect/spawner/random/trash/caution_sign, /turf/open/floor/plating, /area/station/maintenance/department/chapel) -"pmr" = ( -/obj/structure/window/reinforced/spawner/directional/north{ - pixel_y = 2 - }, -/obj/structure/chair, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron/smooth, -/area/station/security/holding_cell) "pmA" = ( /obj/structure/minecart_rail{ dir = 4 @@ -54813,20 +54645,11 @@ /obj/structure/extinguisher_cabinet/directional/west, /turf/open/floor/glass/reinforced, /area/station/science/xenobiology) -"pnG" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/newscaster/directional/north, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +"pnF" = ( +/obj/effect/landmark/start/hangover, /obj/structure/cable, -/turf/open/floor/iron, -/area/mine/laborcamp) -"pnK" = ( -/obj/structure/filingcabinet/chestdrawer, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/light_switch/directional/north, -/turf/open/floor/iron, -/area/station/science/explab) +/turf/open/floor/iron/smooth, +/area/station/engineering/lobby) "pnR" = ( /turf/closed/wall/r_wall, /area/station/ai/satellite/interior) @@ -54852,6 +54675,19 @@ /obj/effect/mapping_helpers/airlock/access/all/security/brig, /turf/open/floor/iron/dark/textured, /area/station/security/execution/transfer) +"pop" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/trimline/red/warning{ + dir = 5 + }, +/obj/effect/turf_decal/stripes/red/line{ + dir = 10 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/surface/outdoors/nospawn) "pos" = ( /obj/structure/table, /obj/effect/spawner/round_default_module, @@ -54909,6 +54745,10 @@ /obj/machinery/light/small/directional/north, /turf/open/floor/plating, /area/station/maintenance/port/aft) +"poU" = ( +/obj/machinery/light/floor, +/turf/open/floor/iron/dark, +/area/station/security/prison/rec) "ppc" = ( /obj/item/trash/syndi_cakes, /obj/effect/turf_decal/stripes/red/line{ @@ -54996,6 +54836,16 @@ /obj/effect/mapping_helpers/no_atoms_ontop, /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/underground/explored) +"ppZ" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 8 + }, +/obj/machinery/status_display/evac/directional/north, +/turf/open/floor/iron/smooth, +/area/station/security/brig/upper) "pqc" = ( /obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible{ dir = 6 @@ -55003,22 +54853,14 @@ /obj/machinery/meter, /turf/open/floor/iron, /area/station/engineering/atmos) -"pql" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/mine/production) -"pqo" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/door/poddoor/shutters/preopen{ - dir = 8; - id = "gene_desk_shutters"; - name = "Genetics Shutters" +"pqs" = ( +/obj/structure/table/wood, +/obj/machinery/fax{ + fax_name = "Head of Security's Office"; + name = "Head of Security's Fax Machine" }, -/turf/open/floor/plating, -/area/station/science/genetics) +/turf/open/floor/wood/large, +/area/station/command/heads_quarters/hos) "pqv" = ( /obj/item/storage/medkit/toxin{ pixel_x = 3; @@ -55034,14 +54876,6 @@ "prg" = ( /turf/open/floor/wood, /area/station/service/library) -"prm" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/smooth, -/area/station/engineering/lobby) "prs" = ( /obj/docking_port/stationary{ dir = 8; @@ -55122,6 +54956,10 @@ dir = 4 }, /area/station/engineering/lobby) +"psz" = ( +/obj/effect/landmark/event_spawn, +/turf/open/floor/iron/cafeteria, +/area/station/security/prison/mess) "psN" = ( /turf/closed/wall/r_wall, /area/station/security/brig/entrance) @@ -55145,17 +54983,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/cargo/office) -"psY" = ( -/obj/machinery/door/poddoor/shutters{ - id = "secmechbay"; - name = "Security Mech Bay Shutters" - }, -/obj/effect/turf_decal/caution/stand_clear, -/obj/effect/turf_decal/box, -/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/security/mechbay) "ptd" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -55171,30 +54998,6 @@ /obj/structure/bookcase/random, /turf/open/floor/iron/grimy, /area/station/maintenance/aft/greater) -"ptr" = ( -/obj/structure/table/wood, -/obj/item/reagent_containers/cup/glass/bottle/vodka/badminka{ - pixel_x = 7; - pixel_y = 20 - }, -/obj/item/taperecorder{ - pixel_x = -5; - pixel_y = 1 - }, -/obj/item/reagent_containers/cup/glass/drinkingglass/shotglass{ - pixel_x = 7; - pixel_y = 8 - }, -/obj/item/reagent_containers/cup/glass/drinkingglass/shotglass{ - pixel_x = 6 - }, -/obj/machinery/firealarm/directional/south, -/obj/structure/secure_safe/hos{ - pixel_x = 28; - pixel_y = 6 - }, -/turf/open/floor/iron/dark/smooth_large, -/area/station/command/heads_quarters/hos) "ptQ" = ( /obj/structure/disposalpipe/trunk/multiz/down, /obj/effect/turf_decal/stripes/line, @@ -55218,15 +55021,6 @@ /obj/machinery/light/directional/south, /turf/open/floor/iron, /area/station/hallway/primary/central) -"puc" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/machinery/light/warm/directional/west, -/turf/open/floor/iron, -/area/station/security/prison/mess) "pue" = ( /obj/structure/extinguisher_cabinet/directional/east, /obj/effect/turf_decal/tile/red, @@ -55286,6 +55080,17 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) +"puM" = ( +/obj/structure/table, +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 5 + }, +/obj/item/paper_bin, +/obj/item/folder/red, +/turf/open/floor/iron/dark/side{ + dir = 5 + }, +/area/mine/laborcamp/security) "puN" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -55409,12 +55214,6 @@ }, /turf/open/floor/iron, /area/station/command/heads_quarters/ce) -"pvJ" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 8 - }, -/turf/open/floor/eighties/red, -/area/station/security/prison/safe) "pvP" = ( /obj/item/radio/intercom/directional/south, /obj/structure/disposalpipe/segment{ @@ -55460,17 +55259,6 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/medical/virology) -"pwo" = ( -/obj/machinery/door/airlock/external{ - name = "Labor Camp Shuttle Airlock"; - shuttledocked = 1 - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 4 - }, -/obj/effect/mapping_helpers/airlock/access/all/security/brig, -/turf/open/floor/iron/dark/smooth_large, -/area/station/security/processing) "pwv" = ( /obj/machinery/atmospherics/pipe/multiz/supply/visible/layer4{ color = "#0000ff"; @@ -55625,14 +55413,6 @@ /obj/machinery/firealarm/directional/north, /turf/open/floor/iron/grimy, /area/station/service/bar/backroom) -"pyG" = ( -/obj/structure/rack, -/obj/effect/turf_decal/tile/red/half/contrasted{ - dir = 4 - }, -/obj/effect/spawner/random/armory/e_gun, -/turf/open/floor/iron/dark/textured, -/area/station/security/armory/upper) "pyI" = ( /obj/machinery/door/airlock/engineering{ name = "Port Quarter Solar Access" @@ -55734,19 +55514,6 @@ /obj/item/book/manual/wiki/detective, /turf/open/floor/carpet/blue, /area/station/security/prison/work) -"pzx" = ( -/obj/machinery/hydroponics/constructable, -/obj/structure/window/reinforced/spawner/directional/west, -/obj/effect/decal/cleanable/dirt, -/obj/item/seeds/carrot, -/obj/effect/turf_decal/tile/green/half/contrasted{ - dir = 8 - }, -/obj/effect/turf_decal/siding/green{ - dir = 8 - }, -/turf/open/floor/iron/dark, -/area/mine/laborcamp) "pzC" = ( /obj/machinery/firealarm/directional/north, /obj/effect/turf_decal/siding/yellow{ @@ -55754,6 +55521,14 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos) +"pzU" = ( +/obj/structure/cable, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/dark, +/area/station/security/mechbay) "pzV" = ( /obj/structure/table, /obj/item/paper_bin{ @@ -55878,27 +55653,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) -"pCp" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/button/flasher{ - id = "visitorflash"; - pixel_y = -26; - pixel_x = -7 - }, -/obj/machinery/button/door/directional/south{ - pixel_x = 7; - pixel_y = -26; - name = "Visitation Shutters Control"; - id = "visitation"; - req_access = list("brig") - }, -/turf/open/floor/iron, -/area/station/security/prison/visit) -"pCE" = ( -/obj/machinery/firealarm/directional/east, -/obj/structure/filingcabinet, -/turf/open/floor/iron/dark/textured, -/area/station/security/office) "pCG" = ( /obj/structure/fence/corner{ dir = 2 @@ -55919,6 +55673,15 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark, /area/mine/eva) +"pCS" = ( +/obj/structure/railing{ + dir = 4 + }, +/obj/structure/stairs/south, +/turf/open/floor/iron/stairs/medium{ + dir = 1 + }, +/area/mine/laborcamp/security) "pDe" = ( /obj/structure/closet/secure_closet/personal{ anchored = 1 @@ -55948,15 +55711,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central) -"pDy" = ( -/obj/structure/table, -/obj/structure/cable, -/obj/item/clothing/head/beanie/red, -/obj/effect/turf_decal/tile/red/half/contrasted{ - dir = 8 - }, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "pDA" = ( /obj/machinery/portable_atmospherics/canister/air, /obj/effect/turf_decal/stripes/line{ @@ -55968,26 +55722,6 @@ /obj/machinery/light/small/directional/south, /turf/open/floor/plating, /area/station/maintenance/fore) -"pDB" = ( -/obj/item/radio/intercom/directional/north, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 - }, -/turf/open/floor/iron/smooth, -/area/station/security/brig/upper) -"pDC" = ( -/obj/machinery/door/airlock/external{ - name = "Escape Pod Three"; - space_dir = 1 - }, -/turf/open/floor/iron/dark/textured, -/area/station/security/processing) -"pDI" = ( -/obj/structure/table, -/obj/machinery/computer/libraryconsole/bookmanagement, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/mine/laborcamp) "pDL" = ( /obj/structure/sign/departments/psychology/directional/south, /obj/effect/turf_decal/trimline/blue/filled/line{ @@ -56008,9 +55742,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/carpet, /area/station/service/library) -"pDW" = ( -/turf/open/floor/plating, -/area/mine/laborcamp/security) "pEc" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -56090,16 +55821,6 @@ }, /turf/open/floor/carpet, /area/station/security/detectives_office) -"pEX" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/firealarm/directional/north, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/security/prison/mess) "pFg" = ( /obj/structure/chair{ dir = 8 @@ -56124,13 +55845,6 @@ /obj/machinery/computer/security/telescreen/entertainment/directional/north, /turf/open/floor/iron/grimy, /area/station/commons/vacant_room/office) -"pFZ" = ( -/obj/item/target/syndicate, -/obj/effect/decal/cleanable/dirt, -/obj/structure/training_machine, -/obj/effect/turf_decal/bot_red, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) "pGd" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 1 @@ -56199,6 +55913,12 @@ /obj/machinery/photocopier/prebuilt, /turf/open/floor/wood, /area/station/service/library) +"pGU" = ( +/obj/structure/chair, +/obj/structure/sign/warning/electric_shock/directional/north, +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/security/execution/education) "pGW" = ( /obj/machinery/camera/directional/west{ c_tag = "MiniSat External SouthEast"; @@ -56272,6 +55992,16 @@ /obj/machinery/status_display/evac/directional/north, /turf/open/floor/iron/grimy, /area/station/service/chapel/office) +"pIl" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/machinery/door/airlock/maintenance{ + name = "Vestibule Maintenance" + }, +/obj/effect/mapping_helpers/airlock/access/all/security/general, +/turf/open/floor/plating, +/area/station/maintenance/department/security) "pIm" = ( /obj/machinery/atmospherics/components/binary/pump{ dir = 8; @@ -56388,12 +56118,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/medbay/aft) -"pJY" = ( -/obj/structure/table, -/obj/machinery/recharger, -/obj/effect/turf_decal/tile/red, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "pKb" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -56443,11 +56167,6 @@ }, /turf/open/floor/iron/white, /area/station/science/robotics/lab) -"pKR" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/plating, -/area/station/security/prison/safe) "pKS" = ( /obj/machinery/atmospherics/pipe/multiz/supply/visible/layer4, /obj/machinery/atmospherics/pipe/multiz/scrubbers/visible/layer2, @@ -56489,6 +56208,13 @@ dir = 8 }, /area/station/hallway/secondary/entry) +"pLp" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/security/prison/workout) "pLt" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -56543,17 +56269,6 @@ /obj/effect/spawner/random/trash/botanical_waste, /turf/open/floor/plating, /area/station/maintenance/port/fore) -"pMg" = ( -/obj/machinery/door/airlock/external{ - name = "Labor Camp Shuttle Airlock"; - req_access = list("brig") - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 8 - }, -/obj/effect/mapping_helpers/airlock/access/all/security/brig, -/turf/open/floor/iron/dark/smooth_large, -/area/station/security/processing) "pMq" = ( /obj/machinery/camera/directional/south{ c_tag = "Atmospherics Storage Room - South" @@ -56647,6 +56362,14 @@ }, /turf/open/floor/iron/dark/airless, /area/station/science/ordnance/freezerchamber) +"pNH" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/disposalpipe/segment, +/obj/machinery/light/floor, +/turf/open/floor/iron, +/area/station/security/brig/upper) "pNK" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 4 @@ -56885,6 +56608,11 @@ }, /turf/open/floor/iron/dark/smooth_half, /area/station/medical/morgue) +"pRA" = ( +/obj/item/radio/intercom/prison/directional/west, +/obj/structure/table, +/turf/open/floor/iron, +/area/mine/laborcamp) "pRL" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -56898,11 +56626,6 @@ }, /turf/open/floor/plating, /area/station/commons/vacant_room/commissary) -"pRZ" = ( -/obj/machinery/shower/directional/south, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/turf/open/floor/iron/freezer, -/area/mine/laborcamp) "pSk" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -56972,6 +56695,10 @@ /obj/structure/sign/warning/cold_temp/directional/north, /turf/open/floor/plating/snowed/icemoon, /area/icemoon/surface/outdoors/nospawn) +"pSN" = ( +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/security/execution/education) "pTd" = ( /obj/structure/table/reinforced, /obj/machinery/door/poddoor/shutters/preopen{ @@ -57011,6 +56738,14 @@ }, /turf/open/floor/iron/dark, /area/station/service/hydroponics) +"pTl" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment, +/obj/machinery/light/floor, +/turf/open/floor/iron, +/area/station/security/brig/upper) "pTy" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -57084,6 +56819,14 @@ }, /turf/open/floor/plating, /area/station/cargo/storage) +"pUl" = ( +/obj/structure/table, +/obj/item/knife/plastic{ + pixel_x = -4; + pixel_y = -2 + }, +/turf/open/floor/iron/kitchen_coldroom/freezerfloor, +/area/station/security/prison/mess) "pUn" = ( /obj/structure/sink/directional/west, /obj/effect/turf_decal/stripes/line{ @@ -57256,14 +56999,6 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/science/xenobiology) -"pXk" = ( -/obj/machinery/door/window/brigdoor/right/directional/north{ - name = "Flash Storage"; - req_access = list("armory") - }, -/obj/machinery/recharge_station, -/turf/open/floor/iron/smooth, -/area/station/security/brig/upper) "pXn" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 1 @@ -57294,12 +57029,26 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/port/aft) -"pXB" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 +"pXw" = ( +/obj/machinery/door/poddoor/preopen{ + id = "Prison Gate"; + name = "Prison Blast Door" }, -/turf/open/floor/iron, -/area/mine/laborcamp/security) +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/status_display/door_timer{ + id = "Cell 1"; + name = "Cell 1"; + pixel_x = -32 + }, +/obj/effect/turf_decal/stripes/red/line, +/obj/effect/turf_decal/stripes/red/line{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron/dark/textured, +/area/station/security/brig) "pXE" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -57324,12 +57073,6 @@ /obj/machinery/atmospherics/pipe/heat_exchanging/simple, /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/surface/outdoors/less_spawns) -"pYa" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 - }, -/turf/open/floor/iron/cafeteria, -/area/station/security/prison/mess) "pYg" = ( /obj/effect/turf_decal/siding/yellow{ dir = 8 @@ -57655,6 +57398,12 @@ /obj/item/storage/medkit/emergency, /turf/open/floor/iron, /area/station/commons/dorms) +"qbB" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/turf/open/floor/iron, +/area/mine/production) "qbF" = ( /obj/structure/closet/secure_closet/personal/cabinet, /obj/effect/landmark/start/hangover, @@ -57732,17 +57481,13 @@ /obj/machinery/plumbing/sender, /turf/open/floor/plating, /area/station/medical/chemistry) -"qdl" = ( -/obj/machinery/light/small/directional/east, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/trimline/red/warning{ - dir = 6 +"qde" = ( +/obj/effect/turf_decal/tile/red/half/contrasted, +/obj/effect/landmark/firealarm_sanity, +/turf/open/floor/iron/dark/textured_edge{ + dir = 1 }, -/obj/effect/turf_decal/stripes/red/line{ - dir = 9 - }, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) +/area/station/security/prison) "qdq" = ( /obj/structure/railing, /obj/structure/disposalpipe/segment{ @@ -57770,12 +57515,6 @@ }, /turf/open/floor/iron/dark/smooth_large, /area/station/command/eva) -"qdF" = ( -/obj/machinery/vending/wardrobe/sec_wardrobe, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/light/directional/north, -/turf/open/floor/iron/smooth_edge, -/area/station/security/lockers) "qdH" = ( /obj/structure/bookcase/random, /obj/structure/sign/poster/official/nanomichi_ad/directional/north, @@ -57806,6 +57545,9 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating, /area/station/maintenance/fore) +"qdP" = ( +/turf/closed/wall, +/area/station/security/range) "qdX" = ( /obj/machinery/turretid{ control_area = "/area/station/ai/satellite/interior"; @@ -57827,6 +57569,10 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/wood, /area/station/service/lawoffice) +"qdZ" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/turf/open/floor/iron/smooth, +/area/station/security/lockers) "qea" = ( /obj/structure/rack, /obj/item/storage/toolbox/mechanical{ @@ -57850,6 +57596,16 @@ /obj/machinery/microwave, /turf/open/floor/stone, /area/mine/eva/lower) +"qeo" = ( +/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/machinery/light/floor, +/turf/open/floor/iron, +/area/station/security/brig/upper) "qes" = ( /obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -57869,6 +57625,10 @@ dir = 4 }, /area/station/hallway/secondary/entry) +"qeI" = ( +/obj/machinery/portable_atmospherics/canister/air, +/turf/open/floor/plating, +/area/station/maintenance/department/security) "qeK" = ( /obj/machinery/door/airlock/maintenance, /obj/structure/cable, @@ -57929,11 +57689,6 @@ /obj/machinery/vitals_reader/directional/north, /turf/open/floor/iron/large, /area/station/medical/treatment_center) -"qfs" = ( -/obj/machinery/portable_atmospherics/canister/air, -/obj/structure/cable, -/turf/open/floor/plating, -/area/station/security/prison/safe) "qfy" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/caution/stand_clear{ @@ -58007,6 +57762,13 @@ }, /turf/open/floor/iron/dark, /area/station/commons/fitness) +"qgd" = ( +/obj/effect/turf_decal/tile/red/opposingcorners, +/obj/structure/closet/crate/trashcart, +/obj/effect/spawner/random/contraband/permabrig_gear, +/obj/effect/spawner/random/contraband/permabrig_weapon, +/turf/open/floor/iron, +/area/station/security/prison/mess) "qgm" = ( /obj/machinery/meter/monitored/waste_loop, /obj/machinery/atmospherics/pipe/smart/manifold/scrubbers/visible{ @@ -58033,12 +57795,6 @@ /obj/effect/spawner/random/maintenance/three, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) -"qgO" = ( -/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/processing) "qhb" = ( /obj/structure/table/wood, /obj/effect/spawner/random/trash/crushed_can, @@ -58077,16 +57833,6 @@ /obj/machinery/space_heater, /turf/open/floor/plating, /area/station/maintenance/port/fore) -"qhP" = ( -/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/red/half/contrasted{ - dir = 1 - }, -/obj/machinery/light/floor, -/turf/open/floor/iron/dark/side, -/area/station/security/processing) "qhR" = ( /obj/structure/fence/corner{ dir = 2 @@ -58125,11 +57871,11 @@ /obj/effect/turf_decal/tile/brown/half/contrasted, /turf/open/floor/iron/dark/side, /area/mine/eva/lower) -"qiJ" = ( -/obj/structure/closet/secure_closet/freezer/kitchen/maintenance, -/obj/effect/spawner/random/contraband/prison, -/turf/open/floor/iron/showroomfloor, -/area/station/security/prison/mess) +"qiH" = ( +/obj/structure/table, +/obj/item/taperecorder, +/turf/open/floor/iron/dark, +/area/station/security/interrogation) "qiK" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/brown/anticorner/contrasted{ @@ -58210,15 +57956,6 @@ /obj/structure/girder, /turf/open/floor/plating, /area/station/maintenance/port/fore) -"qjE" = ( -/obj/machinery/door/airlock/security{ - name = "Private Cell" - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/carpet/black, -/area/station/security/prison/safe) "qjF" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 9 @@ -58256,6 +57993,10 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/stone, /area/station/service/bar/atrium) +"qkf" = ( +/obj/structure/cable, +/turf/open/floor/iron, +/area/mine/laborcamp) "qkg" = ( /mob/living/basic/pet/penguin/baby/permanent, /obj/item/toy/snowball{ @@ -58271,6 +58012,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/carpet/blue, /area/station/hallway/secondary/entry) +"qkv" = ( +/obj/structure/rack, +/obj/item/book/bible, +/obj/item/book/bible{ + pixel_y = 3; + pixel_x = 3 + }, +/turf/open/floor/iron/dark, +/area/station/security/prison/rec) "qkB" = ( /obj/effect/turf_decal/trimline/green/filled/corner{ dir = 1 @@ -58282,17 +58032,16 @@ }, /turf/open/floor/iron/dark, /area/station/medical/virology) -"qkI" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/railing/corner/end{ - dir = 4 +"qkP" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/disposalpipe/segment, +/obj/structure/railing/corner/end/flip{ + dir = 8 }, -/turf/open/floor/iron, -/area/mine/production) -"qkL" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/station/security/lockers) +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/smooth, +/area/station/engineering/lobby) "qkR" = ( /obj/structure/extinguisher_cabinet/directional/west, /obj/machinery/chem_master, @@ -58429,13 +58178,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply, /turf/open/floor/plating, /area/station/medical/virology) -"qna" = ( -/obj/machinery/camera/directional/east{ - c_tag = "Security - Permabrig Chapel"; - network = list("ss13","prison") - }, -/turf/open/floor/carpet, -/area/station/security/prison/rec) "qnj" = ( /turf/closed/wall, /area/station/commons/locker) @@ -58456,6 +58198,17 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply, /turf/open/floor/iron/dark, /area/station/medical/virology) +"qnv" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/trimline/red/warning{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/red/line{ + dir = 8 + }, +/obj/machinery/light/small/red/directional/west, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/surface/outdoors/nospawn) "qnw" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/brown/half{ @@ -58469,6 +58222,9 @@ "qnC" = ( /turf/closed/wall/r_wall, /area/station/command/heads_quarters/ce) +"qnI" = ( +/turf/open/floor/iron/kitchen_coldroom/freezerfloor, +/area/station/security/prison/mess) "qnO" = ( /obj/machinery/atmospherics/components/trinary/mixer/airmix{ dir = 4 @@ -58538,10 +58294,17 @@ /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/plating, /area/station/maintenance/department/medical/morgue) -"qoY" = ( -/obj/effect/spawner/random/structure/crate_abandoned, +"qoU" = ( +/obj/structure/cable, +/obj/effect/spawner/structure/window/reinforced/tinted, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/door/poddoor/preopen{ + id = "labor"; + name = "Labor Camp Blast Door" + }, /turf/open/floor/plating, -/area/station/security/prison/safe) +/area/mine/laborcamp) "qpb" = ( /obj/machinery/disposal/bin{ desc = "A pneumatic waste disposal unit. This one leads to the morgue."; @@ -58769,6 +58532,14 @@ }, /turf/open/floor/iron/smooth, /area/station/engineering/lobby) +"qrz" = ( +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/structure/sign/warning/pods/directional/north, +/turf/open/floor/iron, +/area/station/security/brig/upper) "qrB" = ( /obj/effect/turf_decal/siding/wood{ dir = 8 @@ -58830,16 +58601,6 @@ "qtj" = ( /turf/closed/wall, /area/station/engineering/storage) -"qts" = ( -/obj/structure/window/reinforced/spawner/directional/west, -/obj/effect/turf_decal/stripes/red/line{ - dir = 5 - }, -/obj/effect/turf_decal/trimline/red/line{ - dir = 1 - }, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) "qtu" = ( /obj/structure/table, /obj/item/mmi, @@ -58868,13 +58629,6 @@ /obj/structure/sign/warning/directional/south, /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/surface/outdoors/less_spawns) -"qtH" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 4 - }, -/turf/open/floor/iron, -/area/mine/laborcamp) "qtM" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable, @@ -58884,18 +58638,6 @@ /obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance, /turf/open/floor/plating, /area/station/maintenance/port/aft) -"qud" = ( -/obj/machinery/conveyor_switch/oneway{ - id = "mining_internal"; - name = "mining conveyor"; - pixel_x = 1; - pixel_y = 8 - }, -/obj/structure/railing{ - dir = 4 - }, -/turf/open/floor/iron, -/area/mine/production) "que" = ( /obj/machinery/camera/directional/south{ c_tag = "Chapel South" @@ -59021,19 +58763,6 @@ }, /turf/open/floor/iron/dark, /area/station/engineering/atmos/storage/gas) -"qwa" = ( -/obj/machinery/door/window/brigdoor/right/directional/west{ - name = "Shooting Range" - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/red/line{ - dir = 8 - }, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) "qwe" = ( /obj/structure/table, /obj/item/phone{ @@ -59095,6 +58824,10 @@ }, /turf/open/floor/iron/dark, /area/station/cargo/miningdock) +"qxg" = ( +/obj/structure/closet/secure_closet/freezer/meat/all_access, +/turf/open/floor/iron/kitchen_coldroom/freezerfloor, +/area/station/security/prison/mess) "qxl" = ( /obj/structure/table, /obj/item/storage/box/beakers{ @@ -59162,12 +58895,6 @@ "qxI" = ( /turf/open/floor/plastic, /area/station/commons/dorms/laundry) -"qxN" = ( -/obj/structure/railing{ - dir = 4 - }, -/turf/open/misc/asteroid/snow/icemoon, -/area/icemoon/underground/explored) "qxQ" = ( /obj/effect/turf_decal/delivery, /turf/open/floor/iron, @@ -59288,6 +59015,16 @@ }, /turf/open/misc/hay/icemoon, /area/icemoon/underground/explored) +"qAz" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/event_spawn, +/obj/structure/railing, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/iron, +/area/mine/production) "qAB" = ( /obj/structure/table/wood, /obj/item/flashlight/lamp, @@ -59415,6 +59152,12 @@ /obj/machinery/airalarm/directional/east, /turf/open/floor/plating, /area/station/ai/satellite/maintenance) +"qDb" = ( +/obj/effect/spawner/structure/window, +/obj/structure/cable, +/obj/machinery/door/firedoor, +/turf/open/floor/plating, +/area/station/security/brig/upper) "qDm" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable, @@ -59432,6 +59175,13 @@ }, /turf/open/floor/plating, /area/station/cargo/storage) +"qDu" = ( +/obj/effect/turf_decal/tile/red/anticorner/contrasted, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 1 + }, +/turf/open/floor/iron/dark/textured, +/area/station/security/armory/upper) "qDA" = ( /obj/structure/bed{ dir = 4 @@ -59445,19 +59195,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/carpet/donk, /area/mine/production) -"qDD" = ( -/obj/machinery/washing_machine, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/blue/opposingcorners{ - dir = 1 - }, -/turf/open/floor/iron/cafeteria, -/area/mine/laborcamp) -"qDG" = ( -/obj/structure/punching_bag, -/obj/effect/turf_decal/bot, -/turf/open/floor/iron/dark/textured, -/area/station/security/prison/workout) "qDI" = ( /obj/effect/spawner/structure/window, /turf/open/floor/plating, @@ -59553,6 +59290,14 @@ /obj/structure/weightmachine, /turf/open/floor/iron, /area/station/commons/fitness) +"qEF" = ( +/obj/effect/mapping_helpers/airlock/access/all/security/general, +/obj/machinery/door/airlock/security/glass{ + name = "Security Firing Range"; + security_level = 1 + }, +/turf/open/floor/iron/dark, +/area/station/security/range) "qEJ" = ( /turf/closed/wall, /area/station/service/chapel/office) @@ -59659,11 +59404,26 @@ /obj/structure/cable, /turf/open/floor/iron/dark/smooth_large, /area/station/security/checkpoint/customs/auxiliary) +"qFM" = ( +/obj/structure/rack, +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 4 + }, +/obj/effect/spawner/random/armory/e_gun, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron/dark/textured, +/area/station/security/armory/upper) "qFO" = ( /obj/structure/flora/bush/flowers_yw/style_random, /obj/structure/flora/bush/sparsegrass/style_random, /turf/open/floor/grass, /area/station/service/hydroponics) +"qFU" = ( +/obj/structure/chair/stool/directional/south, +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/mine/laborcamp) "qFW" = ( /obj/machinery/door/airlock/maintenance, /obj/effect/mapping_helpers/airlock/abandoned, @@ -59904,19 +59664,6 @@ /obj/machinery/airalarm/directional/north, /turf/open/floor/iron, /area/station/service/hydroponics) -"qJC" = ( -/obj/machinery/seed_extractor, -/obj/structure/window/reinforced/spawner/directional/west, -/obj/structure/window/reinforced/spawner/directional/north, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/green/anticorner/contrasted{ - dir = 1 - }, -/obj/effect/turf_decal/siding/green{ - dir = 9 - }, -/turf/open/floor/iron/dark, -/area/mine/laborcamp) "qJT" = ( /obj/machinery/light/small/directional/south, /turf/open/floor/plating/snowed/icemoon, @@ -59928,16 +59675,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central) -"qJY" = ( -/obj/machinery/door/airlock/maintenance{ - name = "Permabrig Maintenance" - }, -/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/security/brig, -/turf/open/floor/plating, -/area/station/security/prison/safe) "qKa" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/decal/cleanable/dirt, @@ -60004,28 +59741,6 @@ }, /turf/open/floor/plating, /area/station/command/heads_quarters/ce) -"qKS" = ( -/obj/machinery/light/small/directional/south, -/obj/structure/closet/secure_closet/brig{ - id = "Cell 1"; - name = "Cell 1 locker" - }, -/obj/structure/cable, -/turf/open/floor/iron/smooth, -/area/station/security/brig) -"qLg" = ( -/obj/effect/spawner/random/contraband/narcotics, -/obj/structure/sign/poster/contraband/syndiemoth/directional/west, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/plating, -/area/station/security/prison/safe) -"qLi" = ( -/obj/effect/turf_decal/siding/wideplating/dark{ - dir = 8 - }, -/obj/machinery/newscaster/directional/west, -/turf/open/floor/iron/dark/textured, -/area/station/security/prison/rec) "qLm" = ( /obj/machinery/suit_storage_unit/mining, /obj/effect/turf_decal/bot, @@ -60086,11 +59801,12 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/mine/eva/lower) -"qLX" = ( -/obj/effect/decal/cleanable/dirt, -/obj/item/toy/basketball, -/turf/open/floor/iron, -/area/station/security/prison/workout) +"qLR" = ( +/obj/structure/cable, +/obj/effect/spawner/structure/window/hollow/reinforced/middle, +/obj/machinery/door/firedoor, +/turf/open/floor/plating, +/area/station/security/prison/rec) "qLY" = ( /turf/closed/wall/r_wall, /area/station/science/xenobiology) @@ -60227,6 +59943,15 @@ /obj/effect/turf_decal/tile/dark_blue/diagonal_edge, /turf/open/floor/iron/dark/diagonal, /area/station/engineering/atmos/mix) +"qNA" = ( +/obj/structure/cable, +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/item/kirbyplants/random, +/turf/open/floor/iron/dark/textured, +/area/station/security/office) "qNE" = ( /obj/effect/spawner/random/trash/mess, /turf/open/floor/plating, @@ -60318,21 +60043,6 @@ /obj/machinery/power/apc/auto_name/directional/north, /turf/open/floor/iron/dark, /area/station/science/server) -"qOP" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/camera/directional/south{ - c_tag = "Security - Vestibule" - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red/half/contrasted, -/turf/open/floor/iron/dark/side{ - dir = 1 - }, -/area/station/security/processing) "qPb" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -60374,11 +60084,6 @@ /obj/effect/turf_decal/tile/brown/half/contrasted, /turf/open/floor/iron/dark/side, /area/mine/eva) -"qPp" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/smooth, -/area/station/security/holding_cell) "qPq" = ( /obj/machinery/door/airlock/maintenance{ name = "Security Maintenance" @@ -60413,6 +60118,17 @@ }, /turf/open/floor/wood, /area/station/maintenance/port/aft) +"qPD" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron/dark/side{ + dir = 1 + }, +/area/station/security/prison) "qPE" = ( /obj/structure/closet/secure_closet/freezer/meat, /turf/open/misc/asteroid/snow/coldroom, @@ -60502,6 +60218,17 @@ /obj/effect/turf_decal/tile/red, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) +"qQQ" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/dark, +/area/station/security/execution/education) +"qQS" = ( +/obj/effect/turf_decal/stripes/corner, +/obj/effect/turf_decal/tile/red/half/contrasted, +/turf/open/floor/iron, +/area/station/security/brig/upper) "qRk" = ( /obj/item/chair/wood, /turf/open/floor/carpet, @@ -60558,17 +60285,20 @@ }, /turf/open/floor/iron/dark/textured, /area/station/hallway/primary/starboard) +"qRM" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/security/execution/education) "qRO" = ( /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/science/ordnance) -"qSb" = ( -/obj/structure/window/reinforced/spawner/directional/north, -/obj/structure/window/reinforced/spawner/directional/west, -/turf/open/floor/iron/dark/textured, -/area/station/security/prison/workout) "qSh" = ( /obj/structure/sink/directional/east, /obj/structure/mirror/directional/west, @@ -60629,12 +60359,6 @@ }, /turf/open/lava/plasma/ice_moon, /area/icemoon/underground/explored) -"qSu" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/sepia, -/area/station/security/prison/rec) "qSE" = ( /obj/machinery/door/poddoor/preopen{ id = "misclab"; @@ -60686,9 +60410,6 @@ }, /turf/open/floor/iron, /area/station/service/hydroponics/garden) -"qTs" = ( -/turf/open/floor/iron/showroomfloor, -/area/station/security/prison/mess) "qTD" = ( /obj/structure/marker_beacon/burgundy{ name = "landing marker" @@ -60749,11 +60470,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/brown/visible/layer2, /turf/open/floor/iron, /area/station/maintenance/disposal/incinerator) -"qUw" = ( -/obj/structure/closet/secure_closet/brig, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/mine/laborcamp) "qUI" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 4 @@ -60846,14 +60562,6 @@ }, /turf/open/floor/iron/smooth, /area/station/maintenance/port/lesser) -"qVJ" = ( -/obj/machinery/disposal/bin, -/obj/machinery/light_switch/directional/south, -/obj/structure/disposalpipe/trunk{ - dir = 8 - }, -/turf/open/floor/iron/dark/smooth_large, -/area/station/command/heads_quarters/hos) "qVK" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -60955,6 +60663,10 @@ dir = 1 }, /area/station/hallway/secondary/exit/departure_lounge) +"qWP" = ( +/obj/structure/cable, +/turf/open/floor/iron/dark, +/area/station/security/mechbay) "qWS" = ( /obj/structure/cable, /obj/effect/landmark/event_spawn, @@ -60986,6 +60698,11 @@ /obj/structure/flora/bush/jungle/c/style_random, /turf/open/floor/grass, /area/station/medical/virology) +"qXY" = ( +/obj/structure/sign/warning/firing_range/directional/west, +/obj/structure/flora/grass/both/style_random, +/turf/open/misc/asteroid/snow/icemoon, +/area/icemoon/surface/outdoors/nospawn) "qYb" = ( /obj/structure/disposalpipe/segment, /obj/effect/turf_decal/stripes/line{ @@ -61106,6 +60823,15 @@ /obj/structure/sign/poster/official/random/directional/north, /turf/open/floor/plating, /area/station/maintenance/port/aft) +"qYS" = ( +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/security/brig/upper) "qYV" = ( /obj/machinery/smartfridge/chemistry/preloaded, /obj/machinery/door/firedoor, @@ -61157,6 +60883,15 @@ /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) +"qZI" = ( +/obj/effect/spawner/structure/window/reinforced/tinted, +/obj/machinery/door/poddoor/preopen{ + id = "labor"; + name = "Labor Camp Blast Door" + }, +/obj/structure/cable, +/turf/open/floor/plating, +/area/mine/laborcamp) "qZN" = ( /turf/closed/wall/r_wall, /area/station/science/ordnance/freezerchamber) @@ -61175,6 +60910,11 @@ /obj/machinery/firealarm/directional/south, /turf/open/floor/iron/textured, /area/mine/mechbay) +"qZU" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/security/brig) "qZZ" = ( /obj/structure/marker_beacon/yellow, /turf/open/misc/dirt{ @@ -61230,12 +60970,6 @@ /obj/structure/reagent_dispensers/fueltank, /turf/open/floor/iron/dark, /area/station/engineering/storage) -"rax" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 - }, -/turf/open/floor/iron/showroomfloor, -/area/station/security/processing) "raA" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/landmark/start/atmospheric_technician, @@ -61263,13 +60997,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/engineering/supermatter/room) -"raY" = ( -/obj/machinery/camera/directional/east{ - c_tag = "Security - Permabrig Observation South"; - network = list("ss13","prison") - }, -/turf/open/lava/plasma/ice_moon, -/area/icemoon/underground/explored) "rbb" = ( /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 8 @@ -61317,11 +61044,6 @@ }, /turf/open/floor/iron/dark, /area/station/service/hydroponics/garden) -"rbT" = ( -/obj/structure/ore_box, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/mine/laborcamp) "rbV" = ( /obj/structure/fence/post{ dir = 2 @@ -61375,6 +61097,21 @@ /obj/effect/spawner/structure/window, /turf/open/floor/plating, /area/station/hallway/primary/central) +"rcF" = ( +/obj/structure/table/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + dir = 8; + id = "gene_desk_shutters"; + name = "Genetics Shutters" + }, +/obj/machinery/door/firedoor, +/obj/machinery/door/window/right/directional/east{ + name = "Genetics Desk"; + req_access = list("genetics") + }, +/obj/structure/window/reinforced/spawner/directional/south, +/turf/open/floor/plating, +/area/station/science/genetics) "rcP" = ( /obj/effect/turf_decal/bot_white/right, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -61436,11 +61173,6 @@ }, /turf/open/floor/iron/dark, /area/station/service/hydroponics) -"rdw" = ( -/obj/structure/bookcase, -/obj/machinery/light/small/directional/north, -/turf/open/floor/carpet, -/area/station/security/processing) "rdG" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 8 @@ -61515,6 +61247,10 @@ dir = 1 }, /area/station/command/heads_quarters/rd) +"reu" = ( +/obj/machinery/light/small/directional/east, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/underground/explored) "reJ" = ( /obj/machinery/navbeacon{ codes_txt = "delivery;dir=8"; @@ -61543,6 +61279,11 @@ }, /turf/open/floor/iron/dark, /area/station/service/bar) +"reR" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/security/eva) "reT" = ( /obj/machinery/door/window/left/directional/east{ name = "Containment Pen 8"; @@ -61583,11 +61324,26 @@ "rfu" = ( /turf/closed/wall/r_wall, /area/station/security/prison/rec) +"rfC" = ( +/mob/living/basic/mouse/white{ + desc = "This mouse smells faintly of alcohol."; + name = "Mik" + }, +/obj/effect/mapping_helpers/broken_floor, +/turf/open/floor/wood, +/area/station/maintenance/fore) "rfF" = ( /obj/effect/spawner/random/trash/mess, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/port/greater) +"rfJ" = ( +/obj/machinery/computer/security/telescreen/interrogation/directional/west, +/obj/structure/chair/stool/directional/west, +/obj/item/radio/intercom/interrogation/outside/directional/east, +/obj/effect/spawner/random/trash/cigbutt, +/turf/open/floor/iron/dark/textured_large, +/area/station/security/interrogation) "rfQ" = ( /obj/structure/disposalpipe/segment{ dir = 10 @@ -61667,6 +61423,13 @@ "rgE" = ( /turf/closed/wall/r_wall, /area/station/engineering/atmos/hfr_room) +"rgP" = ( +/obj/machinery/door/window/brigdoor/left/directional/west{ + req_access = list("security"); + name = "Security Delivery" + }, +/turf/open/floor/plating, +/area/station/maintenance/fore) "rhf" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable, @@ -61749,6 +61512,15 @@ /obj/effect/mapping_helpers/mail_sorting/security/general, /turf/open/floor/iron, /area/station/security/brig/upper) +"riy" = ( +/obj/machinery/camera/directional/east{ + c_tag = "Security - Labor Camp Stairs"; + network = list("ss13","prison","labor") + }, +/obj/effect/turf_decal/tile/red, +/obj/structure/sign/poster/official/nanotrasen_logo/directional/east, +/turf/open/floor/iron, +/area/station/security/brig) "riB" = ( /obj/machinery/computer/records/security, /obj/machinery/computer/security/telescreen/normal/directional/north, @@ -61799,6 +61571,14 @@ /obj/machinery/light/small/directional/east, /turf/open/floor/iron/smooth, /area/station/security/execution/transfer) +"rjm" = ( +/obj/effect/turf_decal/tile/red, +/obj/machinery/light/warm/directional/east, +/obj/structure/chair/sofa/bench/right{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/security/prison/mess) "rjr" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply, /turf/open/floor/plating, @@ -61811,6 +61591,12 @@ /obj/effect/turf_decal/tile/blue/fourcorners, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/cmo) +"rjx" = ( +/obj/effect/turf_decal/stripes/red/line{ + dir = 4 + }, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/surface/outdoors/nospawn) "rjE" = ( /obj/structure/fluff/tram_rail{ pixel_y = 17 @@ -62000,11 +61786,10 @@ }, /turf/open/floor/carpet, /area/station/commons/dorms) -"rmv" = ( -/obj/structure/rack, -/obj/item/wrench, +"rmz" = ( +/obj/machinery/light/directional/north, /turf/open/floor/iron, -/area/mine/laborcamp/security) +/area/mine/laborcamp) "rmA" = ( /obj/structure/cable, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -62046,10 +61831,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/port/aft) -"rnl" = ( -/obj/structure/railing, -/turf/open/floor/iron, -/area/mine/production) "rnp" = ( /obj/machinery/door/poddoor/incinerator_atmos_main{ dir = 4 @@ -62183,10 +61964,10 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/iron, /area/station/science/xenobiology) -"roH" = ( -/obj/structure/chair/pew/right, -/turf/open/floor/wood, -/area/station/security/prison/rec) +"roG" = ( +/obj/machinery/holopad, +/turf/open/floor/iron/dark/side, +/area/station/security/range) "roQ" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -62246,15 +62027,6 @@ }, /turf/open/floor/iron/smooth_large, /area/station/cargo/warehouse) -"rpT" = ( -/obj/structure/closet/emcloset, -/obj/machinery/camera/directional/north{ - c_tag = "Security - Access" - }, -/obj/effect/turf_decal/tile/red/half, -/obj/machinery/light/directional/north, -/turf/open/floor/iron/smooth_half, -/area/station/security/brig/upper) "rpU" = ( /obj/machinery/iv_drip, /obj/effect/turf_decal/trimline/green/filled/line{ @@ -62345,17 +62117,6 @@ /obj/structure/sign/warning/secure_area/directional/north, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) -"rqR" = ( -/obj/machinery/biogenerator, -/obj/structure/window/reinforced/spawner/directional/north, -/obj/effect/turf_decal/tile/green/anticorner/contrasted{ - dir = 4 - }, -/obj/effect/turf_decal/siding/green{ - dir = 5 - }, -/turf/open/floor/iron/dark, -/area/mine/laborcamp) "rqY" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 9 @@ -62604,6 +62365,15 @@ /obj/structure/window/reinforced/spawner/directional/south, /turf/open/floor/iron/white/textured, /area/station/security/medical) +"ruf" = ( +/obj/machinery/atmospherics/pipe/multiz/scrubbers/visible/layer2{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/multiz/supply/visible/layer4{ + dir = 1 + }, +/turf/open/floor/plating, +/area/station/maintenance/department/security) "ruo" = ( /obj/machinery/portable_atmospherics/canister/air, /obj/effect/turf_decal/bot, @@ -62616,13 +62386,6 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos) -"ruC" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/dark/textured_edge{ - dir = 1 - }, -/area/station/security/prison) "ruD" = ( /obj/machinery/space_heater, /turf/open/floor/plating, @@ -62656,27 +62419,11 @@ }, /turf/open/floor/iron, /area/station/engineering/main) -"ruP" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/wall_healer/directional/east, -/turf/open/floor/iron/white/textured, -/area/station/security/medical) "ruZ" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/cable/layer3, /turf/open/floor/iron/dark, /area/station/ai/satellite/chamber) -"rvj" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/eighties/red, -/area/station/security/prison/safe) -"rvy" = ( -/obj/effect/turf_decal/bot, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/mine/laborcamp) "rvA" = ( /obj/structure/disposalpipe/segment, /obj/effect/turf_decal/trimline/blue/filled/line{ @@ -62685,6 +62432,12 @@ /obj/machinery/light/directional/east, /turf/open/floor/iron/white, /area/station/medical/medbay/aft) +"rvM" = ( +/obj/machinery/computer/prisoner/gulag_teleporter_computer{ + dir = 1 + }, +/turf/open/floor/iron/dark, +/area/mine/laborcamp/security) "rvS" = ( /obj/structure/rack, /obj/item/poster/random_contraband, @@ -62722,6 +62475,9 @@ }, /turf/open/floor/plating/snowed/icemoon, /area/icemoon/surface/outdoors/nospawn) +"rwA" = ( +/turf/open/floor/carpet/blue, +/area/station/security/prison/work) "rwB" = ( /obj/machinery/atmospherics/pipe/bridge_pipe/orange/visible, /obj/machinery/atmospherics/pipe/bridge_pipe/green/visible{ @@ -62748,11 +62504,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) -"rwR" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/status_display/evac/directional/west, -/turf/open/floor/iron, -/area/mine/laborcamp) "rwZ" = ( /obj/structure/sign/departments/botany/directional/east, /obj/effect/turf_decal/tile/blue, @@ -62930,6 +62681,11 @@ }, /turf/open/floor/plating/snowed/icemoon, /area/icemoon/surface/outdoors/nospawn) +"rzN" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, +/obj/structure/cable, +/turf/open/floor/wood/large, +/area/station/command/heads_quarters/hos) "rzO" = ( /obj/effect/turf_decal/weather/snow/corner{ dir = 10 @@ -62944,19 +62700,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/aft/greater) -"rAr" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/mob/living/simple_animal/bot/secbot/beepsky{ - desc = "Powered by the tears and sweat of laborers."; - name = "Prison Ofitser" - }, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "rAA" = ( /obj/machinery/pdapainter, /turf/open/floor/iron, @@ -62977,15 +62720,6 @@ /obj/structure/closet/emcloset, /turf/open/floor/plating, /area/station/maintenance/port/aft) -"rAR" = ( -/obj/effect/turf_decal/trimline/red/filled/line{ - dir = 8 - }, -/obj/machinery/firealarm/directional/west, -/turf/open/floor/iron/dark/side{ - dir = 8 - }, -/area/station/security/prison) "rAW" = ( /obj/structure/chair, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -63071,13 +62805,6 @@ "rBV" = ( /turf/closed/wall, /area/station/tcommsat/computer) -"rCe" = ( -/obj/structure/toilet{ - dir = 4 - }, -/obj/machinery/light/small/dim/directional/north, -/turf/open/floor/iron/freezer, -/area/mine/laborcamp) "rCf" = ( /turf/open/floor/iron, /area/station/maintenance/starboard/fore) @@ -63132,6 +62859,12 @@ /obj/effect/turf_decal/tile/red, /turf/open/floor/iron, /area/station/security/prison/mess) +"rCK" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/catwalk_floor/iron_smooth, +/area/station/security/eva) "rCO" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -63321,13 +63054,14 @@ /obj/effect/spawner/random/structure/steam_vent, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) -"rEP" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/obj/effect/turf_decal/tile/red/half/contrasted{ - dir = 1 +"rEQ" = ( +/obj/structure/toilet/greyscale{ + cistern_open = 1; + dir = 2 }, -/turf/open/floor/iron/dark/side, -/area/station/security/processing) +/obj/machinery/light/small/directional/north, +/turf/open/floor/iron/showroomfloor, +/area/station/security/prison/toilet) "rES" = ( /obj/effect/turf_decal/siding/brown/corner{ dir = 4 @@ -63343,6 +63077,12 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) +"rEX" = ( +/obj/effect/turf_decal/delivery, +/obj/effect/decal/cleanable/dirt, +/obj/structure/ore_box, +/turf/open/floor/iron, +/area/mine/laborcamp) "rFb" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 1 @@ -63422,6 +63162,15 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron, /area/station/engineering/main) +"rGv" = ( +/obj/machinery/door/poddoor/preopen{ + id = "labor"; + name = "Labor Camp Blast Door" + }, +/obj/machinery/door/firedoor, +/obj/machinery/prisongate/labour, +/turf/open/floor/iron/textured, +/area/mine/laborcamp/security) "rGw" = ( /obj/machinery/smartfridge/chemistry/preloaded, /obj/machinery/door/firedoor, @@ -63485,11 +63234,13 @@ /obj/effect/turf_decal/trimline/blue/filled/line, /turf/open/floor/iron/white, /area/station/medical/medbay/aft) -"rHH" = ( -/obj/structure/table, -/obj/effect/spawner/random/food_or_drink/snack/lizard, +"rHE" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/sign/poster/official/nanotrasen_logo/directional/south, /turf/open/floor/iron, -/area/station/security/prison/mess) +/area/mine/laborcamp) "rHQ" = ( /obj/machinery/computer/message_monitor{ dir = 4 @@ -63499,6 +63250,16 @@ }, /turf/open/floor/iron/dark, /area/station/tcommsat/computer) +"rHT" = ( +/obj/machinery/camera/directional/east{ + c_tag = "Security - Permabrig Library Reading Room"; + network = list("ss13","prison") + }, +/obj/structure/chair/sofa/corp/corner{ + dir = 8 + }, +/turf/open/floor/carpet/blue, +/area/station/security/prison/work) "rHZ" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -63585,16 +63346,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/smooth, /area/station/maintenance/fore/lesser) -"rKs" = ( -/obj/structure/chair/stool/directional/south, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/obj/machinery/light/small/dim/directional/west, -/obj/structure/sign/poster/official/work_for_a_future/directional/west, -/turf/open/floor/iron, -/area/mine/laborcamp) +"rKp" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/structure/closet/firecloset, +/turf/open/floor/plating, +/area/station/maintenance/department/security) "rKv" = ( /obj/machinery/atmospherics/pipe/smart/manifold/supply/visible{ dir = 1 @@ -63661,19 +63419,6 @@ /obj/machinery/computer/security/telescreen/med_sec/directional/east, /turf/open/floor/iron/dark/smooth_large, /area/station/security/checkpoint/medical) -"rLX" = ( -/obj/item/target, -/obj/item/target/syndicate, -/obj/item/target/alien, -/obj/item/target/clown, -/obj/effect/turf_decal/bot, -/obj/structure/window/reinforced/spawner/directional/west, -/obj/structure/window/reinforced/spawner/directional/north, -/obj/structure/closet/crate{ - name = "Firing Range Supplies Set" - }, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) "rMd" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -63785,6 +63530,10 @@ }, /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/surface/outdoors/nospawn) +"rNG" = ( +/obj/structure/closet, +/turf/open/floor/iron/dark/textured, +/area/station/security/prison/safe) "rNK" = ( /obj/structure/railing{ dir = 1 @@ -63831,6 +63580,14 @@ /obj/structure/closet/toolcloset, /turf/open/floor/iron/dark, /area/station/engineering/supermatter/room) +"rOp" = ( +/obj/machinery/vending/cigarette, +/obj/effect/turf_decal/tile/red/full, +/obj/structure/sign/warning/yes_smoking/circle/directional/west{ + pixel_y = -16 + }, +/turf/open/floor/iron/smooth_large, +/area/station/security/brig/upper) "rOq" = ( /obj/structure/marker_beacon/burgundy{ name = "landing marker" @@ -63951,12 +63708,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/virology) -"rQx" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/mine/laborcamp) "rQG" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -64069,13 +63820,6 @@ }, /turf/open/floor/iron/white/textured_large, /area/station/medical/treatment_center) -"rRM" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/landmark/event_spawn, -/obj/machinery/light/floor, -/turf/open/floor/iron/smooth, -/area/station/security/brig/upper) "rRN" = ( /obj/structure/railing, /turf/open/floor/plating, @@ -64179,25 +63923,6 @@ /obj/effect/turf_decal/tile/neutral/opposingcorners, /turf/open/floor/iron, /area/station/commons/vacant_room/commissary) -"rTV" = ( -/obj/structure/gulag_beacon, -/obj/structure/sign/warning/directional/north, -/turf/open/floor/iron, -/area/mine/laborcamp) -"rTX" = ( -/obj/machinery/door/airlock/security/glass{ - name = "Labor Shuttle Dock" - }, -/obj/effect/mapping_helpers/airlock/access/all/security/general, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/door/firedoor, -/turf/open/floor/iron, -/area/station/security/processing) "rTY" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/shutters/preopen{ @@ -64348,13 +64073,6 @@ }, /turf/open/floor/carpet, /area/station/commons/dorms) -"rVX" = ( -/obj/effect/decal/cleanable/dirt, -/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/mine/laborcamp) "rWc" = ( /obj/structure/table, /obj/item/stock_parts/subspace/transmitter, @@ -64392,6 +64110,12 @@ }, /turf/open/floor/engine/plasma, /area/station/engineering/atmos) +"rWs" = ( +/obj/structure/bed/medical/emergency, +/obj/item/clothing/gloves/latex, +/obj/effect/decal/cleanable/blood/gibs/old, +/turf/open/floor/plating, +/area/station/security/prison) "rWH" = ( /obj/machinery/door/airlock/maintenance{ name = "Chemistry Lab Utilities" @@ -64485,19 +64209,6 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos) -"rXg" = ( -/obj/structure/closet/crate/internals, -/obj/item/tank/internals/emergency_oxygen, -/obj/item/tank/internals/emergency_oxygen, -/obj/item/tank/internals/emergency_oxygen, -/obj/item/tank/internals/emergency_oxygen, -/obj/item/clothing/mask/breath, -/obj/item/clothing/mask/breath, -/obj/item/clothing/mask/breath, -/obj/item/clothing/mask/breath, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/mine/laborcamp) "rXj" = ( /obj/structure/bed{ dir = 4 @@ -64531,22 +64242,23 @@ }, /turf/open/floor/plating, /area/station/commons/lounge) +"rXO" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/landmark/start/prisoner, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/vault, +/area/station/security/prison/rec) "rXP" = ( /obj/item/pickaxe/improvised{ pixel_x = 7 }, /turf/open/misc/asteroid/snow/coldroom, /area/icemoon/underground/explored) -"rXX" = ( -/obj/machinery/door/airlock/external{ - name = "Labor Camp Shuttle Airlock"; - shuttledocked = 1 - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 8 - }, -/turf/open/floor/iron/dark/smooth_large, -/area/station/security/processing) +"rYn" = ( +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/maintenance/department/security) "rYq" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -64641,6 +64353,15 @@ }, /turf/open/floor/iron/dark, /area/station/engineering/atmos/project) +"rZP" = ( +/obj/structure/table, +/obj/item/storage/box/evidence, +/obj/machinery/button/door/directional/west{ + id = "Interrogation"; + name = "Interrogation Shutters" + }, +/turf/open/floor/iron/dark/textured, +/area/station/security/interrogation) "rZR" = ( /obj/effect/turf_decal/trimline/blue/filled/line, /obj/effect/landmark/start/chief_medical_officer, @@ -64698,23 +64419,6 @@ /obj/structure/window/spawner/directional/north, /turf/open/floor/plating, /area/station/maintenance/department/chapel) -"saX" = ( -/obj/machinery/button/door/directional/west{ - id = "executionfireblast"; - name = "Transfer Area Lockdown"; - pixel_y = -6; - req_access = list("brig") - }, -/obj/structure/railing, -/obj/machinery/door/window/left/directional/south, -/obj/machinery/button/flasher{ - id = "executionflash"; - pixel_x = -24; - pixel_y = 5; - dir = 8 - }, -/turf/open/floor/plating/icemoon, -/area/station/security/execution/education) "sbc" = ( /obj/structure/table/reinforced, /obj/machinery/door/firedoor, @@ -64756,10 +64460,6 @@ /obj/structure/grille, /turf/open/floor/plating, /area/station/maintenance/port/fore) -"sbJ" = ( -/obj/structure/window/reinforced/spawner/directional/north, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) "sbK" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 8 @@ -64784,22 +64484,6 @@ /obj/structure/secure_safe/directional/east, /turf/open/floor/iron, /area/station/commons/vacant_room/commissary) -"sca" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "gene_shutters"; - name = "Genetics Shutters" - }, -/turf/open/floor/plating, -/area/station/science/genetics) -"scb" = ( -/obj/structure/toilet/greyscale{ - cistern_open = 1; - dir = 1 - }, -/obj/machinery/light/small/directional/south, -/turf/open/floor/iron/showroomfloor, -/area/station/security/prison/toilet) "scj" = ( /obj/structure/cable, /obj/effect/turf_decal/siding/thinplating/dark{ @@ -64841,13 +64525,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/service/janitor) -"scu" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 8 - }, -/obj/effect/turf_decal/tile/red/half/contrasted, -/turf/open/floor/iron, -/area/station/security/brig/upper) "scw" = ( /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/underground/explored) @@ -64919,11 +64596,6 @@ }, /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/surface/outdoors/less_spawns) -"sdE" = ( -/obj/structure/chair/pew/left, -/obj/machinery/light/small/directional/west, -/turf/open/floor/wood, -/area/station/security/prison/rec) "sdF" = ( /obj/structure/table, /obj/item/grown/log/tree, @@ -64966,10 +64638,21 @@ /obj/effect/turf_decal/tile/neutral/half/contrasted, /turf/open/floor/iron/dark, /area/station/command/eva) +"sea" = ( +/turf/open/floor/iron, +/area/mine/production) "sen" = ( /obj/structure/cable, /turf/open/floor/iron, /area/station/security/courtroom) +"ses" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/turf_decal/bot/right, +/turf/open/floor/iron/smooth_edge{ + dir = 1 + }, +/area/station/security/lockers) "seA" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable, @@ -65042,6 +64725,12 @@ /obj/effect/turf_decal/bot, /turf/open/floor/iron/large, /area/station/hallway/secondary/entry) +"sfs" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, +/turf/open/floor/iron/smooth, +/area/station/security/holding_cell) "sfv" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/general/visible, @@ -65071,6 +64760,12 @@ /obj/structure/sign/warning/electric_shock/directional/east, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) +"sfM" = ( +/obj/structure/fence/door/opened{ + dir = 4 + }, +/turf/open/misc/asteroid/snow/icemoon, +/area/icemoon/surface/outdoors/nospawn) "sfY" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -65147,13 +64842,6 @@ "shc" = ( /turf/open/floor/iron, /area/station/command/heads_quarters/hop) -"she" = ( -/obj/machinery/light/directional/east, -/obj/effect/turf_decal/tile/red/half/contrasted{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/security/brig/upper) "shh" = ( /turf/open/floor/wood, /area/station/hallway/secondary/service) @@ -65252,6 +64940,13 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark, /area/mine/eva) +"siT" = ( +/obj/machinery/vending/sustenance, +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/security/prison/mess) "sjb" = ( /turf/closed/wall/r_wall, /area/station/cargo/drone_bay) @@ -65303,6 +64998,14 @@ }, /turf/open/floor/iron/checker, /area/station/maintenance/port/fore) +"sjx" = ( +/obj/effect/decal/cleanable/wrapping, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/machinery/light/small/dim/directional/north, +/turf/open/floor/vault, +/area/station/security/prison/rec) "sjz" = ( /obj/structure/chair/sofa/bench/left, /obj/effect/turf_decal/stripes/line{ @@ -65817,6 +65520,12 @@ /obj/structure/chair/wood, /turf/open/floor/wood/parquet, /area/station/service/bar/atrium) +"spD" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/iron/dark, +/area/station/security/mechbay) "spV" = ( /obj/effect/spawner/random/trash/bin, /obj/item/paper/crumpled{ @@ -65914,6 +65623,12 @@ /obj/machinery/firealarm/directional/south, /turf/open/floor/iron/dark, /area/station/commons/lounge) +"sri" = ( +/obj/effect/turf_decal/bot, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/power/floodlight, +/turf/open/floor/iron, +/area/mine/laborcamp) "srk" = ( /obj/machinery/door/window/right/directional/west{ name = "Library Desk Door"; @@ -65925,6 +65640,12 @@ /obj/structure/cable, /turf/closed/wall/r_wall, /area/station/maintenance/port/aft) +"sru" = ( +/obj/effect/spawner/random/entertainment/drugs, +/obj/structure/rack, +/obj/effect/spawner/random/contraband/cannabis, +/turf/open/floor/plating, +/area/station/security/prison) "srw" = ( /obj/machinery/door/firedoor, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -66067,15 +65788,6 @@ /obj/item/radio/intercom/directional/west, /turf/open/floor/plating, /area/station/ai/satellite/service) -"stt" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 4 - }, -/turf/open/floor/iron/smooth_edge{ - dir = 1 - }, -/area/station/security/lockers) "stA" = ( /obj/structure/lattice/catwalk, /obj/structure/railing{ @@ -66143,6 +65855,10 @@ }, /turf/open/floor/iron, /area/station/commons/locker) +"suk" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron/cafeteria, +/area/station/security/prison/mess) "sul" = ( /obj/structure/window/reinforced/spawner/directional/east, /obj/structure/window/reinforced/spawner/directional/north, @@ -66163,6 +65879,15 @@ /obj/item/toy/figure/bartender, /turf/open/floor/iron/grimy, /area/station/service/bar/backroom) +"sup" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/preopen{ + id = "labor"; + name = "Labor Camp Blast Door" + }, +/obj/structure/cable, +/turf/open/floor/plating, +/area/mine/laborcamp/security) "suA" = ( /obj/structure/closet/crate/coffin, /obj/effect/decal/cleanable/dirt, @@ -66248,34 +65973,6 @@ /obj/machinery/light/directional/east, /turf/open/floor/engine, /area/station/science/explab) -"swc" = ( -/obj/machinery/light/directional/south, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/red/line, -/obj/effect/turf_decal/trimline/red/line{ - dir = 1 - }, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) -"swf" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/plating, -/area/station/security/prison/safe) -"swk" = ( -/obj/structure/chair/wood{ - dir = 4 - }, -/obj/effect/turf_decal/siding/wood{ - dir = 9 - }, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/wood, -/area/station/security/prison/rec) "sws" = ( /obj/machinery/door/airlock/security{ name = "Permabrig Library" @@ -66484,6 +66181,10 @@ /obj/machinery/firealarm/directional/east, /turf/open/floor/iron/white/textured, /area/station/security/medical) +"syR" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/station/security/prison/mess) "syT" = ( /obj/machinery/light/small/dim/directional/south, /turf/open/floor/plating, @@ -66501,11 +66202,6 @@ /obj/effect/mapping_helpers/airlock/access/all/engineering/general, /turf/open/floor/engine, /area/station/engineering/supermatter/room) -"szu" = ( -/obj/structure/sign/poster/official/obey/directional/north, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/mine/laborcamp) "szD" = ( /obj/effect/turf_decal/trimline/green/filled/end, /obj/effect/decal/cleanable/dirt, @@ -66647,13 +66343,12 @@ }, /turf/open/floor/iron/white/corner, /area/station/hallway/secondary/exit/departure_lounge) -"sCa" = ( -/obj/effect/turf_decal/siding/wideplating/dark{ - dir = 5 +"sBX" = ( +/obj/effect/turf_decal/tile/red{ + dir = 8 }, -/obj/machinery/digital_clock/directional/north, -/turf/open/floor/iron/dark/textured, -/area/station/security/prison/rec) +/turf/open/floor/iron, +/area/station/security/brig) "sCb" = ( /obj/structure/minecart_rail{ dir = 6 @@ -66761,6 +66456,10 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/science/cytology) +"sDH" = ( +/obj/structure/sign/nanotrasen/directional/west, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/underground/explored) "sDJ" = ( /obj/machinery/computer/station_alert, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -66830,6 +66529,21 @@ }, /turf/open/floor/plating, /area/mine/living_quarters) +"sEt" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/medical/glass{ + id_tag = "MedbayFoyer"; + name = "Medbay" + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/mapping_helpers/airlock/access/all/medical/general, +/obj/effect/turf_decal/tile/blue/full, +/obj/effect/mapping_helpers/airlock/unres/delayed, +/turf/open/floor/iron/large, +/area/station/medical/medbay/lobby) "sEz" = ( /obj/structure/disposalpipe/segment{ dir = 5 @@ -66842,14 +66556,6 @@ "sEB" = ( /turf/open/floor/plating/snowed/icemoon, /area/icemoon/surface/outdoors/nospawn) -"sEC" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 1 - }, -/obj/machinery/airalarm/directional/west, -/obj/effect/turf_decal/tile/red/opposingcorners, -/turf/open/floor/iron, -/area/station/security/prison/mess) "sED" = ( /obj/structure/disposalpipe/segment{ dir = 10 @@ -66895,6 +66601,10 @@ }, /turf/open/floor/iron/white/corner, /area/station/engineering/atmos) +"sEY" = ( +/obj/structure/sink/kitchen/directional/west, +/turf/open/floor/iron/cafeteria, +/area/station/security/prison/mess) "sFd" = ( /obj/machinery/light/small/directional/north, /obj/effect/turf_decal/siding/blue{ @@ -66955,6 +66665,9 @@ dir = 1 }, /area/station/command/eva) +"sFV" = ( +/turf/open/floor/iron/smooth, +/area/station/security/holding_cell) "sFY" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/landmark/mining_center, @@ -66982,6 +66695,13 @@ /obj/machinery/status_display/evac/directional/west, /turf/open/floor/iron/dark, /area/station/service/hydroponics/garden) +"sGu" = ( +/obj/effect/turf_decal/tile/red, +/obj/structure/chair/sofa/bench{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/security/prison/mess) "sGw" = ( /obj/structure/sign/warning/secure_area/directional/north, /turf/open/genturf/blue, @@ -67173,28 +66893,12 @@ /obj/machinery/light/warm/directional/north, /turf/open/floor/iron/cafeteria, /area/station/security/prison/mess) -"sJi" = ( -/obj/machinery/vending/donksofttoyvendor, -/turf/open/floor/iron/dark/textured, -/area/station/security/prison/safe) "sJr" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 8 }, /turf/open/floor/iron/large, /area/station/commons/storage/tools) -"sJt" = ( -/obj/machinery/door/poddoor{ - id = "executionfireblast" - }, -/obj/structure/railing{ - dir = 8 - }, -/obj/structure/railing{ - dir = 4 - }, -/turf/open/floor/plating/icemoon, -/area/station/security/execution/education) "sJA" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -67226,14 +66930,6 @@ }, /turf/open/floor/iron/grimy, /area/station/commons/vacant_room/office) -"sJR" = ( -/obj/machinery/door/airlock/security/glass{ - name = "Labor Camp Airlock" - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, -/obj/effect/mapping_helpers/airlock/access/all/security/brig, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "sKf" = ( /turf/open/floor/plating, /area/station/maintenance/aft/greater) @@ -67248,6 +66944,13 @@ }, /turf/open/floor/plating, /area/mine/eva/lower) +"sKs" = ( +/obj/structure/extinguisher_cabinet/directional/west, +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/security/brig/upper) "sKu" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 8 @@ -67287,21 +66990,12 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/engineering/atmos/storage) -"sLa" = ( +"sLe" = ( /obj/structure/table, -/obj/item/restraints/handcuffs, -/obj/machinery/airalarm/directional/north, -/obj/effect/turf_decal/tile/red/half/contrasted{ - dir = 8 - }, -/turf/open/floor/iron, -/area/mine/laborcamp/security) -"sLj" = ( -/obj/effect/turf_decal/tile/red/anticorner/contrasted{ - dir = 1 - }, -/turf/open/floor/iron/dark/corner, -/area/station/security/processing) +/obj/item/folder/red, +/obj/item/flashlight/lamp, +/turf/open/floor/iron/dark, +/area/station/security/interrogation) "sLl" = ( /obj/structure/railing, /obj/structure/railing{ @@ -67355,6 +67049,17 @@ /obj/structure/cable, /turf/open/floor/iron/grimy, /area/station/ai/satellite/interior) +"sMx" = ( +/obj/structure/chair{ + dir = 8 + }, +/obj/item/radio/intercom/directional/east, +/obj/effect/landmark/start/hangover, +/obj/effect/turf_decal/tile/blue/half/contrasted{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/hallway/primary/starboard) "sMy" = ( /obj/structure/flora/tree/pine/style_random, /obj/structure/flora/grass/both/style_random, @@ -67365,16 +67070,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/circuit, /area/station/ai/satellite/hallway) -"sMY" = ( -/obj/structure/table, -/obj/item/radio/off, -/obj/item/screwdriver{ - pixel_y = 10 - }, -/turf/open/floor/iron/dark/textured_half{ - dir = 1 - }, -/area/station/security/office) "sNj" = ( /obj/machinery/light_switch/directional/east, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -67495,11 +67190,17 @@ /obj/structure/cable, /turf/open/floor/iron/white, /area/station/medical/storage) -"sOT" = ( -/obj/structure/table, -/obj/item/kitchen/fork/plastic, -/turf/open/floor/iron, -/area/station/security/prison/mess) +"sOS" = ( +/obj/effect/spawner/random/contraband/prison, +/obj/machinery/power/apc/auto_name/directional/east, +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/maintenance/department/security) +"sOW" = ( +/obj/machinery/light_switch/directional/south, +/obj/structure/sign/nanotrasen/directional/east, +/turf/open/floor/wood, +/area/station/security/courtroom) "sOY" = ( /obj/structure/table/glass, /obj/item/hemostat, @@ -67525,29 +67226,6 @@ }, /turf/open/floor/plating, /area/station/cargo/office) -"sPA" = ( -/obj/structure/rack, -/obj/item/storage/bag/ore, -/obj/item/pickaxe, -/obj/item/flashlight, -/obj/item/clothing/glasses/meson, -/obj/item/mining_scanner, -/obj/effect/decal/cleanable/dirt, -/obj/item/clothing/suit/hooded/wintercoat, -/turf/open/floor/iron, -/area/mine/laborcamp) -"sPE" = ( -/obj/machinery/conveyor{ - id = "mining_internal" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/iron, -/area/mine/production) "sPG" = ( /obj/effect/landmark/generic_maintenance_landmark, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -67629,6 +67307,12 @@ /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) +"sRh" = ( +/obj/machinery/mineral/processing_unit_console{ + pixel_y = 28 + }, +/turf/open/floor/iron, +/area/mine/laborcamp) "sRu" = ( /obj/effect/turf_decal/siding/thinplating/dark{ dir = 10 @@ -67666,6 +67350,10 @@ dir = 8 }, /area/station/service/kitchen/coldroom) +"sRC" = ( +/obj/structure/flora/rock/pile/icy/style_random, +/turf/open/misc/asteroid/snow/icemoon, +/area/icemoon/surface/outdoors/labor_camp) "sRI" = ( /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/plating, @@ -67726,15 +67414,6 @@ /obj/structure/sign/warning/cold_temp/directional/north, /turf/open/floor/iron/smooth, /area/station/engineering/lobby) -"sSO" = ( -/obj/machinery/light/small/directional/south, -/obj/structure/closet/secure_closet/brig{ - id = "Cell 3"; - name = "Cell 3 locker" - }, -/obj/structure/cable, -/turf/open/floor/iron/smooth, -/area/station/security/brig) "sSR" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 8 @@ -67853,13 +67532,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/stone, /area/station/commons/lounge) -"sTO" = ( -/obj/machinery/door/airlock{ - name = "Unisex Restroom" - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron, -/area/mine/laborcamp) "sTP" = ( /obj/structure/window/reinforced/spawner/directional/east, /obj/structure/table, @@ -67873,15 +67545,6 @@ }, /turf/open/floor/plating, /area/station/commons/storage/mining) -"sUb" = ( -/obj/machinery/door/airlock/security/glass{ - name = "Permabrig Visitation" - }, -/obj/machinery/door/firedoor, -/obj/structure/cable, -/obj/effect/mapping_helpers/airlock/access/any/security/brig, -/turf/open/floor/iron, -/area/station/security/prison/visit) "sUB" = ( /obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -68002,14 +67665,6 @@ /obj/effect/turf_decal/tile/blue/full, /turf/open/floor/iron/dark/smooth_large, /area/station/command/heads_quarters/cmo) -"sWo" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/tile/blue/opposingcorners{ - dir = 1 - }, -/turf/open/floor/iron/white, -/area/mine/laborcamp) "sWs" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable, @@ -68034,6 +67689,12 @@ /obj/structure/sign/nanotrasen/directional/north, /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/underground/explored) +"sWJ" = ( +/obj/machinery/suit_storage_unit/security, +/obj/effect/turf_decal/tile/red/half/contrasted, +/obj/effect/turf_decal/bot/right, +/turf/open/floor/iron/smooth, +/area/station/security/eva) "sWN" = ( /obj/structure/chair{ dir = 1; @@ -68095,6 +67756,18 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/smooth, /area/station/maintenance/fore/lesser) +"sXy" = ( +/obj/item/reagent_containers/condiment/saltshaker{ + pixel_x = -3 + }, +/obj/item/reagent_containers/condiment/peppermill{ + pixel_x = 3 + }, +/obj/structure/window/reinforced/spawner/directional/west, +/obj/structure/table/reinforced, +/obj/item/radio/intercom/prison/directional/north, +/turf/open/floor/iron/cafeteria, +/area/station/security/prison/mess) "sXK" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -68155,15 +67828,6 @@ }, /turf/open/lava/plasma/ice_moon, /area/icemoon/underground/explored) -"sYG" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 8 - }, -/obj/effect/turf_decal/tile/red/half/contrasted{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/security/brig/upper) "sYU" = ( /obj/structure/grille/broken, /obj/effect/spawner/random/trash/moisture_trap, @@ -68175,6 +67839,14 @@ }, /turf/open/floor/engine, /area/station/engineering/atmos/hfr_room) +"sZc" = ( +/obj/effect/turf_decal/loading_area, +/turf/open/floor/iron, +/area/mine/laborcamp) +"sZy" = ( +/obj/structure/curtain/bounty, +/turf/open/floor/iron/dark/textured, +/area/station/security/interrogation) "sZB" = ( /obj/structure/noticeboard/directional/north, /turf/open/openspace, @@ -68191,6 +67863,15 @@ "sZF" = ( /turf/closed/wall, /area/station/maintenance/aft/greater) +"sZM" = ( +/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/security/brig/upper) "sZO" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -68228,14 +67909,6 @@ /obj/effect/mapping_helpers/airlock/access/all/medical/chemistry, /turf/open/floor/plating, /area/station/maintenance/department/medical/morgue) -"taj" = ( -/obj/structure/cable, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/machinery/light/small/directional/west, -/turf/open/floor/iron/dark, -/area/station/security/mechbay) "tak" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -68269,10 +67942,10 @@ /obj/effect/turf_decal/tile/yellow/opposingcorners, /turf/open/floor/iron/dark, /area/station/engineering/atmos/project) -"taV" = ( -/obj/structure/cable/multilayer/multiz, -/turf/open/floor/plating, -/area/station/security/prison/safe) +"taP" = ( +/obj/item/toy/basketball, +/turf/open/floor/iron, +/area/station/security/prison/workout) "taX" = ( /obj/machinery/power/port_gen/pacman/pre_loaded, /turf/open/floor/plating, @@ -68321,6 +67994,13 @@ dir = 4 }, /area/station/commons/storage/mining) +"tbv" = ( +/obj/structure/rack, +/obj/item/stack/ducts{ + amount = 5 + }, +/turf/open/floor/iron, +/area/mine/production) "tbH" = ( /obj/structure/table/reinforced, /obj/structure/disposalpipe/segment{ @@ -68398,16 +68078,10 @@ /obj/structure/sign/warning/electric_shock/directional/north, /turf/open/floor/iron/grimy, /area/station/security/prison/work) -"tcQ" = ( -/obj/machinery/camera/directional/west{ - c_tag = "Security - Permabrig Recreation"; - network = list("ss13","prison") - }, -/obj/effect/turf_decal/siding/wideplating/dark{ - dir = 8 - }, -/turf/open/floor/iron/dark/textured, -/area/station/security/prison/rec) +"tcO" = ( +/obj/machinery/light/small/directional/south, +/turf/open/floor/iron, +/area/mine/production) "tcR" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/landmark/generic_maintenance_landmark, @@ -68486,6 +68160,12 @@ }, /turf/open/floor/iron/dark, /area/station/commons/storage/primary) +"tea" = ( +/obj/effect/turf_decal/trimline/red/filled/line, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/landmark/event_spawn, +/turf/open/floor/iron/dark/side, +/area/mine/laborcamp/security) "tec" = ( /obj/structure/cable, /obj/structure/railing{ @@ -68547,6 +68227,15 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/maintenance/port/greater) +"teO" = ( +/obj/structure/table, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/microwave{ + pixel_y = 6 + }, +/obj/structure/cable, +/turf/open/floor/iron, +/area/mine/laborcamp) "teP" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -68573,6 +68262,12 @@ /obj/effect/turf_decal/tile/blue/half/contrasted, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) +"tfi" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/item/radio/intercom/directional/west, +/obj/structure/closet/emcloset/anchored, +/turf/open/floor/iron/smooth, +/area/station/security/eva) "tfk" = ( /obj/machinery/light/small/directional/north, /obj/structure/sign/warning/secure_area/directional/north, @@ -68587,13 +68282,6 @@ /obj/structure/window/reinforced/spawner/directional/west, /turf/open/floor/iron, /area/station/science/xenobiology) -"tfC" = ( -/obj/machinery/holopad, -/obj/effect/turf_decal/bot, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/turf/open/floor/iron/dark, -/area/station/engineering/circuit_workshop) "tfM" = ( /obj/structure/chair/office/light{ dir = 1 @@ -68681,21 +68369,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron/white/smooth_large, /area/station/science/genetics) -"tgF" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/medical/glass{ - id_tag = "MedbayFoyer"; - name = "Medbay" - }, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/mapping_helpers/airlock/access/all/medical/general, -/obj/effect/turf_decal/tile/blue/full, -/obj/effect/mapping_helpers/airlock/unres/delayed, -/turf/open/floor/iron/large, -/area/station/medical/medbay/lobby) "tgH" = ( /obj/machinery/light/small/directional/south, /obj/effect/turf_decal/tile/yellow/half/contrasted, @@ -68804,6 +68477,15 @@ dir = 10 }, /area/station/science/lab) +"tif" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 8 + }, +/turf/open/floor/iron, +/area/mine/production) "tii" = ( /obj/effect/turf_decal/siding/wood{ dir = 8 @@ -68919,6 +68601,18 @@ }, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) +"tjA" = ( +/obj/effect/spawner/random/contraband/narcotics{ + pixel_x = -5; + pixel_y = -4 + }, +/obj/item/cigarette/rollie/cannabis{ + pixel_y = -3; + pixel_x = 6 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/plating, +/area/station/security/prison) "tjC" = ( /obj/machinery/airalarm/directional/south, /obj/effect/turf_decal/tile/red/half/contrasted, @@ -69110,15 +68804,6 @@ }, /turf/open/floor/iron, /area/station/science/robotics/mechbay) -"tlS" = ( -/obj/machinery/door/airlock/security{ - name = "Permanent Cell 3" - }, -/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/dark/textured, -/area/station/security/prison/safe) "tma" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/machinery/door/firedoor, @@ -69137,6 +68822,10 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/hallway/primary/central) +"tmt" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/smooth, +/area/station/engineering/lobby) "tmw" = ( /obj/structure/closet/firecloset, /turf/open/floor/iron, @@ -69161,9 +68850,6 @@ }, /turf/open/floor/iron/dark/corner, /area/station/engineering/atmos/storage/gas) -"tmB" = ( -/turf/open/floor/iron, -/area/mine/laborcamp/security) "tmE" = ( /obj/structure/chair/comfy/beige{ dir = 1; @@ -69232,20 +68918,14 @@ /obj/effect/turf_decal/tile/blue, /turf/open/floor/iron, /area/station/hallway/primary/fore) -"tnD" = ( -/obj/effect/turf_decal/trimline/red/filled/line{ - dir = 9 - }, -/obj/structure/bed{ +"tnF" = ( +/obj/effect/turf_decal/tile/red/half/contrasted{ dir = 1 }, -/obj/effect/spawner/random/bedsheet{ - dir = 1 - }, -/obj/effect/spawner/random/contraband/permabrig_gear, -/obj/structure/sign/warning/electric_shock/directional/north, -/turf/open/floor/iron/white, -/area/station/security/prison/safe) +/obj/structure/sign/poster/official/random/directional/north, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/turf/open/floor/iron/dark/textured_edge, +/area/station/security/prison) "tnI" = ( /obj/effect/turf_decal/trimline/dark_blue/line{ dir = 10 @@ -69273,6 +68953,14 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/wood, /area/station/maintenance/fore) +"tnR" = ( +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 4 + }, +/obj/machinery/airalarm/directional/north, +/obj/structure/closet/emcloset, +/turf/open/floor/iron/smooth, +/area/station/security/brig/upper) "toi" = ( /obj/machinery/computer/security/telescreen/entertainment/directional/east, /obj/machinery/status_display/evac/directional/south, @@ -69295,6 +68983,10 @@ /obj/effect/turf_decal/siding/yellow, /turf/open/floor/iron, /area/station/engineering/storage) +"tor" = ( +/obj/structure/chair/stool/directional/west, +/turf/open/floor/iron, +/area/mine/laborcamp) "toG" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 6 @@ -69306,6 +68998,15 @@ /obj/machinery/shower/directional/west, /turf/open/floor/iron/white, /area/station/medical/virology) +"toN" = ( +/obj/effect/turf_decal/trimline/red/warning{ + dir = 10 + }, +/obj/effect/turf_decal/stripes/red/line{ + dir = 8 + }, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/surface/outdoors/nospawn) "toT" = ( /obj/effect/turf_decal/siding/wood, /obj/structure/railing/corner{ @@ -69360,9 +69061,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark/textured, /area/station/commons/locker) -"tpH" = ( -/turf/closed/wall, -/area/station/security/execution/education) "tpN" = ( /obj/effect/turf_decal/siding/wood{ dir = 8 @@ -69383,18 +69081,6 @@ }, /turf/open/floor/stone, /area/station/service/bar/atrium) -"tpX" = ( -/obj/item/storage/box/bodybags, -/obj/structure/extinguisher_cabinet/directional/west, -/obj/item/reagent_containers/syringe{ - name = "steel point" - }, -/obj/item/reagent_containers/cup/bottle/multiver, -/obj/item/reagent_containers/cup/bottle/epinephrine, -/obj/structure/table/glass, -/obj/structure/window/reinforced/spawner/directional/south, -/turf/open/floor/iron/white/textured, -/area/station/security/medical) "tqs" = ( /obj/machinery/airalarm/directional/west, /turf/open/floor/iron/dark, @@ -69550,22 +69236,19 @@ /obj/effect/landmark/start/chemist, /turf/open/floor/iron/white, /area/station/medical/chemistry) -"ttk" = ( -/obj/machinery/door/airlock/freezer, -/turf/open/floor/iron/showroomfloor, -/area/station/security/prison/mess) "ttw" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/iron/white/smooth_large, /area/station/science/lab) -"ttD" = ( -/obj/effect/turf_decal/siding/wood{ +"ttE" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/small/directional/west, +/obj/machinery/airalarm/directional/west, +/obj/structure/chair/sofa/bench{ dir = 4 }, -/obj/structure/sign/painting/large, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/wood, -/area/station/security/prison/rec) +/turf/open/floor/iron/smooth, +/area/station/security/holding_cell) "ttI" = ( /obj/machinery/door/airlock{ id_tag = "Dorm5"; @@ -69642,12 +69325,6 @@ }, /turf/open/floor/iron/dark/textured, /area/station/hallway/secondary/entry) -"tuH" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/landmark/start/prisoner, -/turf/open/floor/iron, -/area/station/security/prison/mess) "tuQ" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -69787,6 +69464,11 @@ /obj/machinery/holopad, /turf/open/floor/carpet/red, /area/station/security/prison/work) +"twz" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/turf/open/floor/iron/dark/textured, +/area/station/security/interrogation) "twF" = ( /obj/effect/decal/cleanable/dirt/dust, /obj/structure/closet/firecloset, @@ -69805,13 +69487,6 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron/freezer, /area/station/commons/toilet) -"twV" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/green/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron/dark, -/area/mine/laborcamp) "twZ" = ( /obj/structure/table, /obj/effect/spawner/random/maintenance, @@ -69914,6 +69589,14 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/dark/visible, /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) +"tyI" = ( +/obj/structure/railing{ + dir = 4 + }, +/turf/open/floor/iron/stairs/medium{ + dir = 1 + }, +/area/mine/laborcamp/security) "tyK" = ( /obj/item/mop, /obj/item/reagent_containers/cup/bucket, @@ -69990,6 +69673,12 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/medical/virology) +"tAl" = ( +/obj/structure/cable, +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/red/half, +/turf/open/floor/iron/smooth_half, +/area/station/security/brig/upper) "tAx" = ( /obj/effect/turf_decal/trimline/blue/filled/warning, /obj/structure/disposalpipe/segment, @@ -70002,14 +69691,6 @@ dir = 4 }, /area/station/service/chapel) -"tAL" = ( -/obj/structure/table, -/obj/machinery/light/small/directional/south, -/obj/effect/turf_decal/tile/blue/opposingcorners{ - dir = 1 - }, -/turf/open/floor/iron/white, -/area/mine/laborcamp) "tAN" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/plating, @@ -70035,6 +69716,10 @@ dir = 8 }, /area/station/service/kitchen/coldroom) +"tBn" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, +/turf/open/floor/iron/dark/side, +/area/station/security/range) "tBq" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -70074,6 +69759,16 @@ }, /turf/open/floor/iron, /area/station/security/checkpoint/supply) +"tBW" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Equipment Room" + }, +/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/access/all/security/brig, +/turf/open/floor/iron/dark/textured, +/area/station/security/lockers) "tCe" = ( /obj/effect/turf_decal/bot{ dir = 1 @@ -70218,6 +69913,10 @@ }, /turf/open/floor/iron/dark/textured, /area/station/security/armory/upper) +"tDM" = ( +/obj/item/kirbyplants/organic/plant10, +/turf/open/floor/wood/large, +/area/station/security/prison/rec) "tDN" = ( /obj/structure/chair{ name = "Defense" @@ -70229,17 +69928,17 @@ /obj/effect/spawner/random/trash/bin, /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) +"tDT" = ( +/obj/effect/mapping_helpers/broken_floor, +/obj/machinery/light/small/directional/east, +/turf/open/floor/wood, +/area/station/maintenance/fore) "tDU" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/table, /obj/machinery/newscaster/directional/east, /turf/open/floor/iron, /area/station/cargo/storage) -"tDY" = ( -/obj/machinery/vending/cola/sodie, -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/security/prison/visit) "tEe" = ( /obj/effect/spawner/random/structure/closet_maintenance, /turf/open/floor/plating, @@ -70380,6 +70079,16 @@ /obj/effect/turf_decal/tile/green/full, /turf/open/floor/iron/white/smooth_large, /area/station/medical/virology) +"tGd" = ( +/obj/effect/turf_decal/tile/blue/opposingcorners{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 8 + }, +/obj/machinery/light/small/dim/directional/north, +/turf/open/floor/iron/white, +/area/mine/laborcamp) "tGi" = ( /obj/effect/turf_decal/stripes/end, /obj/machinery/door/airlock/external, @@ -70454,22 +70163,6 @@ }, /turf/open/floor/iron, /area/station/command/bridge) -"tGJ" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red/half/contrasted, -/turf/open/floor/iron/dark/textured_edge{ - dir = 1 - }, -/area/station/security/prison) -"tGP" = ( -/obj/machinery/conveyor{ - id = "gulag" - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/mine/laborcamp) "tHb" = ( /obj/effect/spawner/random/structure/musician/piano/random_piano, /obj/machinery/button/curtain{ @@ -70544,11 +70237,6 @@ /obj/structure/cable, /turf/open/floor/iron/dark, /area/station/maintenance/disposal) -"tIf" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/showroomfloor, -/area/station/security/processing) "tIh" = ( /obj/structure/light_construct/directional/south, /obj/structure/sign/poster/official/random/directional/south, @@ -70604,15 +70292,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/mine/eva/lower) -"tIS" = ( -/obj/effect/turf_decal/trimline/red/filled/line{ - dir = 6 - }, -/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/white, -/area/station/security/prison/safe) "tIW" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable, @@ -70742,10 +70421,6 @@ /obj/structure/closet/wardrobe/mixed, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) -"tKB" = ( -/obj/structure/chair/pew/left, -/turf/open/floor/wood, -/area/station/security/prison/rec) "tKD" = ( /obj/machinery/door/firedoor/heavy, /obj/machinery/door/poddoor/preopen{ @@ -71053,6 +70728,16 @@ /obj/machinery/computer/security/telescreen/entertainment/directional/south, /turf/open/floor/iron, /area/station/engineering/storage_shared) +"tOp" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/trimline/red/warning{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/red/line{ + dir = 8 + }, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/surface/outdoors/nospawn) "tOq" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable, @@ -71069,11 +70754,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/engineering/atmos/mix) -"tOE" = ( -/obj/structure/cable/multilayer/multiz, -/obj/structure/sign/warning/electric_shock/directional/north, -/turf/open/floor/plating, -/area/station/security/prison/safe) "tOF" = ( /obj/structure/chair/comfy/black{ dir = 8 @@ -71291,10 +70971,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/hallway/primary/central) -"tSi" = ( -/obj/machinery/suit_storage_unit/security, -/turf/open/floor/iron/smooth, -/area/station/security/brig/upper) "tSj" = ( /obj/structure/fence/corner{ dir = 1 @@ -71550,10 +71226,6 @@ }, /turf/open/floor/carpet/lone, /area/station/service/chapel) -"tWK" = ( -/obj/structure/cable, -/turf/open/floor/plating/snowed/icemoon, -/area/icemoon/underground/explored) "tWO" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -71612,19 +71284,6 @@ /obj/structure/light_construct/directional/west, /turf/open/floor/plating, /area/station/maintenance/port/aft) -"tXM" = ( -/obj/machinery/hydroponics/constructable, -/obj/structure/window/reinforced/spawner/directional/west, -/obj/effect/decal/cleanable/dirt, -/obj/item/plant_analyzer, -/obj/effect/turf_decal/tile/green/anticorner/contrasted{ - dir = 8 - }, -/obj/effect/turf_decal/siding/green{ - dir = 8 - }, -/turf/open/floor/iron/dark, -/area/mine/laborcamp) "tXV" = ( /obj/machinery/airalarm/directional/north, /obj/machinery/camera/directional/north{ @@ -71704,6 +71363,15 @@ /obj/effect/spawner/random/structure/shipping_container, /turf/open/floor/plating, /area/station/maintenance/port/aft) +"tZc" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/obj/structure/railing/corner, +/obj/effect/turf_decal/stripes/corner, +/turf/open/floor/iron, +/area/mine/production) "tZd" = ( /obj/machinery/hydroponics/soil{ pixel_y = 8 @@ -71737,10 +71405,6 @@ /obj/machinery/firealarm/directional/west, /turf/open/floor/iron/dark, /area/station/science/ordnance/office) -"tZF" = ( -/obj/effect/spawner/random/entertainment/slot_machine, -/turf/open/floor/wood, -/area/station/command/meeting_room) "tZG" = ( /turf/open/floor/iron/white/corner{ dir = 1 @@ -71856,15 +71520,6 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/iron/white, /area/station/medical/storage) -"ubE" = ( -/obj/machinery/atmospherics/pipe/multiz/scrubbers/visible/layer2{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/multiz/supply/visible/layer4{ - dir = 1 - }, -/turf/open/floor/plating, -/area/station/maintenance/fore) "ubF" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/purple/visible, /turf/open/floor/iron, @@ -71917,6 +71572,20 @@ /obj/structure/sign/warning/electric_shock, /turf/closed/wall/r_wall, /area/station/engineering/supermatter) +"udj" = ( +/obj/machinery/camera/directional/north{ + c_tag = "Armory - Internal - Lower" + }, +/obj/structure/rack, +/obj/item/storage/toolbox/drone{ + pixel_y = 3; + pixel_x = 1 + }, +/obj/effect/turf_decal/tile/red/half/contrasted, +/obj/machinery/light/small/directional/north, +/obj/item/storage/toolbox/emergency, +/turf/open/floor/iron/dark/textured, +/area/station/security/armory) "udo" = ( /obj/structure/closet{ name = "evidence closet 4" @@ -71993,13 +71662,6 @@ /obj/structure/flora/tree/pine/style_random, /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/surface/outdoors/nospawn) -"uet" = ( -/obj/machinery/keycard_auth/wall_mounted/directional/east, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 1 - }, -/turf/open/floor/iron/dark/smooth_large, -/area/station/command/heads_quarters/hos) "uey" = ( /obj/machinery/power/supermatter_crystal/engine, /turf/open/floor/engine, @@ -72056,12 +71718,6 @@ /obj/machinery/firealarm/directional/north, /turf/open/floor/iron, /area/station/hallway/primary/starboard) -"ufm" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/turf/open/floor/iron/showroomfloor, -/area/station/security/processing) "ufF" = ( /obj/structure/table, /obj/item/storage/box/prisoner{ @@ -72070,19 +71726,20 @@ /obj/item/storage/box/prisoner, /turf/open/floor/iron/smooth, /area/station/security/execution/transfer) +"ufK" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/light/floor, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/security/brig/upper) "ufN" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible, /turf/open/floor/iron/white, /area/station/medical/cryo) -"ugd" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/camera/directional/south{ - c_tag = "Security - Permabrig Meditation"; - network = list("ss13","prison") - }, -/turf/open/floor/sepia, -/area/station/security/prison/rec) "ugi" = ( /obj/machinery/light/small/directional/east, /obj/machinery/computer/order_console/bitrunning{ @@ -72237,6 +71894,17 @@ /obj/effect/mapping_helpers/airlock/access/any/medical/maintenance, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) +"uhN" = ( +/turf/closed/wall, +/area/station/security/eva) +"uhU" = ( +/obj/effect/turf_decal/tile/red/half/contrasted, +/obj/machinery/power/apc/auto_name/directional/south, +/obj/structure/cable, +/turf/open/floor/iron/dark/textured_edge{ + dir = 1 + }, +/area/station/security/prison) "uif" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -72456,12 +72124,6 @@ "ult" = ( /turf/closed/wall/r_wall, /area/station/science/robotics/lab) -"ulz" = ( -/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/security/prison/safe) "ulL" = ( /obj/machinery/modular_computer/preset/id, /obj/effect/turf_decal/tile/blue/full, @@ -72479,24 +72141,16 @@ }, /turf/open/floor/iron/dark/smooth_large, /area/station/command/heads_quarters/cmo) +"ulQ" = ( +/obj/structure/sign/warning/docking/directional/south, +/turf/open/misc/asteroid/snow/icemoon, +/area/icemoon/surface/outdoors/nospawn) "ulR" = ( /obj/effect/turf_decal/siding/wood/corner{ dir = 8 }, /turf/open/floor/stone, /area/station/service/bar/atrium) -"uma" = ( -/obj/item/storage/toolbox/artistic{ - pixel_x = -1; - pixel_y = 2 - }, -/obj/structure/rack, -/obj/item/storage/toolbox/crafter{ - pixel_x = 3; - pixel_y = -3 - }, -/turf/open/floor/sepia, -/area/station/security/prison/rec) "umg" = ( /obj/structure/cable, /obj/effect/turf_decal/weather/snow/corner{ @@ -72567,15 +72221,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/cargo/lobby) -"una" = ( -/obj/machinery/door/window/left/directional/west, -/obj/structure/cable, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/carpet/blue, -/area/station/security/prison/work) "unh" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 4 @@ -72583,13 +72228,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/white, /area/station/medical/treatment_center) -"uno" = ( -/obj/structure/closet/secure_closet/freezer/gulag_fridge, -/obj/effect/turf_decal/tile/red/half/contrasted{ - dir = 8 - }, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "unq" = ( /obj/structure/light_construct/directional/north, /obj/effect/spawner/random/structure/closet_private, @@ -72613,10 +72251,6 @@ /obj/machinery/light/small/directional/north, /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/underground/explored) -"unC" = ( -/obj/machinery/gulag_teleporter, -/turf/open/floor/iron/showroomfloor, -/area/station/security/processing) "unH" = ( /obj/structure/table, /obj/item/analyzer{ @@ -72664,15 +72298,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/fore) -"uoi" = ( -/obj/structure/sink/directional/west, -/obj/item/reagent_containers/cup/bucket, -/obj/item/mop, -/obj/item/reagent_containers/cup/bottle/ammonia, -/obj/machinery/airalarm/directional/south, -/obj/effect/spawner/random/contraband/prison, -/turf/open/floor/plating, -/area/station/security/prison/safe) "uoj" = ( /obj/structure/sign/warning/cold_temp/directional/north, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ @@ -72800,10 +72425,6 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/security/prison) -"upB" = ( -/obj/effect/turf_decal/tile/red/anticorner/contrasted, -/turf/open/floor/iron, -/area/station/security/prison/visit) "upH" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -72823,6 +72444,18 @@ /obj/structure/tank_holder/extinguisher, /turf/open/floor/iron/white, /area/station/medical/treatment_center) +"upP" = ( +/obj/machinery/door/airlock{ + name = "Perma Overlook Closet" + }, +/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/cyclelink_helper_multi{ + cycle_id = "perma-overlook" + }, +/turf/open/floor/vault, +/area/station/security/prison/mess) "upU" = ( /obj/structure/table/wood, /obj/item/raptor_dex{ @@ -72838,11 +72471,6 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/iron/dark, /area/station/engineering/atmos/project) -"upY" = ( -/obj/structure/chair/pew/right, -/obj/machinery/light/small/directional/east, -/turf/open/floor/wood, -/area/station/security/prison/rec) "uqg" = ( /obj/machinery/conveyor_switch/oneway{ dir = 8; @@ -72883,11 +72511,11 @@ /obj/machinery/light/small/directional/north, /turf/open/floor/iron, /area/station/maintenance/starboard/fore) -"uqX" = ( -/obj/effect/decal/remains/human, -/obj/item/pickaxe/improvised, -/turf/open/misc/asteroid/snow/icemoon, -/area/icemoon/surface/outdoors/labor_camp) +"uqZ" = ( +/mob/living/basic/bot/secbot/beepsky/armsky, +/obj/machinery/airalarm/directional/east, +/turf/open/floor/iron/dark/textured, +/area/station/security/armory) "urd" = ( /obj/structure/chair/stool/directional/north, /turf/open/floor/iron, @@ -72912,12 +72540,6 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/iron/dark/textured, /area/station/science/research) -"urm" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/obj/machinery/newscaster/directional/north, -/turf/open/floor/wood, -/area/station/security/prison/rec) "uro" = ( /obj/machinery/requests_console/directional/east{ department = "Telecomms Admin"; @@ -72952,6 +72574,14 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron/white, /area/station/science/research) +"urP" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/turf_decal/bot, +/turf/open/floor/iron/smooth_edge{ + dir = 1 + }, +/area/station/security/lockers) "urQ" = ( /obj/effect/turf_decal/siding/white, /obj/effect/turf_decal/tile/blue/opposingcorners, @@ -72980,18 +72610,6 @@ /obj/machinery/airalarm/directional/east, /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) -"uso" = ( -/obj/structure/closet/crate/trashcart, -/obj/effect/spawner/random/contraband/prison, -/obj/item/trash/chips, -/obj/item/trash/candy, -/turf/open/floor/plating, -/area/station/security/prison/safe) -"usx" = ( -/obj/item/kirbyplants/organic/plant10, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/mine/laborcamp) "usS" = ( /obj/structure/bed{ dir = 1 @@ -73029,6 +72647,19 @@ /obj/item/toy/crayon/spraycan/roboticist, /turf/open/floor/iron, /area/station/science/robotics/lab) +"utw" = ( +/obj/machinery/power/apc/auto_name/directional/west, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/recharge_station, +/obj/effect/turf_decal/bot/left, +/obj/machinery/camera/directional/west{ + c_tag = "Security - Equipment Room" + }, +/turf/open/floor/iron/smooth_edge{ + dir = 1 + }, +/area/station/security/lockers) "utA" = ( /obj/effect/turf_decal/stripes/line{ dir = 9 @@ -73095,10 +72726,22 @@ /obj/item/stack/rods, /turf/open/floor/iron/smooth, /area/station/maintenance/port/aft) +"uuB" = ( +/obj/effect/turf_decal/siding/dark{ + dir = 1 + }, +/turf/open/floor/iron/dark, +/area/mine/laborcamp/security) "uuC" = ( /obj/structure/railing/corner, /turf/open/floor/iron, /area/station/hallway/primary/starboard) +"uuH" = ( +/obj/structure/table, +/obj/machinery/recharger, +/obj/effect/turf_decal/tile/red/fourcorners, +/turf/open/floor/iron/dark, +/area/mine/laborcamp/security) "uuI" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -73161,6 +72804,11 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/engineering/atmos) +"uvI" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/security/prison/mess) "uvM" = ( /obj/effect/spawner/structure/window/hollow/reinforced/middle, /turf/open/floor/plating, @@ -73184,6 +72832,12 @@ /obj/machinery/rnd/production/protolathe/department/engineering, /turf/open/floor/iron/dark, /area/station/engineering/lobby) +"uww" = ( +/obj/machinery/space_heater, +/obj/structure/sign/warning/cold_temp/directional/west, +/obj/machinery/light/small/dim/directional/north, +/turf/open/floor/vault, +/area/station/security/prison/rec) "uwE" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -73438,6 +73092,11 @@ /obj/effect/mapping_helpers/airlock/access/all/service/bar, /turf/open/floor/iron/dark/textured_half, /area/station/service/bar/backroom) +"uzA" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/turf/open/floor/iron/cafeteria, +/area/station/security/prison/mess) "uzB" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 4 @@ -73460,6 +73119,11 @@ }, /turf/open/floor/iron/dark/textured, /area/station/security/prison) +"uzN" = ( +/obj/structure/cable, +/obj/effect/spawner/structure/window/hollow/reinforced/middle, +/turf/open/floor/plating, +/area/station/security/execution/education) "uAi" = ( /obj/structure/table/reinforced, /obj/item/hfr_box/corner, @@ -73481,12 +73145,6 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/iron, /area/station/commons/storage/primary) -"uAE" = ( -/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/textured, -/area/station/security/range) "uAJ" = ( /obj/machinery/space_heater, /turf/open/floor/plating, @@ -73581,15 +73239,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/ai/satellite/interior) -"uCk" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/obj/effect/turf_decal/tile/blue/opposingcorners{ - dir = 1 - }, -/turf/open/floor/iron/white, -/area/mine/laborcamp) "uCn" = ( /obj/structure/marker_beacon/burgundy{ name = "landing marker" @@ -73649,6 +73298,15 @@ /obj/structure/grille/broken, /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/underground/explored) +"uCX" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 1 + }, +/turf/open/floor/iron, +/area/mine/production) "uDa" = ( /obj/structure/chair/comfy/brown{ dir = 4 @@ -73725,14 +73383,6 @@ /obj/machinery/newscaster/directional/east, /turf/open/floor/iron/white/smooth_large, /area/station/service/kitchen) -"uDy" = ( -/obj/item/book/bible, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/table/wood, -/turf/open/floor/iron/dark, -/area/station/security/prison/rec) "uDE" = ( /obj/structure/table, /obj/item/folder/yellow, @@ -73804,29 +73454,6 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/command/bridge) -"uFf" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable, -/turf/open/floor/plating, -/area/station/security/processing) -"uFg" = ( -/obj/machinery/door/poddoor/preopen{ - id = "Prison Gate"; - name = "Prison Blast Door" - }, -/obj/machinery/door/firedoor, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/obj/machinery/status_display/door_timer{ - id = "Cell 1"; - name = "Cell 1"; - pixel_x = -32 - }, -/turf/open/floor/iron/textured, -/area/station/security/brig) "uFh" = ( /turf/open/floor/plating, /area/station/construction) @@ -73955,13 +73582,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/security/prison/visit) -"uHF" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/disposalpipe/segment, -/obj/structure/cable, -/turf/open/floor/plating, -/area/station/maintenance/fore) "uHN" = ( /obj/machinery/newscaster/directional/north, /obj/effect/turf_decal/tile/neutral/half/contrasted{ @@ -73993,18 +73613,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/purple/visible, /turf/open/floor/plating, /area/station/maintenance/port/aft) -"uIC" = ( -/obj/machinery/door/airlock/security{ - aiControlDisabled = 1; - name = "Prisoner Transfer Centre" - }, -/obj/machinery/door/firedoor, -/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/all/security/armory, -/turf/open/floor/iron/dark, -/area/station/security/execution/education) "uID" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/smart/simple/cyan/visible{ @@ -74206,15 +73814,16 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central) -"uLF" = ( -/turf/open/floor/carpet, -/area/station/security/processing) "uLH" = ( /obj/effect/turf_decal/stripes/corner{ dir = 8 }, /turf/open/floor/engine, /area/station/engineering/supermatter/room) +"uLS" = ( +/obj/effect/turf_decal/trimline/red/warning, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/surface/outdoors/nospawn) "uLX" = ( /obj/machinery/door/airlock{ name = "Port Emergency Storage" @@ -74266,6 +73875,14 @@ "uME" = ( /turf/closed/wall/r_wall, /area/station/security/execution/transfer) +"uMF" = ( +/obj/machinery/computer/mech_bay_power_console{ + dir = 1 + }, +/obj/structure/cable, +/obj/item/radio/intercom/directional/south, +/turf/open/floor/iron, +/area/station/security/mechbay) "uMK" = ( /obj/structure/table, /obj/item/paper_bin{ @@ -74280,10 +73897,38 @@ "uMN" = ( /turf/open/openspace, /area/station/commons/storage/mining) +"uMV" = ( +/obj/machinery/power/apc/auto_name/directional/west, +/obj/structure/cable, +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/dark/side{ + dir = 10 + }, +/area/mine/laborcamp/security) "uMW" = ( /obj/structure/sign/warning/directional/west, /turf/open/openspace/icemoon, /area/icemoon/surface/outdoors/less_spawns) +"uMX" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/turf/open/floor/iron, +/area/station/security/prison/mess) +"uNb" = ( +/obj/machinery/bouldertech/refinery{ + dir = 4 + }, +/obj/machinery/conveyor{ + dir = 8; + id = "mining_internal" + }, +/turf/open/floor/iron, +/area/mine/production) "uNq" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 1 @@ -74298,19 +73943,19 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/circuit, /area/station/ai/satellite/hallway) +"uNL" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/cable, +/turf/open/floor/iron/dark, +/area/station/security/mechbay) "uNN" = ( /obj/effect/spawner/random/trash/bin, /obj/effect/spawner/random/maintenance, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) -"uNV" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/turf_decal/siding/wideplating/dark{ - dir = 4 - }, -/obj/machinery/holopad, -/turf/open/floor/iron/dark/textured, -/area/station/security/prison/rec) "uNW" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable, @@ -74427,16 +74072,6 @@ "uPk" = ( /turf/closed/wall/r_wall, /area/station/security/range) -"uPl" = ( -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 4 - }, -/obj/machinery/door/airlock/security/glass{ - name = "Labor Camp Shuttle Prisoner Airlock" - }, -/obj/effect/mapping_helpers/airlock/access/all/security/brig, -/turf/open/floor/iron, -/area/mine/laborcamp) "uPt" = ( /obj/structure/closet/crate/bin, /turf/open/floor/iron/dark, @@ -74500,6 +74135,16 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/mine/production) +"uQm" = ( +/obj/effect/turf_decal/tile/red/anticorner/contrasted{ + dir = 8 + }, +/obj/machinery/light/small/directional/south, +/obj/machinery/newscaster/directional/south, +/obj/structure/cable, +/obj/machinery/vending/cola/sodie, +/turf/open/floor/iron, +/area/station/security/prison/visit) "uQu" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, @@ -74601,13 +74246,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/engineering/atmos/mix) -"uSb" = ( -/obj/effect/spawner/structure/window/hollow/reinforced/middle{ - dir = 4 - }, -/obj/structure/cable, -/turf/open/floor/plating/snowed/icemoon, -/area/icemoon/underground/explored) "uSd" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /obj/effect/turf_decal/siding/blue/corner{ @@ -74659,14 +74297,6 @@ /obj/structure/cable, /turf/open/floor/iron/white, /area/station/medical/pharmacy) -"uTo" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/obj/structure/sign/poster/official/do_not_question/directional/north, -/turf/open/floor/iron, -/area/mine/laborcamp) "uTp" = ( /obj/effect/turf_decal/tile/red/half/contrasted{ dir = 1 @@ -74819,21 +74449,18 @@ }, /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) -"uVC" = ( +"uVH" = ( +/obj/structure/curtain/cloth, +/obj/effect/turf_decal/siding/dark, +/turf/open/floor/iron/showroomfloor, +/area/station/security/prison/toilet) +"uWk" = ( +/obj/effect/decal/cleanable/dirt, /obj/structure/cable, -/obj/machinery/power/apc/auto_name/directional/north, -/obj/effect/turf_decal/tile/red/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron/dark/textured_edge, -/area/station/security/prison) -"uVP" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/turf/open/floor/iron/smooth_edge{ - dir = 1 - }, -/area/station/security/lockers) +/obj/structure/sign/warning/electric_shock/directional/north, +/obj/machinery/airalarm/directional/east, +/turf/open/floor/iron, +/area/station/security/prison/workout) "uWo" = ( /obj/structure/cable, /obj/machinery/duct, @@ -74879,6 +74506,13 @@ /obj/effect/spawner/random/maintenance, /turf/open/floor/plating, /area/station/maintenance/port/aft) +"uWY" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/machinery/light/small/directional/west, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/surface/outdoors/nospawn) "uXd" = ( /obj/effect/turf_decal/tile/bar/opposingcorners, /obj/machinery/duct, @@ -74918,11 +74552,6 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/cargo/bitrunning/den) -"uYj" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/freezer, -/area/mine/laborcamp) "uYB" = ( /obj/effect/turf_decal/trimline/blue/filled/corner, /obj/structure/cable, @@ -74940,12 +74569,6 @@ }, /turf/open/floor/iron, /area/station/service/hydroponics) -"uYF" = ( -/obj/structure/railing{ - dir = 6 - }, -/turf/open/floor/iron, -/area/mine/production) "uYH" = ( /obj/machinery/atmospherics/pipe/layer_manifold/dark/visible{ dir = 8 @@ -75079,6 +74702,11 @@ /obj/item/radio/intercom/directional/south, /turf/open/floor/wood, /area/station/service/library) +"vaH" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, +/obj/structure/sign/warning/gas_mask/directional/north, +/turf/open/floor/iron/smooth, +/area/station/security/eva) "vaL" = ( /obj/structure/table, /obj/item/storage/bag/tray, @@ -75090,11 +74718,6 @@ }, /turf/open/floor/iron/white/smooth_large, /area/station/service/kitchen) -"vaW" = ( -/obj/effect/mapping_helpers/broken_floor, -/obj/machinery/portable_atmospherics/canister, -/turf/open/floor/plating, -/area/station/maintenance/fore) "vaZ" = ( /obj/item/book/manual/wiki/plumbing{ pixel_x = 4; @@ -75125,20 +74748,22 @@ }, /turf/open/floor/engine, /area/station/engineering/atmos/hfr_room) -"vbg" = ( -/obj/structure/cable, -/obj/machinery/power/smes/full, -/obj/machinery/camera/directional/south{ - c_tag = "Labor Camp Utilities"; - network = list("labor") - }, -/turf/open/floor/iron/smooth, -/area/mine/laborcamp/security) "vbn" = ( /obj/machinery/power/smes/full, /obj/structure/cable, /turf/open/floor/circuit/telecomms/mainframe, /area/station/tcommsat/server) +"vbo" = ( +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 5 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/turf/open/floor/iron/dark/side{ + dir = 5 + }, +/area/station/security/prison/safe) "vbC" = ( /obj/structure/chair{ dir = 4 @@ -75219,6 +74844,10 @@ }, /turf/open/floor/cult, /area/station/service/chapel/office) +"vct" = ( +/obj/machinery/firealarm/directional/north, +/turf/open/floor/iron/smooth, +/area/station/engineering/lobby) "vcx" = ( /obj/machinery/newscaster/directional/east, /obj/structure/sink/directional/west, @@ -75486,6 +75115,15 @@ /obj/structure/grille, /turf/open/floor/plating, /area/station/science/xenobiology) +"vgk" = ( +/obj/structure/cable, +/obj/effect/spawner/structure/window/hollow/reinforced/middle, +/obj/machinery/door/poddoor/preopen{ + id = "labor"; + name = "Labor Camp Blast Door" + }, +/turf/open/floor/plating, +/area/mine/laborcamp) "vgw" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/light/small/directional/west, @@ -75541,20 +75179,22 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/plating, /area/station/maintenance/fore) -"vhL" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 6 +"vhS" = ( +/obj/structure/window/reinforced/spawner/directional/north{ + pixel_y = 2 }, -/obj/structure/cable, -/obj/effect/turf_decal/tile/red/anticorner/contrasted{ - dir = 8 +/obj/structure/rack, +/obj/effect/decal/cleanable/dirt, +/obj/item/clothing/mask/muzzle, +/obj/machinery/flasher/directional/east{ + id = "cell4"; + pixel_y = -7 }, -/turf/open/floor/iron/dark/corner{ - dir = 4 +/obj/effect/turf_decal/siding/red{ + dir = 1 }, -/area/station/security/processing) +/turf/open/floor/iron/smooth, +/area/station/security/holding_cell) "vhT" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/simple/brown/visible{ @@ -75575,6 +75215,12 @@ /obj/structure/sign/nanotrasen/directional/north, /turf/open/floor/iron, /area/station/command/bridge) +"vix" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/machinery/power/apc/auto_name/directional/west, +/turf/open/floor/catwalk_floor/iron_smooth, +/area/station/security/eva) "viH" = ( /obj/machinery/power/emitter/welded{ dir = 4 @@ -75614,6 +75260,24 @@ }, /turf/open/floor/iron/dark, /area/station/engineering/atmos/project) +"vjm" = ( +/obj/structure/closet/secure_closet/security/sec, +/obj/machinery/status_display/evac/directional/north, +/obj/effect/turf_decal/bot, +/turf/open/floor/iron/smooth_edge, +/area/station/security/lockers) +"vjo" = ( +/obj/structure/table, +/obj/item/book/manual/wiki/security_space_law, +/obj/item/book/manual/wiki/security_space_law, +/obj/item/hand_labeler{ + pixel_x = -4; + pixel_y = -6 + }, +/turf/open/floor/iron/dark/textured_half{ + dir = 1 + }, +/area/station/security/office) "vjq" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -75691,12 +75355,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) -"vkJ" = ( -/obj/structure/table, -/obj/item/plate, -/obj/effect/turf_decal/tile/red, -/turf/open/floor/iron, -/area/station/security/prison/mess) "vkS" = ( /obj/effect/spawner/random/engineering/tracking_beacon, /turf/open/floor/plating/icemoon, @@ -75713,6 +75371,12 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central) +"vlm" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/vending/sustenance/labor_camp, +/obj/structure/cable, +/turf/open/floor/iron, +/area/mine/laborcamp) "vlF" = ( /obj/structure/railing{ dir = 4 @@ -75720,12 +75384,6 @@ /obj/structure/stairs/north, /turf/open/floor/iron, /area/mine/eva/lower) -"vlH" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/light/directional/north, -/obj/machinery/airalarm/directional/north, -/turf/open/floor/iron, -/area/station/security/prison/visit) "vlL" = ( /obj/machinery/computer/cargo/request, /turf/open/floor/iron, @@ -75746,6 +75404,11 @@ /obj/effect/mapping_helpers/airlock/access/all/supply/mining, /turf/open/floor/iron/smooth, /area/mine/mechbay) +"vme" = ( +/obj/machinery/light/directional/east, +/obj/structure/cable, +/turf/open/floor/carpet/blue, +/area/station/security/prison/work) "vmj" = ( /obj/structure/chair{ dir = 1; @@ -75807,6 +75470,14 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/port/fore) +"vmz" = ( +/obj/structure/table, +/obj/item/storage/bag/tray, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable, +/obj/item/kitchen/rollingpin, +/turf/open/floor/iron/cafeteria, +/area/station/security/prison/mess) "vmA" = ( /obj/structure/fluff/tram_rail{ pixel_y = 17 @@ -75864,6 +75535,15 @@ /obj/structure/table/wood, /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) +"vmY" = ( +/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/red{ + dir = 8 + }, +/turf/open/floor/iron, +/area/mine/laborcamp/security) "vmZ" = ( /obj/effect/landmark/firealarm_sanity, /turf/open/floor/glass/reinforced, @@ -75942,6 +75622,15 @@ /obj/structure/closet/crate/critter, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) +"vof" = ( +/obj/structure/sign/warning/cold_temp/directional/west, +/obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/mine/laborcamp) "voj" = ( /obj/structure/disposalpipe/sorting/mail/flip{ dir = 8 @@ -75957,6 +75646,13 @@ /obj/effect/turf_decal/tile/yellow/half/contrasted, /turf/open/floor/iron, /area/station/hallway/primary/aft) +"vop" = ( +/obj/effect/spawner/structure/window/hollow/reinforced/middle{ + dir = 4 + }, +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/engineering/lobby) "vos" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -75979,12 +75675,6 @@ "voK" = ( /turf/closed/wall/r_wall, /area/station/tcommsat/computer) -"voL" = ( -/obj/effect/turf_decal/tile/red{ - dir = 8 - }, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "voO" = ( /obj/machinery/light/small/directional/east, /turf/open/floor/iron/dark, @@ -76032,11 +75722,6 @@ /obj/machinery/firealarm/directional/south, /turf/open/floor/iron/smooth, /area/station/security/execution/transfer) -"vpn" = ( -/obj/vehicle/sealed/mecha/ripley/paddy/preset, -/obj/structure/cable, -/turf/open/floor/iron/recharge_floor, -/area/station/security/mechbay) "vpx" = ( /obj/structure/sign/departments/evac/directional/north, /turf/open/floor/iron, @@ -76085,6 +75770,21 @@ }, /turf/open/floor/plating, /area/station/maintenance/fore/lesser) +"vqu" = ( +/obj/structure/table, +/obj/machinery/recharger{ + pixel_x = 5 + }, +/obj/machinery/light_switch/directional/east, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/machinery/recharger{ + pixel_x = -6 + }, +/turf/open/floor/iron/smooth_edge{ + dir = 1 + }, +/area/station/security/lockers) "vqv" = ( /obj/effect/turf_decal/stripes/line, /turf/open/floor/iron, @@ -76146,6 +75846,9 @@ /obj/item/kirbyplants/random, /turf/open/floor/iron, /area/station/security/courtroom) +"vri" = ( +/turf/closed/wall/r_wall, +/area/station/security/eva) "vrw" = ( /obj/machinery/button/door/directional/west{ id = "xenobio3"; @@ -76191,6 +75894,12 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron, /area/station/hallway/primary/central) +"vrY" = ( +/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, +/area/mine/laborcamp) "vsk" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/turf_decal/tile/red/half/contrasted, @@ -76205,14 +75914,6 @@ }, /turf/open/floor/iron/dark/textured_large, /area/station/engineering/storage/tech) -"vsp" = ( -/obj/structure/window/reinforced/spawner/directional/west, -/obj/effect/turf_decal/stripes/red/line{ - dir = 6 - }, -/obj/effect/turf_decal/trimline/red/line, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) "vsx" = ( /obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/visible/layer4, @@ -76233,16 +75934,6 @@ /obj/structure/marker_beacon/burgundy, /turf/open/floor/plating/snowed/icemoon, /area/icemoon/surface/outdoors/nospawn) -"vsL" = ( -/obj/structure/cable, -/obj/effect/turf_decal/tile/red/anticorner/contrasted{ - dir = 8 - }, -/obj/machinery/camera/directional/west{ - c_tag = "Security - Office - Port" - }, -/turf/open/floor/iron/dark, -/area/station/security/mechbay) "vsM" = ( /obj/structure/cable, /obj/machinery/power/apc/auto_name/directional/west, @@ -76377,14 +76068,6 @@ /obj/machinery/atmospherics/pipe/layer_manifold/dark, /turf/open/floor/plating, /area/station/engineering/atmos) -"vux" = ( -/obj/structure/bed, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 1 - }, -/turf/open/floor/iron, -/area/mine/laborcamp) "vuK" = ( /obj/structure/sign/warning/fire, /turf/closed/wall/r_wall, @@ -76426,6 +76109,13 @@ dir = 1 }, /area/station/command/eva) +"vvz" = ( +/obj/structure/closet/bombcloset/security, +/obj/effect/turf_decal/bot, +/turf/open/floor/iron/smooth_edge{ + dir = 1 + }, +/area/station/security/lockers) "vvE" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -76555,29 +76245,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) -"vwE" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/chair/wood{ - dir = 8 - }, -/obj/effect/turf_decal/siding/wood{ - dir = 5 - }, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/wood, -/area/station/security/prison/rec) -"vwG" = ( -/obj/machinery/vending/security{ - all_products_free = 0 - }, -/obj/effect/turf_decal/tile/red/half/contrasted{ - dir = 8 - }, -/obj/machinery/light/small/directional/west, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "vwJ" = ( /obj/machinery/door/airlock/maintenance, /obj/effect/mapping_helpers/airlock/abandoned, @@ -76610,6 +76277,14 @@ }, /turf/open/floor/iron/dark, /area/station/command/gateway) +"vwU" = ( +/obj/machinery/door/airlock/security{ + name = "Labor Camp Supplies" + }, +/obj/structure/cable, +/obj/effect/mapping_helpers/airlock/access/all/security/brig, +/turf/open/floor/iron, +/area/mine/laborcamp/security) "vxc" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -76666,12 +76341,6 @@ /obj/machinery/modular_computer/preset/id, /turf/open/floor/carpet/royalblue, /area/station/command/heads_quarters/hos) -"vyh" = ( -/obj/structure/chair{ - dir = 8 - }, -/turf/open/floor/iron/showroomfloor, -/area/station/security/processing) "vym" = ( /turf/closed/wall, /area/station/construction) @@ -76701,12 +76370,6 @@ "vyt" = ( /turf/open/floor/plating, /area/station/ai/satellite/maintenance) -"vyw" = ( -/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/dark/textured, -/area/station/security/range) "vyx" = ( /obj/effect/spawner/random/engineering/tracking_beacon, /obj/effect/landmark/event_spawn, @@ -76724,13 +76387,6 @@ /obj/machinery/light/small/dim/directional/east, /turf/open/floor/plating, /area/station/maintenance/department/medical/morgue) -"vyO" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/landmark/event_spawn, -/turf/open/floor/wood, -/area/station/security/prison/rec) "vyU" = ( /obj/machinery/atmospherics/pipe/heat_exchanging/simple, /turf/open/misc/asteroid/snow/icemoon, @@ -76758,11 +76414,6 @@ dir = 1 }, /area/station/science/research) -"vzp" = ( -/obj/machinery/light/warm/directional/north, -/obj/machinery/newscaster/directional/north, -/turf/open/floor/iron/dark/textured, -/area/station/security/prison/rec) "vzs" = ( /obj/structure/filingcabinet, /obj/structure/cable, @@ -76819,13 +76470,6 @@ /obj/machinery/newscaster/directional/west, /turf/open/floor/iron/recharge_floor, /area/station/science/robotics/mechbay) -"vAm" = ( -/obj/machinery/airalarm/directional/north, -/obj/effect/turf_decal/tile/red/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/security/brig/upper) "vAq" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark, @@ -76851,6 +76495,15 @@ /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/plating, /area/station/maintenance/aft/lesser) +"vAz" = ( +/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/security/brig/upper) "vAF" = ( /obj/machinery/door/airlock/hatch{ name = "MiniSat Teleporter" @@ -76868,6 +76521,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/construction) +"vAJ" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 8 + }, +/obj/machinery/status_display/evac/directional/east, +/turf/open/floor/iron/smooth, +/area/station/engineering/lobby) "vAP" = ( /obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/tile/blue/half/contrasted, @@ -76947,6 +76607,16 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/engineering/atmos/pumproom) +"vBA" = ( +/obj/structure/mineral_door/paperframe{ + name = "Meditation Room" + }, +/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, +/turf/open/floor/iron/sepia, +/area/station/security/prison/rec) "vBC" = ( /obj/machinery/meter, /obj/machinery/atmospherics/pipe/smart/simple/yellow/visible{ @@ -76957,6 +76627,12 @@ "vBG" = ( /turf/closed/wall, /area/station/command/heads_quarters/cmo) +"vCe" = ( +/obj/structure/table, +/obj/effect/turf_decal/tile/red, +/obj/effect/spawner/random/food_or_drink/snack/lizard, +/turf/open/floor/iron, +/area/station/security/prison/mess) "vCm" = ( /obj/structure/marker_beacon/burgundy, /obj/effect/turf_decal/weather/snow/corner{ @@ -76965,19 +76641,6 @@ /obj/structure/sign/warning/cold_temp/directional/north, /turf/open/floor/plating/snowed/icemoon, /area/icemoon/surface/outdoors/nospawn) -"vCn" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/camera/directional/north{ - c_tag = "Security - Upper Permabrig Cafeteria"; - network = list("ss13","prison") - }, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/security/prison/mess) "vCy" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -77034,15 +76697,10 @@ /obj/effect/spawner/random/armory/disablers, /turf/open/floor/iron/dark/textured, /area/station/security/armory) -"vDy" = ( -/obj/structure/sign/poster/official/safety_report/directional/west, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/camera/directional/west{ - c_tag = "Labor Camp Central"; - network = list("labor") - }, -/turf/open/floor/iron, -/area/mine/laborcamp) +"vDC" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/security/execution/education) "vDO" = ( /obj/effect/turf_decal/stripes/corner{ dir = 8 @@ -77125,6 +76783,16 @@ /obj/structure/cable, /turf/open/floor/iron/dark/telecomms, /area/station/tcommsat/server) +"vFN" = ( +/obj/structure/rack, +/obj/machinery/syndicatebomb/training, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/item/screwdriver, +/obj/item/wirecutters, +/turf/open/floor/iron/dark/smooth_half, +/area/station/security/office) "vFO" = ( /obj/structure/window/reinforced/spawner/directional/west, /obj/structure/window/reinforced/spawner/directional/east, @@ -77155,6 +76823,42 @@ /obj/effect/mapping_helpers/mail_sorting/medbay/virology, /turf/open/floor/iron/white, /area/station/medical/medbay/aft) +"vFZ" = ( +/obj/structure/cable, +/obj/structure/table/glass, +/obj/item/stack/medical/wrap/sticky_tape/surgical, +/obj/item/stack/medical/bone_gel, +/obj/effect/turf_decal/tile/blue/half/contrasted, +/obj/machinery/camera/directional/south{ + c_tag = "Surgery B"; + network = list("ss13","medbay") + }, +/obj/machinery/newscaster/directional/south, +/turf/open/floor/iron/white, +/area/station/medical/surgery/aft) +"vGb" = ( +/obj/effect/turf_decal/tile/red, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 1 + }, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/security/prison/mess) +"vGh" = ( +/obj/structure/cable, +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/machinery/light/small/directional/east, +/obj/machinery/camera/directional/east{ + c_tag = "Security - Labor Camp"; + network = list("ss13","prison","labor") + }, +/turf/open/floor/iron/dark/side{ + dir = 4 + }, +/area/mine/laborcamp/security) "vGw" = ( /obj/structure/transit_tube/station/reverse, /obj/structure/sign/warning/secure_area/directional/north, @@ -77348,6 +77052,10 @@ dir = 8 }, /area/station/medical/chemistry) +"vIE" = ( +/obj/effect/spawner/random/structure/girder, +/turf/open/floor/plating, +/area/station/maintenance/department/security) "vIH" = ( /obj/structure/closet{ name = "evidence closet 1" @@ -77449,10 +77157,6 @@ }, /turf/open/floor/iron, /area/station/command/heads_quarters/rd) -"vKk" = ( -/obj/machinery/vending/security, -/turf/open/floor/iron/smooth_edge, -/area/station/security/lockers) "vKq" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -77541,6 +77245,11 @@ /obj/machinery/door/firedoor, /turf/open/floor/iron/textured, /area/station/commons/storage/mining) +"vLw" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, +/obj/item/radio/intercom/directional/east, +/turf/open/floor/iron/smooth, +/area/station/security/eva) "vLY" = ( /obj/structure/railing{ dir = 8 @@ -77570,12 +77279,39 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/service/chapel/office) +"vMt" = ( +/obj/structure/table/glass, +/obj/item/book/manual/wiki/medicine{ + pixel_x = 1; + pixel_y = 5 + }, +/obj/item/book/manual/wiki/surgery{ + pixel_x = -4; + pixel_y = 3 + }, +/obj/effect/turf_decal/tile/blue/full, +/obj/item/tgui_book/manual/idc{ + pixel_y = 3; + pixel_x = 3 + }, +/obj/item/tgui_book/manual/dsm, +/turf/open/floor/iron/large, +/area/station/medical/treatment_center) "vMA" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/cable/layer3, /turf/open/floor/plating, /area/station/ai/satellite/interior) +"vMO" = ( +/obj/structure/toilet/greyscale{ + cistern_open = 1; + dir = 2 + }, +/obj/machinery/light/small/directional/north, +/obj/effect/spawner/random/entertainment/cigar, +/turf/open/floor/iron/showroomfloor, +/area/station/security/prison/toilet) "vMY" = ( /obj/structure/disposalpipe/segment{ dir = 6 @@ -77680,10 +77416,6 @@ /obj/item/radio/intercom/directional/south, /turf/open/floor/iron, /area/station/service/janitor) -"vPt" = ( -/obj/structure/closet/secure_closet/freezer/meat/all_access, -/turf/open/floor/iron/showroomfloor, -/area/station/security/prison/mess) "vPx" = ( /turf/open/floor/iron/dark/textured, /area/station/security/prison/workout) @@ -77790,31 +77522,22 @@ }, /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/surface/outdoors/less_spawns) -"vRN" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 10 - }, -/turf/open/floor/iron, -/area/station/security/processing) -"vRO" = ( -/obj/machinery/mineral/unloading_machine{ - dir = 1; - icon_state = "unloader-corner"; - input_dir = 1; - output_dir = 2 - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/mine/laborcamp) "vRP" = ( /obj/structure/window/reinforced/spawner/directional/west, /turf/open/floor/iron/dark/side{ dir = 8 }, /area/station/security/prison/workout) +"vRQ" = ( +/obj/structure/chair/sofa/bench/left{ + dir = 8 + }, +/obj/structure/extinguisher_cabinet/directional/east, +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 4 + }, +/turf/open/floor/iron/smooth, +/area/station/security/brig/upper) "vRS" = ( /obj/machinery/meter, /obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible, @@ -77853,13 +77576,6 @@ }, /turf/open/floor/wood, /area/station/maintenance/port/aft) -"vSK" = ( -/obj/structure/chair/sofa/bench/right{ - dir = 8 - }, -/obj/effect/turf_decal/tile/red, -/turf/open/floor/iron, -/area/station/security/prison/mess) "vSM" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 10 @@ -77994,12 +77710,6 @@ }, /turf/open/floor/plating/snowed/icemoon, /area/icemoon/surface/outdoors/less_spawns) -"vUs" = ( -/obj/structure/easel, -/obj/item/canvas/nineteen_nineteen, -/obj/machinery/airalarm/directional/north, -/turf/open/floor/sepia, -/area/station/security/prison/rec) "vUy" = ( /obj/structure/chair/pew/right{ dir = 1 @@ -78244,6 +77954,19 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/carpet, /area/station/command/meeting_room) +"vYf" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Security EVA"; + security_level = 1 + }, +/obj/effect/mapping_helpers/airlock/access/all/security/armory, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/red_alert_access, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/iron/smooth, +/area/station/security/eva) "vYg" = ( /obj/machinery/camera/directional/west{ c_tag = "Chapel West" @@ -78367,6 +78090,25 @@ }, /turf/open/floor/iron/dark, /area/station/science/genetics) +"wae" = ( +/obj/machinery/door/poddoor/shutters{ + id = "secmechbaymaint"; + name = "Security Mech Bay Shutters"; + dir = 4 + }, +/obj/effect/turf_decal/caution/stand_clear{ + dir = 4 + }, +/obj/effect/turf_decal/siding/dark_red{ + dir = 4 + }, +/obj/effect/turf_decal/siding/dark_red{ + dir = 8 + }, +/turf/open/floor/iron/dark/textured_half{ + dir = 1 + }, +/area/station/security/mechbay) "wam" = ( /turf/open/openspace, /area/station/cargo/storage) @@ -78456,13 +78198,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron/white, /area/station/medical/treatment_center) -"wbG" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/obj/machinery/airalarm/directional/west, -/turf/open/floor/iron/dark/textured, -/area/station/security/interrogation) "wbH" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -78653,19 +78388,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/engineering/main) -"wfp" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 4 - }, -/obj/machinery/camera/directional/west{ - c_tag = "Security - Upper Hallway North" - }, -/obj/machinery/firealarm/directional/west, -/obj/effect/turf_decal/tile/red/half/contrasted{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/security/brig/upper) "wfE" = ( /obj/structure/disposalpipe/segment{ dir = 10 @@ -78766,6 +78488,10 @@ }, /turf/open/floor/iron, /area/station/science/lab) +"wgW" = ( +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/underground/explored) "whb" = ( /obj/machinery/recharge_station, /obj/effect/decal/cleanable/dirt, @@ -79027,6 +78753,11 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/construction) +"wlg" = ( +/obj/structure/cable, +/obj/effect/turf_decal/bot, +/turf/open/floor/iron, +/area/mine/laborcamp) "wlr" = ( /obj/structure/table, /obj/item/stack/spacecash/c10, @@ -79055,10 +78786,6 @@ /obj/structure/filingcabinet, /turf/open/floor/iron/dark, /area/station/tcommsat/computer) -"wlR" = ( -/obj/structure/closet/boxinggloves, -/turf/open/floor/iron, -/area/station/security/prison/workout) "wlW" = ( /obj/item/radio/intercom/directional/south, /obj/machinery/computer/robotics{ @@ -79068,17 +78795,29 @@ dir = 6 }, /area/station/command/heads_quarters/rd) -"wlY" = ( -/obj/machinery/door/airlock/freezer, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/showroomfloor, -/area/station/security/prison/mess) "wme" = ( /obj/effect/turf_decal/weather/snow, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/plating/icemoon, /area/icemoon/underground/explored) +"wmn" = ( +/obj/structure/rack, +/obj/machinery/light/cold/directional/north, +/obj/item/storage/box/bandages{ + pixel_x = -6; + pixel_y = 6 + }, +/obj/item/healthanalyzer, +/obj/machinery/wall_healer/directional/north, +/turf/open/floor/iron/white/textured, +/area/station/security/medical) +"wmu" = ( +/obj/machinery/conveyor{ + id = "gulag"; + dir = 4 + }, +/turf/open/floor/iron, +/area/mine/laborcamp) "wmG" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -79129,22 +78868,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/command/bridge) -"wnm" = ( -/obj/structure/window/reinforced/spawner/directional/west, -/obj/structure/table/reinforced, -/obj/machinery/recharger, -/obj/machinery/light_switch/directional/south, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) -"wnv" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/obj/machinery/firealarm/directional/south, -/turf/open/floor/iron/dark, -/area/station/security/execution/education) "wnz" = ( /obj/structure/rack, /obj/item/electronics/airalarm, @@ -79167,6 +78890,13 @@ }, /turf/open/floor/engine, /area/station/science/xenobiology) +"wnH" = ( +/obj/structure/chair/pew/right{ + dir = 8 + }, +/obj/effect/spawner/random/contraband/permabrig_gear, +/turf/open/floor/wood/large, +/area/station/security/prison/rec) "wnK" = ( /obj/effect/turf_decal/stripes/corner{ dir = 8 @@ -79204,6 +78934,14 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/security/brig) +"woo" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/iron/dark, +/area/station/security/execution/education) "wor" = ( /turf/open/openspace, /area/station/medical/medbay/aft) @@ -79323,13 +79061,6 @@ "wqx" = ( /turf/closed/wall/r_wall, /area/station/hallway/primary/fore) -"wqI" = ( -/obj/item/radio/intercom/directional/north, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/turf/open/floor/iron/smooth, -/area/station/security/brig) "wqN" = ( /obj/structure/railing{ dir = 10 @@ -79351,6 +79082,28 @@ /obj/machinery/airalarm/directional/south, /turf/open/floor/plating, /area/station/maintenance/port/lesser) +"wre" = ( +/obj/structure/table/wood, +/obj/item/storage/box/matches, +/obj/item/toy/cards/deck{ + pixel_y = 4 + }, +/obj/item/reagent_containers/cup/glass/drinkingglass{ + pixel_x = 14; + pixel_y = 12 + }, +/obj/item/reagent_containers/cup/glass/drinkingglass{ + pixel_x = -18; + pixel_y = 10 + }, +/obj/item/reagent_containers/cup/glass/drinkingglass{ + pixel_x = -10; + pixel_y = 2 + }, +/obj/effect/mapping_helpers/broken_floor, +/obj/effect/turf_decal/siding/wood, +/turf/open/floor/wood, +/area/station/maintenance/fore) "wrk" = ( /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 8 @@ -79409,6 +79162,18 @@ "wrX" = ( /turf/closed/wall, /area/station/service/chapel) +"wrY" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/firealarm/directional/east{ + pixel_y = -6 + }, +/obj/machinery/light_switch/directional/east{ + pixel_y = 4 + }, +/turf/open/floor/iron/dark/textured, +/area/station/security/interrogation) "wsh" = ( /obj/structure/rack, /obj/effect/spawner/random/maintenance/three, @@ -79443,6 +79208,22 @@ /obj/machinery/light/directional/south, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) +"wsF" = ( +/obj/structure/table/glass, +/obj/item/book/manual/wiki/infections{ + pixel_y = 7 + }, +/obj/item/reagent_containers/syringe/antiviral, +/obj/effect/turf_decal/trimline/green/filled/line, +/obj/structure/reagent_dispensers/wall/virusfood/directional/south, +/obj/item/tgui_book/manual/idc{ + pixel_y = 3; + pixel_x = 3 + }, +/obj/item/reagent_containers/spray/cleaner, +/obj/item/reagent_containers/dropper, +/turf/open/floor/iron/white, +/area/station/medical/virology) "wsN" = ( /obj/structure/girder, /obj/structure/grille, @@ -79480,11 +79261,16 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/department/chapel) -"wtg" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +"wtf" = ( +/obj/machinery/camera/directional/east{ + c_tag = "Security - Permabrig Chapel"; + network = list("ss13","prison") + }, /obj/structure/cable, -/turf/open/floor/wood/large, -/area/station/command/heads_quarters/hos) +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/newscaster/directional/east, +/turf/open/floor/iron/dark, +/area/station/security/prison/rec) "wtj" = ( /obj/structure/flora/grass/brown/style_2, /turf/open/misc/asteroid/snow/icemoon, @@ -79493,6 +79279,17 @@ /obj/machinery/atmospherics/pipe/heat_exchanging/simple, /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/underground/explored) +"wtE" = ( +/obj/structure/table/wood, +/obj/item/food/grown/harebell, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/item/radio/intercom/prison/directional/north, +/obj/item/food/grown/harebell{ + pixel_y = -3; + pixel_x = -2 + }, +/turf/open/floor/iron/dark, +/area/station/security/prison/rec) "wtM" = ( /obj/machinery/door/airlock/external{ dir = 4; @@ -79511,12 +79308,6 @@ }, /turf/open/floor/wood, /area/station/commons/vacant_room/office) -"wug" = ( -/obj/machinery/gulag_item_reclaimer{ - pixel_y = 24 - }, -/turf/open/floor/carpet, -/area/station/security/processing) "wuh" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -79712,9 +79503,6 @@ }, /turf/open/floor/iron, /area/station/command/gateway) -"wxg" = ( -/turf/open/floor/iron/freezer, -/area/mine/laborcamp) "wxl" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/effect/turf_decal/trimline/neutral/line, @@ -79840,13 +79628,13 @@ /obj/effect/turf_decal/siding/wood, /turf/open/floor/wood/large, /area/mine/eva/lower) -"wzn" = ( -/obj/effect/decal/cleanable/dirt, +"wzs" = ( +/obj/machinery/light/small/directional/west, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 4 }, -/turf/open/floor/iron, -/area/mine/laborcamp) +/turf/open/floor/iron/dark, +/area/station/security/prison/rec) "wzv" = ( /obj/machinery/atmospherics/components/tank/air{ dir = 3; @@ -79899,6 +79687,20 @@ /obj/item/folder/yellow, /turf/open/floor/iron, /area/station/cargo/storage) +"wAn" = ( +/obj/structure/cable, +/obj/machinery/door/airlock/external{ + name = "Security External Access"; + security_level = 1 + }, +/obj/effect/mapping_helpers/airlock/access/all/security/brig, +/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{ + cycle_id = "sec-external-upper" + }, +/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/security/eva) "wAv" = ( /obj/structure/chair/comfy/brown{ dir = 1 @@ -79931,19 +79733,6 @@ /obj/machinery/griddle, /turf/open/floor/iron/white/smooth_large, /area/station/service/kitchen) -"wAQ" = ( -/obj/machinery/computer/shuttle/labor/one_way{ - dir = 4 - }, -/turf/open/floor/iron, -/area/mine/laborcamp) -"wAT" = ( -/obj/structure/cable, -/obj/effect/turf_decal/tile/red/half/contrasted, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/station/security/brig/upper) "wAW" = ( /obj/structure/table, /obj/item/knife/kitchen, @@ -79986,10 +79775,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/port/greater) -"wBc" = ( -/obj/machinery/airalarm/directional/north, -/turf/open/floor/iron/showroomfloor, -/area/station/security/processing) "wBk" = ( /obj/machinery/camera/directional/north{ c_tag = "Robotics Lab - North"; @@ -80121,11 +79906,6 @@ /obj/machinery/space_heater, /turf/open/floor/plating, /area/station/maintenance/starboard/upper) -"wDI" = ( -/obj/effect/spawner/random/trash/moisture_trap, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/wood, -/area/station/maintenance/fore) "wDK" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -80157,13 +79937,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/hallway/primary/fore) -"wEp" = ( -/obj/effect/turf_decal/tile/red/half/contrasted{ - dir = 1 - }, -/obj/structure/sign/poster/official/random/directional/north, -/turf/open/floor/iron/dark/textured_edge, -/area/station/security/prison) "wEu" = ( /obj/structure/sign/warning/directional/south, /turf/open/misc/asteroid/snow/icemoon, @@ -80203,6 +79976,10 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/cafeteria, /area/station/commons/dorms/laundry) +"wEO" = ( +/obj/effect/turf_decal/tile/brown/opposingcorners, +/turf/open/floor/iron, +/area/mine/production) "wET" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -80241,6 +80018,13 @@ /obj/effect/mapping_helpers/airlock/access/any/engineering/maintenance/departmental, /turf/open/floor/plating, /area/station/maintenance/port/aft) +"wFs" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/decal/cleanable/dirt, +/obj/structure/sign/nanotrasen/directional/east, +/turf/open/floor/iron, +/area/mine/laborcamp) "wFt" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -80273,6 +80057,14 @@ }, /turf/open/floor/carpet, /area/station/service/library) +"wFR" = ( +/obj/structure/cable, +/obj/effect/spawner/structure/window/hollow/reinforced/middle{ + dir = 4 + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plating, +/area/station/security/prison/rec) "wFX" = ( /obj/machinery/computer/telecomms/server{ dir = 4; @@ -80332,14 +80124,6 @@ }, /turf/open/floor/iron/dark/diagonal, /area/station/engineering/atmos/storage) -"wGW" = ( -/obj/structure/table, -/obj/item/book/manual/wiki/security_space_law, -/obj/item/book/manual/wiki/security_space_law, -/turf/open/floor/iron/dark/textured_half{ - dir = 1 - }, -/area/station/security/office) "wGX" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/cable, @@ -80440,6 +80224,18 @@ /obj/effect/decal/remains/plasma, /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/underground/explored) +"wJh" = ( +/obj/effect/turf_decal/stripes/red/line{ + dir = 5 + }, +/obj/machinery/light/small/red/directional/west, +/obj/machinery/door/poddoor/shutters/window/preopen{ + name = "Firing Range Shutters"; + dir = 1; + id = "firingrangeshuttersoutside" + }, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/surface/outdoors/nospawn) "wJi" = ( /obj/structure/railing{ dir = 4 @@ -80591,6 +80387,13 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/iron, /area/station/command/bridge) +"wLx" = ( +/obj/structure/table, +/obj/item/electropack, +/obj/machinery/power/apc/auto_name/directional/west, +/obj/structure/cable, +/turf/open/floor/iron/dark/textured, +/area/station/security/interrogation) "wLO" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -80721,9 +80524,6 @@ /obj/effect/mapping_helpers/airlock/access/all/medical/general, /turf/open/floor/plating, /area/station/maintenance/aft/greater) -"wNt" = ( -/turf/open/floor/iron/smooth, -/area/station/security/brig/upper) "wND" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 1 @@ -80750,12 +80550,6 @@ /obj/effect/mapping_helpers/mail_sorting/supply/qm_office, /turf/open/floor/iron, /area/station/cargo/office) -"wOc" = ( -/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/textured, -/area/station/security/processing) "wOn" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -80777,6 +80571,11 @@ }, /turf/open/floor/iron, /area/station/service/hydroponics) +"wOv" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/security/prison/rec) "wOy" = ( /obj/effect/turf_decal/tile/blue{ dir = 8 @@ -80812,6 +80611,15 @@ /obj/effect/mapping_helpers/airlock/access/all/science/research, /turf/open/floor/iron, /area/station/science/explab) +"wPa" = ( +/obj/machinery/door/airlock/security{ + name = "Permanent Cell 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/textured, +/area/station/security/prison/safe) "wPd" = ( /obj/structure/cable, /turf/open/floor/iron/white, @@ -80932,18 +80740,6 @@ "wQr" = ( /turf/closed/wall, /area/station/cargo/drone_bay) -"wQu" = ( -/obj/structure/table, -/obj/item/taperecorder{ - pixel_x = -3 - }, -/obj/item/folder/red{ - pixel_x = 3 - }, -/obj/item/reagent_containers/spray/pepper, -/obj/item/assembly/flash, -/turf/open/floor/plating/icemoon, -/area/station/security/execution/education) "wQx" = ( /obj/structure/flora/grass/brown/style_random, /turf/open/misc/asteroid/snow/standard_air, @@ -80998,10 +80794,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/aft/greater) -"wRs" = ( -/obj/structure/extinguisher_cabinet/directional/west, -/turf/open/floor/glass/reinforced, -/area/station/security/lockers) "wRu" = ( /obj/machinery/portable_atmospherics/canister, /obj/machinery/atmospherics/components/unary/portables_connector/visible{ @@ -81025,15 +80817,6 @@ /obj/machinery/recharge_station, /turf/open/floor/plating, /area/station/ai/satellite/service) -"wRK" = ( -/obj/machinery/conveyor{ - dir = 8; - id = "gulag" - }, -/obj/effect/decal/cleanable/dirt, -/obj/structure/plasticflaps, -/turf/open/floor/plating, -/area/mine/laborcamp) "wRM" = ( /obj/effect/turf_decal/siding/wood{ dir = 8 @@ -81044,6 +80827,12 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/freezer, /area/mine/eva/lower) +"wRQ" = ( +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 8 + }, +/turf/open/floor/iron/dark/textured, +/area/station/security/prison) "wRR" = ( /obj/machinery/door/poddoor/shutters/preopen{ dir = 1; @@ -81213,6 +81002,24 @@ /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/plating, /area/station/maintenance/port/fore) +"wUb" = ( +/obj/structure/rack, +/obj/item/storage/toolbox/artistic{ + pixel_x = -1; + pixel_y = 2 + }, +/obj/item/storage/toolbox/crafter{ + pixel_x = 3; + pixel_y = -3 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/sign/painting/large{ + dir = 1 + }, +/turf/open/floor/iron/sepia, +/area/station/security/prison/rec) "wUf" = ( /obj/effect/turf_decal/tile/blue{ dir = 1 @@ -81303,16 +81110,6 @@ /obj/effect/mapping_helpers/airlock/access/all/supply/mining_station, /turf/open/floor/iron/dark/textured_half, /area/station/cargo/warehouse) -"wUO" = ( -/obj/machinery/door/airlock{ - name = "Utility Closet" - }, -/obj/effect/mapping_helpers/airlock/access/all/security/brig, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/plating, -/area/station/security/prison/safe) "wUP" = ( /obj/structure/closet/crate, /turf/open/floor/iron, @@ -81419,6 +81216,10 @@ }, /turf/open/floor/iron/white, /area/station/science/ordnance/office) +"wWk" = ( +/obj/effect/spawner/structure/window/reinforced/tinted, +/turf/open/floor/plating, +/area/mine/laborcamp) "wWo" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment, @@ -81444,10 +81245,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/engineering/storage_shared) -"wWU" = ( -/obj/structure/cable, -/turf/open/floor/iron/showroomfloor, -/area/station/security/processing) "wWY" = ( /obj/effect/turf_decal/bot, /obj/structure/ore_box, @@ -81492,18 +81289,6 @@ /obj/machinery/mining_weather_monitor/directional/north, /turf/open/floor/iron/dark/smooth_large, /area/station/hallway/secondary/entry) -"wYq" = ( -/obj/machinery/door/airlock{ - name = "Perma Overlook Closet" - }, -/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/cyclelink_helper_multi{ - cycle_id = "perma-overlook" - }, -/turf/open/floor/vault, -/area/station/security/prison/rec) "wYt" = ( /obj/structure/cable, /obj/effect/landmark/start/prisoner, @@ -81589,6 +81374,15 @@ /obj/structure/window/spawner/directional/north, /turf/open/floor/iron, /area/station/medical/medbay/aft) +"wZz" = ( +/obj/structure/window/reinforced/spawner/directional/north, +/obj/structure/window/reinforced/spawner/directional/east{ + pixel_y = 0; + pixel_x = 3 + }, +/obj/structure/platform/iron, +/turf/open/floor/iron/dark/textured, +/area/station/security/range) "wZD" = ( /obj/machinery/computer/records/security{ dir = 1 @@ -81641,11 +81435,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) -"xad" = ( -/obj/effect/spawner/structure/window/hollow/reinforced/middle, -/obj/structure/cable, -/turf/open/floor/plating, -/area/station/security/range) "xal" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable, @@ -81819,6 +81608,10 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/engineering/atmos/storage) +"xbD" = ( +/obj/effect/spawner/random/gizmo, +/turf/open/floor/engine, +/area/station/science/explab) "xbV" = ( /obj/structure/ladder, /turf/open/floor/plating/snowed/icemoon, @@ -81861,12 +81654,6 @@ }, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/cmo) -"xcx" = ( -/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/mine/laborcamp/security) "xcy" = ( /obj/effect/spawner/random/vending/colavend, /turf/open/floor/iron, @@ -81960,12 +81747,6 @@ /obj/item/radio/intercom/directional/east, /turf/open/floor/iron, /area/station/hallway/primary/central) -"xdZ" = ( -/obj/effect/turf_decal/siding/wideplating/dark{ - dir = 6 - }, -/turf/open/floor/iron/dark/textured, -/area/station/security/prison/rec) "xee" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/cable, @@ -82347,15 +82128,6 @@ }, /turf/open/floor/iron/dark, /area/station/engineering/transit_tube) -"xiq" = ( -/obj/machinery/computer/security/telescreen/interrogation/directional/north, -/obj/effect/turf_decal/tile/red/anticorner/contrasted{ - dir = 4 - }, -/turf/open/floor/iron/dark/corner{ - dir = 8 - }, -/area/station/security/processing) "xit" = ( /obj/item/book/manual/wiki/security_space_law, /obj/structure/table/wood, @@ -82365,6 +82137,13 @@ /obj/structure/marker_beacon/burgundy, /turf/open/floor/plating/snowed/icemoon, /area/icemoon/underground/explored) +"xiy" = ( +/obj/machinery/door/window/left/directional/west, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/carpet/blue, +/area/station/security/prison/work) "xiC" = ( /obj/structure/table/wood, /obj/effect/spawner/random/food_or_drink/snack, @@ -82427,12 +82206,6 @@ }, /turf/open/floor/iron, /area/station/command/heads_quarters/qm) -"xjO" = ( -/obj/machinery/power/port_gen/pacman{ - anchored = 1 - }, -/turf/open/floor/iron/smooth, -/area/mine/laborcamp/security) "xjP" = ( /obj/machinery/disposal/delivery_chute{ dir = 8 @@ -82471,14 +82244,6 @@ }, /turf/open/floor/iron/smooth, /area/station/commons/storage/mining) -"xkw" = ( -/obj/structure/sign/poster/official/twelve_gauge/directional/north, -/obj/effect/turf_decal/tile/red{ - dir = 1 - }, -/obj/structure/cable, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "xkA" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 8 @@ -82537,6 +82302,14 @@ }, /turf/open/floor/iron, /area/station/service/hydroponics) +"xln" = ( +/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, +/obj/effect/turf_decal/tile/red, +/turf/open/floor/iron, +/area/mine/laborcamp/security) "xlq" = ( /obj/structure/lattice/catwalk, /obj/structure/railing, @@ -82563,24 +82336,6 @@ dir = 1 }, /area/mine/eva/lower) -"xlC" = ( -/obj/structure/table, -/obj/machinery/recharger, -/obj/machinery/power/apc/auto_name/directional/west, -/obj/structure/cable, -/obj/machinery/light/directional/south, -/turf/open/floor/iron/smooth_edge{ - dir = 1 - }, -/area/station/security/lockers) -"xlH" = ( -/obj/effect/mapping_helpers/broken_floor, -/mob/living/basic/mouse/white{ - desc = "This mouse smells faintly of alcohol."; - name = "Mik" - }, -/turf/open/floor/wood, -/area/station/maintenance/fore) "xlN" = ( /obj/machinery/door/poddoor/preopen{ id = "maint2" @@ -82672,12 +82427,6 @@ }, /turf/open/floor/iron, /area/station/cargo/sorting) -"xmO" = ( -/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/fore) "xmQ" = ( /obj/machinery/computer/security/telescreen/entertainment/directional/south, /obj/effect/mapping_helpers/broken_floor, @@ -82697,6 +82446,16 @@ }, /turf/open/floor/iron/white, /area/station/medical/pharmacy) +"xnj" = ( +/obj/machinery/atmospherics/pipe/multiz/scrubbers/visible/layer2{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/multiz/supply/visible/layer4{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/station/maintenance/department/security) "xns" = ( /obj/effect/landmark/start/hangover, /obj/effect/turf_decal/tile/yellow{ @@ -82749,11 +82508,6 @@ }, /turf/open/lava/plasma/ice_moon, /area/icemoon/underground/explored) -"xob" = ( -/obj/effect/spawner/structure/window/hollow/reinforced/middle, -/obj/structure/cable, -/turf/open/floor/plating, -/area/station/engineering/lobby) "xow" = ( /obj/machinery/portable_atmospherics/canister/air, /obj/machinery/firealarm/directional/west, @@ -82938,12 +82692,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/medbay/aft) -"xrf" = ( -/obj/structure/railing, -/obj/structure/cable, -/obj/machinery/door/window/right/directional/south, -/turf/open/floor/plating/icemoon, -/area/station/security/execution/education) "xrg" = ( /obj/machinery/firealarm/directional/east, /obj/structure/closet/secure_closet/engineering_welding, @@ -82976,12 +82724,10 @@ /obj/machinery/newscaster/directional/west, /turf/open/floor/wood, /area/station/service/library) -"xrC" = ( -/obj/effect/turf_decal/siding/wideplating/dark{ - dir = 9 - }, -/turf/open/floor/iron/dark/textured, -/area/station/security/prison/rec) +"xrL" = ( +/obj/item/radio/intercom/directional/north, +/turf/open/floor/iron/smooth, +/area/station/engineering/lobby) "xrS" = ( /obj/structure/ladder, /obj/effect/turf_decal/stripes/box, @@ -83032,6 +82778,12 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/iron, /area/station/cargo/miningdock) +"xtx" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/carpet/blue, +/area/station/security/prison/work) "xtG" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -83098,6 +82850,9 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/science/xenobiology) +"xuz" = ( +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/underground/unexplored/no_rivers) "xuA" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/dark/textured, @@ -83132,6 +82887,19 @@ }, /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/surface/outdoors/less_spawns) +"xuV" = ( +/obj/structure/rack, +/obj/item/poster/random_official, +/obj/item/poster/random_official, +/obj/item/poster/random_official, +/obj/item/poster/random_official, +/obj/item/poster/random_official, +/obj/item/poster/random_official, +/obj/item/poster/random_official, +/obj/item/poster/random_official, +/obj/item/clothing/head/costume/fancy, +/turf/open/floor/iron/dark/textured, +/area/station/security/prison) "xuW" = ( /obj/effect/turf_decal/tile/blue{ dir = 8 @@ -83511,10 +83279,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/port/fore) -"xyS" = ( -/obj/machinery/holopad, -/turf/open/floor/iron, -/area/station/security/processing) "xyT" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/simple/dark/visible{ @@ -83525,11 +83289,6 @@ }, /turf/open/floor/iron, /area/station/maintenance/disposal/incinerator) -"xyU" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/turf/open/floor/iron/showroomfloor, -/area/station/security/prison/mess) "xza" = ( /obj/vehicle/ridden/wheelchair{ dir = 4 @@ -83569,12 +83328,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/hallway/secondary/entry) -"xzp" = ( -/obj/item/kirbyplants/random, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/turf/open/floor/iron, -/area/mine/laborcamp/security) "xzs" = ( /obj/structure/table/reinforced, /obj/item/storage/medkit/regular, @@ -83585,6 +83338,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/port/aft) +"xzN" = ( +/obj/structure/table, +/obj/item/storage/medkit/regular, +/obj/effect/turf_decal/tile/blue/opposingcorners{ + dir = 1 + }, +/obj/machinery/light/small/dim/directional/north, +/turf/open/floor/iron/white, +/area/mine/laborcamp) "xzO" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/spawner/random/maintenance/three, @@ -83684,15 +83446,6 @@ }, /turf/open/floor/iron/dark, /area/station/service/chapel) -"xBv" = ( -/obj/machinery/light/directional/north, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/red/line{ - dir = 1 - }, -/obj/effect/turf_decal/trimline/red/line, -/turf/open/floor/iron/dark/textured, -/area/station/security/range) "xBL" = ( /obj/machinery/camera/directional/north{ c_tag = "Solar Maintenance - North East Access" @@ -83988,6 +83741,20 @@ /obj/machinery/light/directional/east, /turf/open/floor/iron, /area/station/maintenance/disposal/incinerator) +"xFh" = ( +/obj/machinery/door/airlock/external{ + glass = 1; + name = "Labor Camp External Airlock"; + opacity = 0 + }, +/obj/structure/cable, +/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{ + cycle_id = "labour-exit" + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/mine/laborcamp) "xFj" = ( /obj/machinery/door/firedoor{ dir = 8 @@ -84117,6 +83884,19 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos) +"xGN" = ( +/obj/machinery/door/airlock/research/glass{ + name = "Genetics Lab" + }, +/obj/effect/mapping_helpers/airlock/access/all/science/genetics, +/obj/machinery/door/firedoor, +/obj/machinery/door/poddoor/shutters/preopen{ + dir = 8; + id = "gene_desk_shutters"; + name = "Genetics Shutters" + }, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "xGX" = ( /obj/machinery/door/airlock/public/glass{ name = "Trial Transfer" @@ -84201,21 +83981,6 @@ /obj/item/clothing/mask/gas, /turf/open/floor/iron/textured, /area/station/command/eva) -"xIk" = ( -/obj/structure/chair/comfy{ - dir = 4 - }, -/obj/structure/extinguisher_cabinet/directional/west, -/turf/open/floor/carpet, -/area/station/security/processing) -"xIp" = ( -/obj/structure/closet/secure_closet/brig, -/obj/machinery/camera/directional/north{ - c_tag = "Security - Transport" - }, -/obj/machinery/light/directional/north, -/turf/open/floor/iron/showroomfloor, -/area/station/security/processing) "xIF" = ( /obj/machinery/firealarm/directional/south, /turf/open/floor/iron/dark, @@ -84315,10 +84080,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/dark, /area/station/engineering/supermatter/room) -"xJY" = ( -/obj/machinery/firealarm/directional/north, -/turf/open/floor/iron/smooth, -/area/station/engineering/lobby) "xKb" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/window/reinforced/spawner/directional/south, @@ -84361,6 +84122,19 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/starboard/upper) +"xKp" = ( +/obj/effect/turf_decal/tile/red/half/contrasted{ + dir = 8 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, +/obj/machinery/camera/directional/west{ + c_tag = "Security - Escape Pod" + }, +/obj/item/radio/intercom/directional/west, +/turf/open/floor/iron/smooth, +/area/station/security/brig/upper) "xKq" = ( /obj/machinery/seed_extractor, /obj/effect/turf_decal/tile/blue/opposingcorners, @@ -84623,6 +84397,10 @@ }, /turf/open/floor/iron/textured, /area/station/service/hydroponics) +"xPc" = ( +/obj/machinery/portable_atmospherics/canister, +/turf/open/floor/plating, +/area/station/maintenance/fore) "xPs" = ( /obj/effect/mapping_helpers/airlock/access/all/science/general, /obj/effect/mapping_helpers/airlock/cyclelink_helper, @@ -84717,11 +84495,6 @@ }, /turf/open/floor/wood, /area/station/commons/lounge) -"xQm" = ( -/obj/machinery/airalarm/directional/west, -/obj/structure/closet/secure_closet/freezer/fridge/all_access, -/turf/open/floor/iron/showroomfloor, -/area/station/security/prison/mess) "xQs" = ( /obj/effect/turf_decal/tile/red/half/contrasted{ dir = 4 @@ -84737,25 +84510,9 @@ /obj/effect/turf_decal/tile/yellow/opposingcorners, /turf/open/floor/iron/white, /area/station/maintenance/port/fore) -"xQG" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red/half/contrasted, -/turf/open/floor/iron/dark/side{ - dir = 1 - }, -/area/station/security/processing) -"xQK" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 1 - }, -/obj/structure/railing, -/turf/open/floor/iron, -/area/mine/production) +"xQL" = ( +/turf/closed/wall, +/area/station/maintenance/department/security) "xQO" = ( /obj/vehicle/sealed/mecha/ripley/cargo, /obj/effect/decal/cleanable/wrapping, @@ -84791,12 +84548,6 @@ }, /turf/open/floor/iron, /area/station/command/bridge) -"xRP" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/eighties/red, -/area/station/security/prison/safe) "xRZ" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/light/small/directional/east, @@ -84817,13 +84568,6 @@ /obj/machinery/light/small/directional/east, /turf/open/floor/wood, /area/station/commons/vacant_room/office) -"xSn" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 4 - }, -/obj/structure/cable, -/turf/open/floor/iron/smooth, -/area/station/security/brig) "xSx" = ( /obj/structure/closet/secure_closet/chemical, /obj/effect/turf_decal/trimline/blue/filled/line{ @@ -84899,6 +84643,11 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/starboard/upper) +"xTE" = ( +/obj/structure/cable, +/obj/structure/chair/sofa/left/brown, +/turf/open/floor/carpet/blue, +/area/station/security/prison/work) "xTL" = ( /obj/effect/turf_decal/tile/blue, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -85069,6 +84818,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/cafeteria, /area/station/hallway/secondary/exit/departure_lounge) +"xUZ" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/effect/landmark/event_spawn, +/turf/open/floor/iron/smooth, +/area/station/security/brig/upper) "xVc" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -85092,6 +84848,13 @@ /obj/machinery/newscaster/directional/north, /turf/open/floor/wood, /area/station/command/meeting_room) +"xVt" = ( +/obj/structure/table, +/obj/item/plate, +/obj/effect/turf_decal/tile/red, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/security/prison/mess) "xVB" = ( /obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/incinerator_ordmix{ dir = 8 @@ -85137,6 +84900,10 @@ }, /turf/open/floor/wood, /area/station/maintenance/space_hut/cabin) +"xVP" = ( +/obj/machinery/keycard_auth/wall_mounted/directional/east, +/turf/open/floor/iron/dark/smooth_large, +/area/station/command/heads_quarters/hos) "xVT" = ( /obj/structure/railing{ dir = 9 @@ -85222,6 +84989,14 @@ }, /turf/open/floor/iron, /area/station/commons/storage/primary) +"xXb" = ( +/obj/structure/cable, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/mine/laborcamp) "xXd" = ( /obj/effect/turf_decal/tile/blue/opposingcorners{ dir = 1 @@ -85273,20 +85048,22 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos) -"xXQ" = ( -/obj/structure/table, -/obj/effect/decal/cleanable/dirt, -/obj/item/book/manual/chef_recipes{ - pixel_x = 2; - pixel_y = 6 - }, -/turf/open/floor/iron, -/area/mine/laborcamp) "xYg" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) +"xYh" = ( +/obj/machinery/light/small/directional/east, +/obj/structure/cable, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, +/obj/machinery/flasher/directional/east{ + id = "executionflash" + }, +/turf/open/floor/plating, +/area/station/security/execution/education) "xYn" = ( /obj/structure/cable, /obj/effect/turf_decal/siding/yellow, @@ -85367,6 +85144,15 @@ }, /turf/open/floor/iron/dark/smooth_large, /area/station/engineering/main) +"xZu" = ( +/obj/structure/cable, +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 6 + }, +/turf/open/floor/iron/dark/side{ + dir = 6 + }, +/area/mine/laborcamp/security) "xZy" = ( /obj/structure/stairs/east, /obj/effect/turf_decal/trimline/neutral/line, @@ -85378,6 +85164,12 @@ "xZA" = ( /turf/open/floor/iron/checker, /area/station/science/lab) +"xZB" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, +/turf/open/floor/carpet/blue, +/area/station/security/prison/work) "xZS" = ( /obj/effect/spawner/random/trash/moisture_trap, /obj/item/reagent_containers/cup/bucket, @@ -85421,6 +85213,13 @@ /obj/effect/turf_decal/tile/dark_blue/fourcorners, /turf/open/floor/iron/dark/textured, /area/station/hallway/primary/central) +"yaq" = ( +/obj/structure/closet/l3closet/security, +/obj/effect/turf_decal/bot, +/turf/open/floor/iron/smooth_edge{ + dir = 1 + }, +/area/station/security/lockers) "yar" = ( /obj/machinery/door/poddoor/shutters/preopen{ dir = 1; @@ -85490,11 +85289,6 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/disposal) -"yaZ" = ( -/obj/machinery/light/small/directional/west, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, -/turf/open/floor/iron/showroomfloor, -/area/station/security/prison/mess) "yba" = ( /obj/structure/fence/corner{ dir = 2 @@ -85793,6 +85587,15 @@ }, /turf/open/floor/plating/snowed/coldroom, /area/station/service/kitchen/coldroom) +"yfu" = ( +/obj/effect/turf_decal/stripes/red/line{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/plating/snowed/icemoon, +/area/icemoon/surface/outdoors/nospawn) "yfz" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 8 @@ -85804,6 +85607,20 @@ /obj/structure/flora/bush/sparsegrass/style_random, /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/surface/outdoors/nospawn) +"yfJ" = ( +/obj/structure/table/wood, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/item/paper_bin{ + pixel_x = 8; + pixel_y = 3 + }, +/obj/item/stamp/head/hos{ + pixel_x = 10; + pixel_y = 6 + }, +/turf/open/floor/wood/large, +/area/station/command/heads_quarters/hos) "yfW" = ( /obj/structure/fence/post{ dir = 8 @@ -85904,6 +85721,12 @@ /obj/structure/sign/poster/random/directional/north, /turf/open/floor/plating, /area/station/maintenance/aft/lesser) +"yhr" = ( +/obj/structure/fence/door/opened{ + dir = 8 + }, +/turf/open/misc/asteroid/snow/icemoon, +/area/icemoon/surface/outdoors/nospawn) "yhw" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -85931,11 +85754,6 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/iron, /area/station/engineering/atmos) -"yiz" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/light/small/directional/south, -/turf/open/floor/iron/showroomfloor, -/area/station/security/prison/toilet) "yiK" = ( /obj/structure/rack, /obj/item/reagent_containers/cup/bottle/potassium{ @@ -85961,6 +85779,10 @@ /obj/structure/sign/warning/cold_temp/directional/west, /turf/open/floor/plating, /area/station/maintenance/port/aft) +"yiV" = ( +/obj/effect/turf_decal/delivery, +/turf/open/floor/iron, +/area/mine/laborcamp) "yjh" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -86022,18 +85844,24 @@ }, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) -"ykw" = ( -/turf/closed/wall/r_wall, -/area/station/security/processing) "ykA" = ( /obj/structure/cable, /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating, /area/station/maintenance/fore) +"ykE" = ( +/obj/effect/spawner/structure/window/hollow/reinforced/middle, +/obj/structure/cable, +/turf/open/floor/plating, +/area/station/engineering/lobby) "ykG" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, /area/station/commons/locker) +"ykL" = ( +/obj/structure/chair/stool/directional/east, +/turf/open/floor/iron/dark, +/area/station/security/execution/education) "ykM" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -86062,16 +85890,6 @@ /obj/structure/window/reinforced/spawner/directional/west, /turf/open/floor/iron/dark/textured, /area/station/security/prison/workout) -"ylL" = ( -/obj/machinery/flasher/directional/north{ - id = "Cell 3" - }, -/obj/structure/bed{ - dir = 1; - pixel_x = -2 - }, -/turf/open/floor/iron/smooth, -/area/station/security/brig) "ylM" = ( /obj/machinery/light/directional/south, /obj/machinery/atmospherics/pipe/smart/simple/dark/visible{ @@ -86109,16 +85927,6 @@ /obj/item/kirbyplants/organic/plant11, /turf/open/floor/stone, /area/station/service/bar/atrium) -"ymj" = ( -/obj/structure/chair{ - dir = 8 - }, -/obj/effect/turf_decal/tile/purple/half/contrasted{ - dir = 4 - }, -/obj/structure/sign/departments/evac/directional/east, -/turf/open/floor/iron, -/area/station/hallway/primary/starboard) (1,1,1) = {" oSU @@ -98514,7 +98322,7 @@ iDt abB exv iDt -iDt +ebd iDt exv oSU @@ -99025,7 +98833,7 @@ oSU oSU iDt iDt -iDt +ebd iDt ksu iDt @@ -99287,7 +99095,7 @@ qrg iDt iDt exv -iDt +ebd iDt oSU oSU @@ -107520,14 +107328,14 @@ thA thA thA thA +vjh +vjh +vjh +vjh thA thA -thA -thA -thA -thA -ghx -ghx +vjh +etz ghx ghx ghx @@ -107774,17 +107582,17 @@ thA thA thA thA -thA -thA -thA -thA -thA -thA -thA -thA -thA -rfu -etz +vjh +vjh +vjh +vjh +bmE +kyD +vjh +vjh +vjh +vjh +ghx ghx ghx ghx @@ -108031,16 +107839,16 @@ thA thA thA thA -thA -thA -thA -thA -thA -thA -thA -thA -thA -rfu +vjh +kih +bzS +vjh +wWk +hWv +vjh +xzN +msi +vgk ghx ghx ghx @@ -108288,16 +108096,16 @@ thA thA thA thA -thA -thA -thA -thA -thA -thA -thA -thA -thA -rfu +vjh +wWk +lEf +auZ +mRq +kfz +bgn +jem +kot +vgk ghx ghx ghx @@ -108542,20 +108350,20 @@ thA thA thA thA -thA -thA -thA -thA -thA -thA -thA -thA -thA -thA -thA -thA -rfu -rhF +vjh +nTW +nTW +vjh +lgB +oEr +njJ +hDK +fOd +njJ +tGd +pcj +vgk +ghx ghx ghx ghx @@ -108799,24 +108607,24 @@ thA thA thA thA -thA -thA -thA -thA -thA -thA -thA -thA -thA -thA -thA -thA -rfu -lWI -lWI -adD -lWI -ena +mpi +teO +aqA +njJ +njJ +njJ +njJ +dqx +fOd +nTO +nTO +nTO +nTO +rhF +ghx +ghx +ghx +ghx ghx ghx ghx @@ -109056,25 +108864,25 @@ thA thA thA thA -thA -thA -thA -thA -thA -thA -thA -thA -thA -thA -thA -thA -rfu -xuo -xuo -xuo -xuo -oBz -ena +vjh +ckm +qkf +aVt +mXY +pRA +hqo +dqx +fOd +nTO +mRE +omw +jKH +ghx +ghx +ghx +ghx +ghx +ghx ghx ghx ghx @@ -109313,26 +109121,26 @@ thA thA thA thA -thA -thA -thA -thA -thA -thA -thA -thA -thA -thA -thA -thA -rfu -xuo -xuo -xuo -xuo -xuo -oBz -ena +mpi +vlm +dqx +qFU +gWO +jfG +wdX +dqx +rHE +nTO +oBC +xZu +jKH +ghx +ghx +ghx +ghx +ghx +ghx +ghx ghx ghx ghx @@ -109568,29 +109376,29 @@ xMq xMq thA thA -thA -thA -thA -thA -uOb -uOb -uOb -uOb -uOb -uOb -uOb -uOb -uOb -uOb -uOb -rfu -omJ -rfu -kOc -daf -kmH -oBz -ena +vjh +vjh +vjh +vjh +rmz +qkf +oDg +tor +hDK +dqx +fsd +nTO +nTO +vwU +nTO +nTO +nTO +nTO +ghx +ghx +ghx +ghx +ghx ghx ghx ghx @@ -109825,29 +109633,29 @@ xMq xMq thA thA -thA -thA -thA -thA -uOb -nDV -amx -fXO -lBR -nhg -scb -lBR -nhg -mbe -lBR -kIo -hap -rfu -pjj -daf -daf -xuo -oBz +vjh +fyt +eTr +rEX +hSM +qkf +dqx +eOe +oYK +oYK +mgN +nTO +cjZ +jxK +uMV +uuB +rvM +nTO +gfE +lWI +lWI +adD +lWI ena ghx ghx @@ -110082,31 +109890,31 @@ iDt xMq thA thA -thA -thA -thA -thA -uOb -dQT -dQT -yiz -lBR -fZq -lBR -lBR -fZq -lBR -lBR -kZI -hap -rfu -bPV -dFF -dFF +vjh +wmu +vjh +kEe +dqx +wlg +cJO +sri +wWY +iBt +fOd +sup +kWG +bBP +tea +ccO +jST +nTO xuo xuo -xlq -ghx +xuo +xuo +xuo +oBz +ena ghx ghx ghx @@ -110339,32 +110147,32 @@ iDt xMq xMq xMq -thA -thA -thA -thA -uOb -jnX -amx -kHn -lBR -xrC -tcQ -qLi -cur -gQE -nNn -nNn -nNn +vjh +kWp +vjh +sRh +hDK +wlg +wWY +gUx +aHq +gGh +fOd +sup +puM +vGh +hwJ +fWm rfu -ooW -ooW +rfu +rfu +wFR +wFR +wFR rfu jrv -xuo -xlq -ghx -ghx +oBz +ena ghx ghx ghx @@ -110583,8 +110391,8 @@ dhq dhq dhq dhq -dhq -dhq +akp +adA ghx ghx ghx @@ -110596,33 +110404,33 @@ iDt xMq xMq xMq -thA -thA -thA -thA -uOb -dQT -dQT -nHs -lBR -oWe -swk -mbp -fWa -beQ -nNn -hYy -sdE -bAk -mAO +vjh +dHG +fZY +yiV +sZc +qkf +nix +jpn +jrd +lUo +fOd +nTO +uuH +nTO +maK +wOv +rfu +qkv +wzs +poU +mtQ kXY -mJX -xuo -xuo -xlq -ghx -ghx -ghx +qLR +pjj +daf +ahg +ena ghx ghx ghx @@ -110838,49 +110646,49 @@ dhq dhq dhq dhq -dhq -dhq -dhq -dhq -ghx -ghx -ghx -ghx -ghx -ghx -ghx -iDt -iDt -xMq -xMq -thA -thA -thA -thA -uOb -ifZ -amx -ddz -lBR -vzp -fnj -egz -hsr -alA -nNn -alA -roH -foO -bDF -kXY -mJX -xuo -xuo -xlq -ghx +iZz +iZz +akp +adA +fIt +etz ghx ghx ghx +cRt +fIt +fIt +fIt +fIt +vjh +vjh +vjh +vjh +vjh +vjh +kTs +njJ +iIa +iIa +njJ +bMe +nTO +nTO +nTO +mMx +mKL +rfu +rfu +wtE +kUC +ctW +fPe +qLR +pjj +daf +daf +oBz +ena ghx ghx ghx @@ -111095,43 +110903,47 @@ dhq dhq dhq dhq -dhq -dhq -dhq -dhq -ghx -ghx -ghx -ghx -ghx -ghx -ghx -ghx -iDt -iDt -xMq -thA -thA -thA -thA -uOb -dQT -dQT -kXO -lBR -jbb -ibz -mpf -ehZ -bwi -hPk -bwi -vyO -dEz -uDy -kZn -mJX +lAt +iZz +cWw +cWw +lWI +lWI +lWI +lWI +lWI +lWI +lWI +lWI xuo +ivv +nMn +ohV +gpD +vof +nMn +nWx +bir +mZk +lwA +lwA +lvd +dNI +iKn +rGv +dwR +vmY +oET +mzG +rfu +foO +abq +mAO +foO +qLR +bPV +dFF +dFF xuo xlq ghx @@ -111142,10 +110954,6 @@ ghx ghx ghx ghx -ghx -ghx -ghx -ghx thA thA thA @@ -111351,50 +111159,50 @@ dhq dhq dhq dhq -dhq -dhq -dhq -dhq -dhq -dhq -ghx -ghx -ghx -ghx -ghx -ghx -ghx -ghx -iDt -xMq -thA -thA -thA -thA -uOb -aLM -amx -yia -dhS -cTv -vwE -kqh -kqh -ttD -nNn -urm -tKB -foO -bdo -kXY -mJX -xuo +iZz +iZz +iZz +iZz +cWw +cWw +fQR +fQR +fQR +fQR +fQR +fQR +fQR +fQR +wgW +nMn +xXb +wFs +jNn +xFh +pcX +vrY +mgN +dNI +cCa +nhn +dNI +fer +izz +kbX +xln +tyI +pCS +rfu +juA +iWu +juA +juA +rfu +reu xuo +eNw +fSF xlq -raY -ghx -ghx -ghx ghx ghx ghx @@ -111607,51 +111415,51 @@ dhq dhq dhq dhq -dhq -dhq -dhq -dhq -dhq -dhq -dhq -dhq -ghx -ghx -ghx -ghx -ghx -ghx -ghx -ghx +iZz +iZz +mBV +iZz +iZz +iZz +akp +adA fIt -uSb -uSb -uSb +etz +ghx +ghx +ghx +cRt fIt -uOb -uOb -lBR -lBR -lBR -sCa -jRu -uNV -khb -xdZ -nNn -iDu -upY -qna -dEz -gxx +fIt +vjh +nTW +vjh +nTW +vjh +vjh +aes +dqx +aes +vjh +vjh +qoU +qZI +nTO +nTO +glE +mJK +rfu +rfu +mRD +hpn +gjo +juA +rfu rfu kIi rfu rfu -rfu -akn -ghx -ghx +xlq ghx ghx ghx @@ -111864,14 +111672,14 @@ dhq dhq dhq dhq -dhq -dhq -dhq -dhq -dhq -dhq -dhq -dhq +iZz +mBV +nxP +iZz +mBV +iZz +akp +adA ghx ghx ghx @@ -111880,35 +111688,35 @@ ghx ghx ghx ghx -iDt -iDt -iDt -tWK -tWK -tWK -xhK -tnD -jGg -vVH -gkN -ogL +xuo +xuo +sDH +xuo +xuo +vjh +aes +nUS +iLR +vjh +jli +kPG jZI -aHw -vVH -vVH -vVH -vVH +xuV +xhK +xhK +xhK +xhK +tDM +mRD +hpn +wnH +fdz nNn -gzV -nNn -nNn -evP -bVs -dgx +uww +hap +bcH mJX -ghx -ghx -ghx +xlq ghx ghx ghx @@ -112122,11 +111930,11 @@ dhq dhq dhq dhq -dhq -dhq -dhq -dhq -dhq +iZz +iZz +iZz +iZz +iZz dhq dhq dhq @@ -112142,30 +111950,30 @@ ghx iDt iDt iDt -tWK -xby -dSm -hMS -vVH -nGo -wPg +vjh +vjh +vjh +vjh +vjh +gkN +qPD fHg -mkb -vVH +nGo +xhK fps usS -vVH -keD -kqR -qSu -wYq -nkP -kry +xhK +oaa +foO +abq +foO +foO +gQc +icJ +rXO uRi mJX -ghx -ghx -ghx +xlq ghx ghx ghx @@ -112381,8 +112189,8 @@ dhq dhq dhq dhq -dhq -dhq +iZz +iZz dhq dhq dhq @@ -112397,13 +112205,13 @@ ghx ghx ghx iDt +xxV iDt iDt -iDt -xby -byq -tIS -tlS +uOb +rEQ +nhg +uVH npL wPg nAv @@ -112411,18 +112219,18 @@ yjh eJU dFX nbm -vVH -vUs -kqR -hjQ +xhK +gCO +iGn +irU +wtf +gxb nNn -eCg -aJu +sjx +dLj ong mJX -ghx -ghx -ghx +xlq ghx ghx ghx @@ -112654,30 +112462,30 @@ ghx ghx ghx iDt -iDt -iDt +ijY +pfw scw -xhK -vVH -vVH -vVH -dWn +uOb +lBR +lBR +lBR +dId wPg fHg -bol -vVH -vVH -vVH -vVH -dHb -kqR -ugd +gjs +xhK +xhK +xhK +xhK +nNn +vBA +nNn nNn ldH ldH ldH -dbH -dbH +upP +ldH dbH ghx ghx @@ -112914,27 +112722,27 @@ ghx iDt iDt scw -xhK -taV -kZh -vVH -bub +uOb +vMO +nhg +uVH +bol wPg fHg hnt -vVH +xhK fps usS -vVH -gwy -ixw -kqR -gzV -xUG -kcC -puc -kGP -sEC +xhK +mVr +hhE +oPa +nNn +ajl +siT +gdE +hLH +qgd dbH akn ghx @@ -113171,28 +112979,28 @@ ghx ghx eZz uOs -xhK -nGd -swf -vVH -jli +uOb +lBR +lBR +lBR +lBR wPg aDJ yjh eTv dFX nbm -vVH -akZ -pdx -uma +xhK +aDL +hhE +flz nNn -fTb -cgb -nwF -nwF -kFN -ots +kWu +eAv +uvI +hwf +vGb +ecp ghx ghx ghx @@ -113200,7 +113008,7 @@ ghx ghx ghx ghx -pJm +aDG iDt thA thA @@ -113428,28 +113236,28 @@ ghx ghx iDt fgN -xhK -ikb -swf -vVH -iVN +uOb +nDV +amx +eVh +lBR wPg oCd tVf -tVf -tVf -ldH -ldH -ldH -ldH -ldH -ldH -eMG -iKw -iZs -sOT -rCE -ots +mMM +mMM +rfu +rfu +lbP +hhE +hhE +vBA +fTb +vrG +cgb +nwF +kFN +ecp ghx ghx ghx @@ -113457,7 +113265,7 @@ ghx ghx ghx ghx -pJm +rcY iDt thA thA @@ -113685,28 +113493,28 @@ ghx ghx ghx fIt -xhK -vVH -wUO -vVH -vVH +uOb +dQT +dQT +ffN +lBR dZW fHg ayS aze lsn -ldH -xQm -yaZ -dNH -xyU -wlY -fTb -eQA +nNn +wUb +lph +hhE +flz +nNn +mWL +vrG +iKw xWA -rHH -bZK -ots +rCE +ecp ghx ghx ghx @@ -113942,28 +113750,28 @@ ghx ghx ghx ghx -xby -nXj -xRP -nId -myQ +uOb +jnX +amx +ddz +lBR fQG fHg aEY oad gAV -ldH -qiJ -qTs -vPt -hfv -ldH -pEX +nNn +hhE +gzB +oTp +nRM +nNn +fTb +vrG bta lpY -lpY kse -ots +ecp ghx ghx ghx @@ -114199,28 +114007,28 @@ ghx ghx ghx ghx -xby -lFe -rvj -bSo -vVH +uOb +dQT +dQT +kXO +lBR gZP mbZ tVf tVf tVf -ldH -ldH -ttk -ldH -ldH -ldH -vCn -jdf -tuH -jdf -fhU -ots +nNn +vBA +nNn +nNn +nNn +nNn +nnt +syR +mOa +syR +uMX +ecp ghx ghx ghx @@ -114456,28 +114264,28 @@ ghx ghx ghx ghx -xby -sJi -pvJ -gaS -vVH +uOb +ifZ +amx +yia +dhS fQG lsN iLy eDg oGB sKu -rAR -jZI +cMY +cIn oUM +lmE nFn -jQE fTb vrG -vrG cgb +nwF kFN -ots +ecp ghx ghx ghx @@ -114713,11 +114521,11 @@ ghx ghx ghx ghx -xhK -vVH -vVH -vVH -vVH +uOb +lBR +lBR +lBR +lBR nef oZz oZz @@ -114731,10 +114539,10 @@ xUG mpn bfg bfg -vrG -sOT -vkJ -ots +oAS +aDf +xVt +ecp ghx ghx ghx @@ -114973,23 +114781,23 @@ axF dcw sKT sSl -etw -lXJ +nks +ceI xbv vRP vRP vRP vRP -qSb +dnr ylA krN ldH mXK ueP -bZK +vCe gOS -fhF -vSK +rjm +sGu kse dbH akn @@ -115229,7 +115037,7 @@ ghx ghx dcw fGI -qLX +taP nks cfh nLW @@ -115238,10 +115046,10 @@ iZo czW gSy vPx -qDG -bDj +bsv +cSC ldH -fTo +sXy fVJ kzx kFx @@ -115485,8 +115293,8 @@ ghx ghx ghx dcw -cpp -gTW +gSy +pLp xDK cfh wBp @@ -115494,9 +115302,9 @@ knq cBG loP nAD -cYv -cmD -cmD +ckC +vPx +vPx ldH pyr lkS @@ -115751,14 +115559,14 @@ hhr iZo ajG gSy -rLX -kLo -wnm +xQL +xQL +xQL ldH gNP pBb gbu -kHL +gfR dbH psb psb @@ -115972,10 +115780,10 @@ dhq dhq dhq dhq -iZz -iZz -iZz -iZz +dhq +dhq +dhq +dhq dhq dhq dhq @@ -116000,22 +115808,22 @@ ghx ghx dcw fGI -gTW -cPQ +cRx +agc cfh -wBp +bpv gvj xNY xtG xtG -vyw -bdJ -fPY +fWW +gQS +hRB ldH opI -daE -nub -hCv +uzA +suk +vmz ots ghx ghx @@ -116227,23 +116035,23 @@ dhq dhq dhq dhq -iZz -iZz -iDt -iDt -scw -iDt -scw -scw -iDt -scw -scw -scw -iDt -scw -scw -iDt -fIt +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq tvk ghx ghx @@ -116256,22 +116064,22 @@ ghx ghx ghx dcw -cdp -hBF +uWk +frf owf bkX sBw uDk bht iUw -wlR -sbJ -vyw -fuX +bCr +xQL +gMJ +xnj ldH sJe wKC -pYa +psz gcZ ots ghx @@ -116483,24 +116291,24 @@ dhq dhq dhq dhq -iZz -iZz -iZz -scw -scw -scw -scw -scw -scw -iDt -scw -scw -scw -scw -scw -scw -scw -iwV +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq ghx ghx ghx @@ -116521,13 +116329,13 @@ jmI jmI jmI jmI -uPk -vsp -qwa -qts +dbH ldH -fwL -wKC +ldH +ldH +ldH +daE +sEY kDu vXn ots @@ -116740,24 +116548,24 @@ dhq dhq dhq dhq -iZz -iZz -iZz -scw -scw -scw -iDt -scw -iDt -iDt -iDt -scw -iDt -iDt -iDt -iDt -iDt -gem +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq ghx ghx ghx @@ -116778,12 +116586,12 @@ thA thA thA thA -uPk -jYj -uAE -eni -dbH dbH +qxg +ecI +qnI +ldH +lOW dbH dbH dbH @@ -116995,26 +116803,26 @@ dhq dhq dhq dhq -iZz -iZz -iZz -iZz -iZz -scw -iDt -scw -scw -iDt -iDt -scw -scw -iDt -iDt -scw -scw -scw -scw -iwV +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq ghx ghx ghx @@ -117035,13 +116843,13 @@ thA thA thA thA -uPk -xBv -uAE -swc -uPk -scw -iDt +dbH +gYy +qnI +qnI +qnI +qnI +dbH iDt ghx ghx @@ -117251,27 +117059,27 @@ dhq dhq dhq dhq -iZz -iZz -iZz -iZz -iZz -iZz -iDt -iDt -scw -iDt -iDt -scw -iDt -scw -scw -iDt -scw -scw -scw -iDt -iwV +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq ghx ghx ghx @@ -117292,14 +117100,14 @@ thA thA thA thA -uPk -gHF -eki -jlX -xad -scw -cfS -ghx +dbH +pUl +hfz +gbt +hXL +dbH +dbH +etz ghx ghx ghx @@ -117508,27 +117316,27 @@ dhq dhq dhq dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq iZz iZz -iZz -iZz -iZz -iZz -scw -iDt -scw -iDt -scw -scw -jBn -iDt -iDt -scw -scw -scw -scw -scw -iwV ghx ghx ghx @@ -117537,7 +117345,7 @@ ghx ghx ghx ghx -iDt +ghx iDt xMq xMq @@ -117549,13 +117357,13 @@ thA thA thA thA -uPk -fsp -icS -efx -xad -scw -iDt +dbH +dbH +dbH +dbH +dbH +dbH +cfS ghx ghx ghx @@ -117765,27 +117573,27 @@ dhq dhq dhq dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq iZz iZz -iZz -iZz -fKw -iZz -iDt -iDt -scw -scw -scw -iDt -iDt -scw -scw -scw -scw -scw -iDt -scw -iwV ghx ghx ghx @@ -117806,11 +117614,11 @@ thA thA thA thA -uPk -lmf -fnW -lTa -xad +thA +thA +thA +thA +iDt scw ghx ghx @@ -118022,27 +117830,27 @@ dhq dhq dhq dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq iZz iZz iZz -iZz -iZz -iZz -scw -iDt -scw -scw -scw -scw -iDt -scw -scw -scw -scw -iDt -scw -iDt -iwV ghx ghx ghx @@ -118050,7 +117858,7 @@ ghx ghx ghx ghx -iDt +ghx iDt iDt xMq @@ -118063,11 +117871,11 @@ thA thA thA thA -uPk -eqS -pFZ -lFL -xad +thA +thA +thA +thA +iDt scw ghx ghx @@ -118279,35 +118087,35 @@ dhq dhq dhq dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq iZz iZz +sRC iZz -iZz -fKw -iZz -scw -scw -iDt -iDt -scw -iDt -scw -scw -scw -scw -scw -scw -iDt -scw -gem ghx ghx ghx ghx ghx -iDt -iDt -iDt +ghx +ghx +ghx iDt iDt xMq @@ -118320,12 +118128,12 @@ thA thA thA thA -uPk -oXd -bJp -qdl -uPk -ltH +thA +thA +thA +thA +iDt +scw ghx ghx ghx @@ -118536,34 +118344,34 @@ dhq dhq dhq dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq iZz iZz iZz iZz -fKw -iZz -iDt -scw -iDt -scw -iDt -iDt -iDt -scw -scw -scw -scw -scw -iDt -iDt -iwV ghx ghx ghx ghx ghx -iDt -iDt +ghx +ghx iDt iDt iDt @@ -118577,12 +118385,12 @@ thA thA thA thA -uPk -uPk -uPk -uPk -uPk -etz +thA +thA +thA +iDt +iDt +ghx ghx ghx ghx @@ -118793,36 +118601,36 @@ dhq dhq dhq dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq iZz iZz iZz iZz -iZz -iZz -vjh -dLN -dLN -dLN -dLN -vjh -aRm -vjh -vjh -vjh -uPl -vjh -hMv -qxN -fIt -tvk +ghx +ghx +ghx +ghx ghx ghx ghx ghx iDt -iDt -iDt -iDt +ebd iDt xMq xMq @@ -119050,33 +118858,33 @@ dhq dhq dhq dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq iZz iZz iZz -fKw -fKw -iZz -vjh -dqx -oDg -oDg -dqx -njJ -lDD -njJ -wAQ -njJ -kcf -vjh -scw ghx ghx ghx ghx ghx ghx -iDt -iDt +ghx +ghx iDt iDt iDt @@ -119307,24 +119115,27 @@ dhq dhq dhq dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq iZz iZz -iZz -iZz -iZz -iZz -vjh -szu -hdV -jLo -bJx -njJ -ciN -njJ -rTV -njJ -blk -vjh +ghx +ghx +ghx ghx ghx ghx @@ -119334,10 +119145,7 @@ ghx iDt iDt iDt -iDt -iDt -iDt -iDt +pfw iDt xMq xMq @@ -119564,37 +119372,37 @@ dhq dhq dhq dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq iZz iZz -iZz -dLN -dLN -dLN -vjh -cJb -cpG -han -dqx -njJ -cVD -njJ -hpl -dqx -dqx -vjh -nTO -nTO -nTO -eQT -nTO -eQT -eQT -eQT -nTO -kXf +ghx +ghx +ghx +ghx +ghx +ghx +ghx +ghx iDt iDt iDt +jAv +iDt iDt iDt xMq @@ -119820,39 +119628,39 @@ dhq dhq dhq dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq iZz iZz -iZz -fKw -dLN -wxg -ipd -njJ -dqx -dqx -pfO -dqx -vDy -hDK -rwR -hDK -wzn -qtH -vjh -sLa -vwG -uno -pDy -nTO -kAG -pdc -xzp -iSf -faV +ghx +ghx +ghx +ghx +ghx +ghx +ghx +ghx iDt iDt iDt iDt +ijY +iDt iDt iDt iDt @@ -120076,38 +119884,38 @@ dhq dhq dhq dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq iZz iZz iZz -fKw -oIv -vjh -pRZ -uYj -dUG -rQx -rQx -rVX -rVX -rVX -rVX -rVX -kfz -kfz -rVX -aGW -rAr -xcx -jvM -ifa -nTO -okl -tmB -jvM -nTO -nTO -nTO -fqG +ghx +ghx +ghx +ghx +ghx +ghx +ghx +ghx +iDt +ebd +iDt +iDt iDt iDt iDt @@ -120331,39 +120139,39 @@ dhq dhq dhq dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq iZz iZz iZz -iZz -iZz -fKw -lxY -vjh -aYQ -bLL -njJ -kqs -dqx -rVX -dqx -kbx -dLR -xXQ -usx -qUw -qUw -vjh -xkw -cqz -tmB -dlq -nTO -lRE -tmB -jvM -sJR -tmB -kCH +ghx +ghx +ghx +ghx +ghx +ghx +ghx +ghx +iDt +iDt +xxV iDt iDt iDt @@ -120587,41 +120395,41 @@ dhq dhq dhq dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq iZz iZz -iZz -iZz -iZz -dLN -dLN -dLN -vjh -njJ -njJ -njJ -njJ -bEi -rVX -dqx -qJC -pzx -bqz -tXM -vjh -vjh -vjh -fEX -cqz -ccx -voL -fcY -pdc -lMC -aWV -nTO -nTO -nTO -kXf +ghx +ghx +ghx +ghx +ghx +ghx +ghx +ghx +ghx +iDt +iDt +iDt +iDt iDt iDt xMq @@ -120844,43 +120652,43 @@ dhq dhq dhq dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq iZz iZz iZz -iZz -fKw -dLN -bml -msi -njJ -pDI -wdX -wzn -njJ -mZJ -rVX -dqx -twV -hVB -npH -gqh -vjh -pDW -fLT -ivq -bAM -bAM -bAM -mcr -bAM -bAM -bAM -bAM -cRE -eQT +ghx +ghx +ghx +ghx +ghx +ghx +ghx +ghx iDt iDt iDt +iDt +ebd +iDt +iDt xMq thA thA @@ -121101,40 +120909,40 @@ dhq dhq dhq dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq iZz iZz iZz -iZz -fKw -dLN -uCk -tAL -njJ -mPp -jlG -rQx -duS -lmK -rVX -fez -rqR -maM -aWo -ddK -vjh -drP -czD -kwU -tmB -pXB -eSr -fcY -tmB -tmB -tmB -bAM -rmv -eQT +ghx +ghx +ghx +ghx +ghx +ghx +ghx +ghx +iDt +iDt +iDt +iDt iDt iDt iDt @@ -121358,42 +121166,42 @@ dhq dhq dhq dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq iZz iZz iZz -iZz -fKw -dLN -sWo -kmA -njJ -kRd -mXl -njJ -njJ -njJ -klX -njJ -njJ -njJ -njJ -njJ -vjh -nTO -nTO -piD -cdd -tmB -kSv -nTO -nTO -nTO -nTO -iGj -nTO -nTO -nTO -mbJ +ghx +ghx +ghx +ghx +ghx +ghx +ghx +ghx +ghx +iDt +iDt +iDt +iDt +iDt +iDt xMq xMq thA @@ -121615,41 +121423,41 @@ dhq dhq dhq dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq iZz +lAt iZz -iZz -fKw -iZz -vjh -sWo -njJ -njJ -njJ -njJ -njJ -rCe -njJ -pnG -cWH -njJ -bsd -lOP -dLN ghx ghx -eQT -fXy -bvj -pJY -iav -nTO +ghx +ghx +ghx +ghx +ghx +ghx ghx iDt -nTO -ody -hMJ -vbg -nTO +iDt +iDt +iDt +iDt iDt xMq xMq @@ -121871,42 +121679,42 @@ dhq dhq dhq dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq iZz iZz iZz -iZz -fKw -myW -vjh -sWo -njJ -sPA -sPA -sPA -njJ -mTI -sTO -rVX -rQx -jXY -rQx -vux -dLN ghx ghx -eQT -eQT -eQT -eQT -eQT -nTO -akn +ghx +ghx +ghx +ghx +ghx +ghx +ghx +iDt +iDt +iDt +iDt iDt -nTO -kJw -mQq -jyL -nTO iDt xMq xMq @@ -122128,27 +121936,28 @@ dhq dhq dhq dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq iZz iZz -iZz -iZz -iZz -myW -vjh -mYi -njJ -bDI -dqx -dqx -njJ -njJ -njJ -oLj -dqx -njJ -njJ -njJ -vjh ghx ghx ghx @@ -122159,11 +121968,10 @@ ghx ghx ghx iDt -nTO -auw -eYC -xjO -nTO +iDt +iDt +iDt +iDt iDt xMq xMq @@ -122385,27 +122193,28 @@ dhq dhq dhq dhq -iZz -iZz -iZz -bqf -vjh -vjh -vjh -nZC -eQH -hDK -dqx -dqx -dqx -rXg -njJ -uTo -cCG -njJ -rKs -hLk -dLN +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq ghx ghx ghx @@ -122416,12 +122225,11 @@ ghx ghx ghx iDt -nTO -cpe -cpe -nTO -nTO -mbJ +iDt +iDt +iDt +pfw +iDt xMq xMq thA @@ -122642,27 +122450,28 @@ dhq dhq dhq dhq -iZz -iZz -fKw -fKw -aqa -oDB -nhT -kYw -avP -gUx -gUx -wWY -mZk -bJx -njJ -rVX -rQx -gXy -lmK -vux -dLN +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +ghx ghx ghx ghx @@ -122673,10 +122482,9 @@ ghx ghx ghx iDt -nTO -krC -krC -nTO +iDt +iDt +iDt iDt iDt xMq @@ -122899,27 +122707,28 @@ dhq dhq dhq dhq -iZz -iZz -iZz -bqf -vjh -vjh -vjh -eFu -dRk -dRk -rvy -oie -rQx -rQx -jZi -rVX -dqx -njJ -njJ -njJ -vjh +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +ghx ghx ghx ghx @@ -122930,11 +122739,10 @@ ghx ghx ghx iDt -nTO -nTO -nTO -nTO -mbJ +iDt +pfw +iDt +iDt iDt xMq xMq @@ -123156,27 +122964,28 @@ dhq dhq dhq dhq -iZz -iZz -iZz -iZz -mbq -dLN -hlE -dqx -kSU -dqx -dqx -dqx -kpH -dqx -njJ -isc -mEb -njJ -bsd -fBs -dLN +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +ghx ghx ghx ghx @@ -123189,8 +122998,7 @@ ghx iDt iDt iDt -iDt -iDt +jAv iDt iDt xMq @@ -123414,26 +123222,26 @@ dhq dhq dhq dhq -iZz -mBV -iZz -fKw -dLN -dqx -dqx -aGr -dqx -jEs -dqx -hDK -kaO -njJ -fWo -rQx -oSa -rQx -vux -dLN +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq ghx ghx ghx @@ -123448,7 +123256,7 @@ iDt iDt iDt iDt -iDt +jAv iDt iDt xMq @@ -123671,26 +123479,26 @@ dhq dhq dhq dhq -iZz -iZz -nxP -iZz -dLN -rbT -mts -njJ -njJ -gHg -njJ -njJ -wRK -vjh -oCo -dFR -vjh -vjh -vjh -vjh +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq etz ghx ghx @@ -123702,11 +123510,11 @@ ghx ghx iDt iDt +xxV iDt +ebd iDt -iDt -iDt -iDt +ijY iDt xMq thA @@ -123928,25 +123736,25 @@ dhq dhq dhq dhq -iZz -iZz -mBV -iZz -dLN -rbT -lLN -vRO -ggV -eYz -tGP -tGP -iRp -vjh -jmc -qDD -dLN -uqX -adA +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq etz ghx ghx @@ -123962,7 +123770,7 @@ iDt iDt iDt iDt -iDt +xxV iDt iDt xMq @@ -124185,25 +123993,25 @@ dhq dhq dhq dhq -iZz -iZz -iZz -iZz -dLN -dLN -dLN -vjh -vjh -vjh -vjh -vjh -vjh -vjh -dLN -dLN -dLN -fKw -mzl +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq ghx ghx ghx @@ -124215,9 +124023,9 @@ ghx ghx ghx iDt +ebd iDt -iDt -iDt +xxV iDt iDt iDt @@ -124442,25 +124250,25 @@ dhq dhq dhq dhq -iZz -iZz -iZz -iZz -fKw -iZz -iZz -iZz -iZz -oGJ -iZz -iZz -iZz -iZz -iZz -fKw -fKw -iZz -mzl +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq ghx ghx ghx @@ -124699,25 +124507,25 @@ dhq dhq dhq dhq -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -mzl +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq ghx ghx ghx @@ -124956,25 +124764,25 @@ dhq dhq dhq dhq -iZz -iZz dhq -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -mzl +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq ghx ghx ghx @@ -125217,21 +125025,21 @@ dhq dhq dhq dhq -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -mzl +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq ghx ghx ghx @@ -125474,21 +125282,21 @@ dhq dhq dhq dhq -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -iZz -mzl +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq +dhq ghx ghx ghx @@ -125737,15 +125545,15 @@ dhq dhq dhq dhq -iZz -iZz -iZz -iZz -iZz dhq dhq dhq -adA +dhq +dhq +dhq +dhq +dhq +dhq etz ghx ghx @@ -130622,7 +130430,7 @@ dhq dhq dhq iZz -iZz +sRC ghx ghx ghx @@ -169808,9 +169616,9 @@ sht gOU gjq eJf -gjq -gjq -gjq +eJf +eJf +eJf gjq gjq gjq @@ -170064,9 +169872,9 @@ cMk wmR cMk cMk -eJf -eJf -eJf +bie +cMk +cMk faL eJf eJf @@ -170317,13 +170125,13 @@ kZu bKE vpc kZu -aYM -tDa +aFb +tif sWU +jLq +sea +tbv cMk -cMk -gjq -gjq eJf gjq gjq @@ -170575,12 +170383,12 @@ bDC kZu kZu fxY -pql -qkI -coY +tZc +ore +bzX +lds +tcO cMk -gjq -gjq eJf gjq gjq @@ -170832,12 +170640,12 @@ uQl ajr uQx vQy -ngl -xQK -brX -cMk -gjq -gjq +qAz +asd +dNE +dxS +ddD +uvM eJf gjq iDt @@ -171088,13 +170896,13 @@ tDa tDa tDa sWB -tDa -pql -rnl -gko -uvM -gjq -gjq +uCX +oBp +dbh +lRb +qbB +wEO +cMk gnh iDt iDt @@ -171346,9 +171154,9 @@ lYd jCV kZu jrQ -qud -uYF -jXH +gFc +uNb +imq nWH hFL hFL @@ -171602,10 +171410,10 @@ aIW nWH nWH nWH -mHe -sPE -ceF -dTF +ngE +kNB +hgi +ePD nWH qeP fde @@ -174607,10 +174415,10 @@ jNf jNf jNf jNf -xhK -kXf -iDt -iDt +dAZ +dAZ +kcM +kcM wUj lpS qdY @@ -174860,14 +174668,14 @@ iRV npL wuH npL -bol -omP -fYQ -uso -xhK -iDt -iDt -iDt +wws +nXV +jGC +rIH +ukN +nCs +bZk +uQm wUj gOi vuk @@ -175115,16 +174923,16 @@ jhH cIc sDQ oVY -bXI -vVH -vVH -vVH -nYZ -uoi -xhK -iDt -ijY -pfw +lnF +hQl +oiP +dAZ +fxP +nKL +hpF +uHv +bKK +dcD wUj pYn jeJ @@ -175373,15 +175181,15 @@ cIc uTp oVY pez -oOg -qLg -vVH -vVH -vVH -xhK +tVf +tVf dAZ -kcM -kcM +jmA +lWb +eDq +bZk +pSE +bcy ntl hwu hwu @@ -175630,15 +175438,15 @@ cIc kqn oVY pez -anQ -aQQ -fdm -eIg -rIH +tVf +rWs +dAZ +lPe +brJ ukN -nCs +uHv lWb -hmA +gNV dAZ vOw eGW @@ -175886,17 +175694,17 @@ ilZ sws bpX oVY -oCU -vVH -vVH -vVH -ivw +pez +gAR +acf +dAZ +dSJ nKL hpF uHv -bZk -gAu -sUb +toU +dTg +cDN eCE eCE eCE @@ -176143,16 +175951,16 @@ jty cIc nUL oVY -bLc -diN -diN -lgK -vlH -lWb +pez +tVf +sru +dAZ +wrw +qqd eDq -tDY -pSE -izY +fbp +bZk +oef eND qpB qpB @@ -176398,19 +176206,19 @@ iHV iHV qTI cIc -kqn +llS oVY -ruC -wws -wws -nXV -icQ -brJ -ukN -uHv -lWb -kEn -dAZ +hEs +tVf +mMM +lyg +lyg +lyg +lyg +lyg +qZU +jzv +lyg dKy dKy lyg @@ -176653,29 +176461,29 @@ hPs jhj pzu sRQ -una +xiy cIc kAW oVY -nyP -tVf -gAR -lgK -dSJ -nKL -hpF -uHv -toU -pCp -dAZ -eRp -qKS +pez +diN +mMM +dan +dan +eOY +sBX +leV +sBX +oww +lyg +fdD +ihS dUO -fWQ -kkB +fdD +esm dUO -ylL -sSO +fdD +ayv lyg gjq gjq @@ -176909,30 +176717,30 @@ iDt oqL fnF gBc -erY -clR +xZB +xtx cIc uTp oVY pez -tVf -izn -lgK -wrw -qqd -eDq -iXh -lWb -upB -dAZ -wqI -xSn +diN +mMM +dan +dan +dan +riy +leV +buG +aSa +lyg +kSN +bBt dUO -wqI -xSn +kSN +bBt dUO -wqI -xSn +kSN +bBt lyg gjq gjq @@ -177164,10 +176972,10 @@ iDt iDt iDt oqL -lEa -boO -pdT -klv +xTE +vme +rwA +bHR cIc kqn oVY @@ -177179,9 +176987,9 @@ yiL yiL yiL yiL -eDq -ejb -dAZ +qZU +btV +lyg emM wob dUO @@ -177423,8 +177231,8 @@ ebd hPs gBX hPs -cIc -cIc +ixN +rHT cIc dHw qhS @@ -177438,7 +177246,7 @@ uBs xaH erM nDp -uFg +pXw lgD nDp mtS @@ -177679,11 +177487,11 @@ iDt iDt iDt iDt -xby -olV -mcF -qjE -oZR +xhK +xhK +xhK +xhK +kqn oVY pez yiL @@ -177695,7 +177503,7 @@ pPK yiL gwl rQZ -bSk +gGV uQC nSk bcm @@ -177937,8 +177745,8 @@ xMq iDt iDt xhK -eTb -mDo +fps +usS vVH nUL oVY @@ -178193,13 +178001,13 @@ xMq xMq fIt nbB -xhK -vVH -vVH -vVH -kqn +heL +vbo +ebF +imY +lwK oVY -pez +uhU yiL vDx cxO @@ -178451,14 +178259,14 @@ xMq cek iDt xhK -taV -qfs -vVH +xhK +xhK +xhK fKW oVY vHU yiL -oAY +udj cxO pgL lab @@ -178708,15 +178516,15 @@ gjq cek iDt xhK -nCQ -swf -vVH -kqn +fps +usS +xhK +uTp oVY pez yiL agF -gJI +uqZ rGh iJE qnU @@ -178737,11 +178545,11 @@ gjq gjq gjq cwr -mvv +iUg mqR dTr gjS -dUW +sOW gKQ thA thA @@ -178964,11 +178772,11 @@ gjq gjq fIt nbB -xhK -oAP -oua -vVH -uTp +heL +vbo +ebF +wPa +lwK oVY tjC yiL @@ -179222,12 +179030,12 @@ gjq gjq gjq xhK -oyH -swf -vVH -uVC +xhK +xhK +xhK +tnF oVY -tGJ +iuW tVf mzH gAn @@ -179479,12 +179287,12 @@ gjq gjq gjq xhK -vVH -fkV -vVH -wEp +rNG +iVs +rNG +kqn oVY -nMZ +qde tVf wJi rME @@ -179738,7 +179546,7 @@ gjq upw uzM iRV -cvq +wRQ xgL oVY bWh @@ -180013,7 +179821,7 @@ hBg nzj rjd pOk -par +cVR rsM xby gjq @@ -180266,7 +180074,7 @@ pdz eic mLT dha -nzl +bLl vpi uME xhK @@ -180519,17 +180327,17 @@ gTw gTw gTw mMM -xhK -qJY -xhK +aVg +ejJ +aVg pNm -tpH -uIC pNm -ovP -ovP -ovP -ovP +nFj +pNm +oVE +nDc +pNm +xuz gjq gjq gjq @@ -180776,17 +180584,17 @@ wRa wRa wRa wRa -vVH -ulz -ulz +xQL +fBz +kkd pNm -oPn -wnv -pNm -ovP -ovP -ovP -ovP +kre +qQQ +oGM +woo +mAQ +uzN +xuz gjq gjq gjq @@ -181033,17 +180841,17 @@ wRa wRa wRa wRa -vVH -dbL -ulz +xQL +mzR +kkd pNm -eUB -bQS -pNm -ovP -ovP -ovP -ovP +iOe +qQQ +bXc +gWe +ykL +uzN +xuz gjq gjq gjq @@ -181287,21 +181095,21 @@ wRa wRa wRa wRa -wRa -vVH -vVH -vVH -hBB -ulz +nyV +xQL +xQL +xQL +vIE +fBz pNm uKW -bBx +nFj +pNm +fsK +fsK pNm pNm -pNm -pNm -pNm -gjq +fhL gjq gjq gjq @@ -181544,16 +181352,16 @@ wRa wRa wRa wRa -wRa -vVH -tOE -ulz -ulz -ulz +nJE +xQL +aAk +kkd +fBz +kkd pNm -cLp -fdG -saX +pSN +qRM +goP gjq gjq gjq @@ -181801,17 +181609,17 @@ wSZ wRa wRa wRa -wRa -vVH -kUt -pKR -ejX -fjG +tjA +xQL +mXX +fAa +rYn +cYF pNm -wQu -fdG -lPb -sJt +pGU +vDC +atH +jKr jKr jKr gjq @@ -182059,15 +181867,15 @@ mMM mMM mMM mMM -xhK -xhK -xhK -phK -qoY +aVg +aVg +aVg +sOS +qeI pNm -iEN -paL -xrf +pSN +xYh +mkj gjq lzx gjq @@ -182318,9 +182126,9 @@ ovP ovP ovP ovP -xhK -xhK -xhK +aVg +aVg +aVg pNm fsK pNm @@ -182329,7 +182137,7 @@ pNm pNm pNm pNm -gjq +fhL gjq gjq gjq @@ -182404,7 +182212,7 @@ xMq bID qhL iEQ -xob +ykE gjq eJf gjq @@ -182661,7 +182469,7 @@ iDt bID iWW thq -xob +ykE gjq eJf gjq @@ -182916,8 +182724,8 @@ thA iDt scw bID -gfV -lpQ +lmp +pnF bID bID bID @@ -183088,8 +182896,8 @@ ovP ovP ovP ovP -ovP -ovP +gFX +iXc ovP ovP ovP @@ -183173,7 +182981,7 @@ thA thA ppY bID -cqa +xrL jJI tiJ uSA @@ -183343,11 +183151,11 @@ ovP ovP ovP ovP +iDt +scw +scw ovP ovP -gFX -iXc -ovP ovP ovP ovP @@ -183430,7 +183238,7 @@ thA thA iDt bID -coc +mCF jJI eEn bCy @@ -183439,8 +183247,8 @@ iub iub dOb oWy -nPr -tfC +koa +hXg oxD aEz vJm @@ -183600,9 +183408,9 @@ ovP ovP ovP ovP -iDt -scw -scw +ovP +ovP +ovP ovP ovP ovP @@ -183690,14 +183498,14 @@ bID bID jJI qrt -lco -bec -prm -bec +qkP +jAA +lNx +jAA gzL jsw nYl -jPf +kOP twu wJW oWy @@ -183945,13 +183753,13 @@ iDt iDt ppY bID -lbF +vop bID -xJY +vct iWW muJ -cDt -hfo +tmt +vAJ oWy qtu gTx @@ -185118,12 +184926,12 @@ ovP ovP ovP xMq -xMq -xMq -xMq -xMq -xMq -xMq +gjq +gjq +gjq +gjq +gjq +gjq xMq xMq ovP @@ -185375,12 +185183,12 @@ ovP ovP ovP xMq -xMq -xMq -xMq -xMq -xMq -xMq +gjq +gjq +gjq +gjq +gjq +gjq xMq xMq ovP @@ -185632,12 +185440,12 @@ ovP ovP ovP xMq -xMq -xMq -xMq -xMq -xMq -xMq +gjq +gjq +gjq +gjq +gjq +gjq xMq ovP ovP @@ -185888,13 +185696,13 @@ ovP ovP ovP ovP -ovP -ovP -ovP -ovP -ovP -ovP -ovP +xMq +gjq +gjq +gjq +gjq +gjq +gjq ovP ovP ovP @@ -186146,12 +185954,12 @@ ovP ovP ovP ovP -ovP -ovP -ovP -ovP -ovP -ovP +gjq +gjq +gjq +gjq +gjq +gjq ovP ovP ovP @@ -186403,12 +186211,12 @@ ovP ovP ovP ovP -ovP -ovP -ovP -ovP -ovP -ovP +gjq +gjq +gjq +gjq +gjq +gjq ovP ovP ovP @@ -186660,12 +186468,12 @@ ovP ovP ovP ovP -ovP -ovP -ovP -ovP -ovP -ovP +gjq +gjq +gjq +gjq +gjq +gjq ovP ovP ovP @@ -186916,13 +186724,13 @@ ovP ovP ovP ovP -ovP -ovP -ovP -xMq -xMq -xMq xMq +gjq +gjq +gjq +gjq +gjq +gjq xMq ovP ovP @@ -187172,14 +186980,14 @@ ovP ovP ovP ovP -ovP -ovP -ovP -xMq -xMq -xMq xMq gjq +gjq +gjq +gjq +gjq +gjq +gjq xMq ovP ovP @@ -187429,14 +187237,14 @@ ovP ovP ovP ovP -ovP -ovP -xMq -xMq -xMq -xMq xMq gjq +gjq +gjq +gjq +gjq +gjq +gjq xMq ovP ovP @@ -187687,10 +187495,10 @@ ovP ovP ovP xMq -xMq -xMq -xMq -xMq +gjq +gjq +gjq +gjq gjq gjq gjq @@ -188522,7 +188330,7 @@ kmo hWl kmo jUi -oqu +ibJ jre jre jre @@ -188778,7 +188586,7 @@ pbF tdc sHa ccL -jaU +eLB jre jre jDV @@ -190867,7 +190675,7 @@ vEJ wGX oQY hrZ -evv +wsF jUB jUB xDb @@ -237050,8 +236858,8 @@ txl txl txl utC -utC hMQ +utC tkU utC utC @@ -237307,10 +237115,10 @@ aBR aBR tGr tGr -tGr umh jZo jZo +mwB jZo jZo umh @@ -241167,8 +240975,8 @@ bln ntK bln bln -jSf -xgm +kCb +bln bln bln lSu @@ -241418,11 +241226,11 @@ tGr tGr mZf vwC -pby -bln +ddC bln +nXZ tGr -tGr +jVy bln jSf lBD @@ -241675,11 +241483,11 @@ tGr tGr tGr bln -bln -lSu -tGr -tGr -tGr +bDu +bDu +bDu +bDu +bDu tGr umh kSw @@ -241925,7 +241733,7 @@ txl txl aBR aBR -aBR +tGr tGr tGr tGr @@ -241933,9 +241741,9 @@ tGr tGr bDu bDu +yaq bDu -bDu -bDu +vvz bDu bDu xAs @@ -241949,10 +241757,10 @@ bln lSu cuq itE -lSu +lxD cuq itE -lSu +lxD cuq itE rzG @@ -242182,18 +241990,18 @@ txl txl txl aBR -aBR -aBR -tGr -tGr tGr tGr +vri +vri +vri +vri bDu -vKk -hwR -igB -wRs -xlC +erU +mAe +joP +qdZ +utw bDu dvl cuq @@ -242440,17 +242248,17 @@ txl txl txl aBR -aBR -aBR -tGr -tGr tGr +vri +sWJ +fch +vix bDu -jgG +bkO mAe jJM mAe -dfz +iCI dnX bln abb @@ -242697,17 +242505,17 @@ txl txl txl txl -aBR -aBR -aBR -tGr tGr +vri +vri +bbq +myc bDu -nGU +oAO mAe jJM mAe -dfz +eNX feJ feJ awd @@ -242954,17 +242762,17 @@ txl txl txl txl -txl -aBR -aBR -aBR -lbc +tGr +vri +mDN +fMk +rCK bDu -jgG +vjm mAe jJM mAe -stt +urP qVB eeD aSH @@ -243210,20 +243018,20 @@ txl txl txl txl -txl -aBR -aBR -aBR -aBR -lbc +vri +vri +vri +vri +uhN +vYf bDu -cFb -mAe +feL +kUq jgs mAe -uVP -aWk -diC +ses +oGW +nuH bJj lyG teq @@ -243467,21 +243275,21 @@ txl txl txl txl -txl -aBR -aBR -aBR -aBR -lbc -bDu -qdF -cno +vri +vaH +tfi +vri +hYN +mvn +iie +nmk +nIt oSC ovV -hkY +vqu feJ -pyG -pdK +qFM +qDu lyG apS uCs @@ -243536,7 +243344,7 @@ hue hBZ eYT lLr -tZF +oMP iYb txI xvZ @@ -243724,17 +243532,17 @@ txl txl txl txl -aBR -aBR -aBR -aBR -aBR -lbc +vri +olZ +mvn +wAn +mvn +aLN bDu hGH -qkL -cLD -qkL +mtA +tBW +mtA hGH feJ iuS @@ -243981,23 +243789,23 @@ txl txl txl txl -aBR -aBR -aBR -aBR -aBR -lbc +vri +lHx +itH +reR +vLw +akb nbp lIt -hdn +qNA ijj -nbw -lRF +ijj +vFN feJ mgZ tDL lyG -lok +hoX nGK feJ mex @@ -244238,11 +244046,11 @@ txl txl txl aBR -aBR -aBR -bln -aBR -aBR +vri +reR +iYo +vri +vri nbp nbp hjX @@ -244254,7 +244062,7 @@ feJ feJ cqW wHe -aPW +dHD hsN feJ uGr @@ -244496,22 +244304,22 @@ txl aBR aBR aBR -aBR -bln -bln -aBR +mZf +ooL +uWY +iLb nbp mhx jeF -egm +fIE axd -wGW +vjo tJN -ikI +osN feJ feJ gPn -fLs +feJ feJ feJ uGr @@ -244756,23 +244564,23 @@ aBR bln lBD bln -aBR +kTJ nbp xKY omk -sMY +gSj wMV qqM wMi xaJ -arA -jwx +fzB +ciW kfy -aZo -jwx -wfp -cZm -hLf +sKs +bQg +mEK +fSL +bRG okx mLu lAL @@ -245017,18 +244825,18 @@ lBD nbp mhx jeF -lkb -arb +noz +agR mwh xlx oSm jQB eqI +pNH eqI eqI eqI -eqI -piv +gyK bkC kyy daq @@ -245270,7 +245078,7 @@ lBD bln bln bln -lBD +hIR nbp nbp ezs @@ -245278,12 +245086,12 @@ jeF omk jeF nQf -pCE -arA +dfn +fzB rYB +qYS rgC -she -sYG +hSi rgC sGp kNQ @@ -245292,7 +245100,7 @@ kyy bKN kyy iDq -rpT +bQq ygM mfH sDl @@ -245542,12 +245350,12 @@ mgU mgU mgU mgU -vAm +cAC hAO -jwx +hnM kOk nlp -dNt +faa mfH uJX nCi @@ -245793,17 +245601,17 @@ lQc lQc nbp mgU -bvX +muL ccF -fad +jsN azx tDw rhf cAC cEL -hwZ +pTl vdf -xFm +eSo riv xHq ccr @@ -245837,7 +245645,7 @@ wmK rcj utR tmQ -eOw +aAw rns mkA nOH @@ -246048,9 +245856,9 @@ lBD bln npb bln -lSu hIO rPP +ePr eNl vbF mcH @@ -246058,7 +245866,7 @@ xyx eDM xFm tGB -nCh +iKx fwh ijU bqG @@ -246305,22 +246113,22 @@ bln bln npb bln -bln hIO vyd ePr -kGc +kKO +yfJ kWh -qVJ +nVH mgU kqc kqc kqc -jct +kfu jaw xwf aPd -hQP +tAl lWg ncB bgN @@ -246562,19 +246370,19 @@ bln bln miY oot -oot hIO -jDt -wtg +bzG +rzN +hYQ diq -uet -ptr +xVP +fsP mgU -fUj +fXY kcc -tpX +nMo oIC -jjt +nRm bvY jNp jNp @@ -246819,23 +246627,23 @@ bln bln npb bln -bln hIO hIO -hIO -bUx -bUx -bUx -bUx +oHJ +pqs +aVg +aVg +aVg +aVg kpX jmy xMn cAC -nRm +jjt bRG -hfA -idv -ahA +eXx +ttE +oek cHY sDl sDl @@ -247076,21 +246884,21 @@ bln bln lbc bln -bln lBD -bln -lSu -bUx -jOQ -bxQ -bUx -oty +hIO +hIO +hIO +aVg +rYn +hRB +aVg +wmn vxc aKt tDk jjt lUw -iWS +lMI vwt gII cHY @@ -247151,7 +246959,7 @@ dnq iuv yas xVK -jbh +cYJ eUW bmu cvS @@ -247337,18 +247145,18 @@ bln bln bln bln -bUx -xmO -ubE -bUx +aVg +bLw +ruf +aVg iQj uZW rud cAC mWM -scu -pmr -qPp +bRG +lGX +jYm ryG cHY sDl @@ -247592,21 +247400,21 @@ npb bln bln bln +bln tGr -tGr -bUx -xmO -deY -bUx +aVg +bLw +gre +aVg kdT -ruP +uZW syN -cAC -mWM +azd +kHt bRG -kpj -fGq -eig +vhS +sfs +kwI jNp jbe sDl @@ -247851,21 +247659,21 @@ tGr tGr tGr tGr -bUx -hJe -xmO -bUx -kzw -kzw -kzw +aVg +rKp +bLw +aVg +kqc +kqc +kqc cAC xAQ iMg jNp +dtN jNp jNp -jNp -pVL +sDl sDl sDl sDl @@ -248104,25 +247912,25 @@ lBD bln mlS bln -xAs -nXb -nXb -nXb -ykw -eyb -gck -ykw -sLj -vhL -law -eqI -ewM -wAT -kdy -taj -vsL -vpn -lRc +ulQ +mfH +sQB +sQB +sQB +mfH +pIl +mfH +rOp +oSG +sQB +qDb +iTa +qDb +jNp +sFV +bvh +jNp +sDl sDl sDl sDl @@ -248364,22 +248172,22 @@ bln bln bln bln +bln sEB -ykw -nEs -wOc -lEj -cKv -nsL -eyb -hAQ -ksC -loy -psY -lmM -oyL -kbm -lRc +mfH +ppZ +xKp +hrA +kHl +sQB +cAC +vAz +mbs +jNp +jNp +jNp +jNp +sDl sDl sDl sDl @@ -248617,26 +248425,26 @@ tGr tGr bln lSu +bln xiI mBh oot oot kei -pDC -clq -qgO -qgO -bqx -xQG -ykw +knB +oaM +dns +xUZ +oaM +eDL +tDk +qeo +aLy mfH -cIY -mfH -mfH -lHL -fAH -aAl -lRc +fsm +bln +sDl +sDl sDl sDl sDl @@ -248878,23 +248686,23 @@ bln bln bln bln +bln sEB -ykw -dtz -lEj -fCW -nUg -dKP -ykw -tSi -kfc -dcX mfH -nmq -kqG -pVL -pVL -jbe +tnR +dfl +fjb +vRQ +sQB +qrz +vAz +dZz +lbk +bln +sDl +sDl +sDl +sDl sDl sDl skl @@ -249132,30 +248940,30 @@ bln lBD bln bln -bln -bln -mvl -mvl -mvl -mvl -mvl -kkl -nUg -qOP -ykw -nOQ -cqx +ulQ +mfH +sQB +sQB sQB mfH -pVL -pVL -pVL +mfH +mfH +mfH +mfH +sQB +aoa +vAz +bRG +lbk +bln +sDl +sDl sDl sDl tOq tOq skl -wDI +gBT jOQ skl eFW @@ -249391,28 +249199,28 @@ bln bln bln lBD -tCR -lGK -jRP -bLd -wbG -kkl -dhU -xQG -olY -hQi -rRM -mFQ -lbk bln -sDl -sDl -sDl +bln +tCR +rZP +wLx +aBx +oOT +joD +kkl +hIQ +sZM +qQS +pVL +lRc +lRc +pVL +bUx sDl tOq -bLq -bLq -bLq +mfQ +eeP +lnH jOQ skl dxh @@ -249642,34 +249450,34 @@ aBR aBR aBR aBR -aBR +tGr bln bln uer bln bln +bln +lBD tCR gWX gWX -bEf -iME +bSB +wrY +lnz tsH -qhP -xQG -ykw -pDB -wNt -pXk -lbk -sDl -sDl -skl -skl -skl -skl +adT +ufK +dZL +hjq +pzU +lFM +fXi +bUx +bUx +bUx nTK tnP -cIK +iIf jOQ skl ddr @@ -249898,35 +249706,35 @@ txl aBR aBR aBR -aBR -aBR +tGr +tGr bln bln bln lBD bln +bln +mQb tCR -nKR -aaw -nsO -eWB +qiH +sLe +twz kkl -rEP -xQG -ykw -jpE -gnL -lbk -lbk -sDl -sDl -skl -vaW -deY -skl +kkl +kkl +cAC +sZM +jOq +nuE +uNL +ccm +ntA +bUx +xPc +bUx gDz -xlH -kbN +rfC +wre nzn skl ygB @@ -250154,36 +249962,36 @@ txl txl txl aBR -aBR -aBR -aBR +tGr +tGr +tGr bln bln bln bln +ntK bln +dqc tCR dcx -ihb -bnM -iRM -kkl -xiq -gUs -ykw -lbk -lbk -lbk -bln -sDl -bln +gVr +cLu +oxJ +rfJ +sZy +eSf +tDk +opR +pVL +lHa +fGr +uMF bUx pnU -fhz -skl -jVb +bUx tnP -kki +tDT +ljj jOQ skl dnk @@ -250409,36 +250217,36 @@ txl txl txl txl -txl -aBR -aBR -aBR -aBR -bln -bln -lBD -bln -ykw -mvl -kkl -kkl -kkl -kkl -kkl -eyb -rTX -ykw -bln -bln -bln -bln -bln -bln +tGr +tGr +tGr +uPk +uPk +uPk +kdS +xFn +sfM +kdS +kdS +uPk +uPk +uPk +uPk +uPk +uPk +uPk +qdP +ojE +vAz +tDk +klU +hLb +qWP +dYY +bUx +dYO +bUx bUx -tOq -ous -skl -skl skl skl ykA @@ -250666,35 +250474,35 @@ txl txl txl txl -txl -txl -aBR -aBR -aBR -aBR -aBR -aBR -aBR -ykw -ftA -unC -cLB -arT -eyb -rdw -xIk -bYF -ykw +tGr +tGr +tGr +uPk +aXF +qnv +toN +hrE +hrE +hrE +hrE +wJh +iJu +hXe +fFg +roG +iPd +qEF +ksC +gjy +qeo +gRw +pVL +jfY +spD bUx bUx -bUx -bln -bln -fsm -bUx -buR -kVe -fnS +ayz +mhN skl hir kAT @@ -250923,35 +250731,35 @@ txl txl txl txl -txl -txl -aBR -aBR -aBR -aBR -aBR -aBR -aBR -ykw -wBc -kYI -vyh -ufm -eyb -wug -uLF -nSH -hqi -dKA -deY +tGr +tGr +tGr +fPc +lkp +jsI +uLS +sEB +sEB +sEB +sEB +hCK +oyV +hXe +pap +jdB +cRB +uPk +rgP +bUx +gDg bUx bUx +wae +wae bUx -bUx -bUx -oBV -aXq -fnS +cnk +oPs +iAp skl bVx idP @@ -251180,35 +250988,35 @@ txl txl txl txl -txl -txl -aBR -aBR -aBR -aBR -aBR -aBR -aBR -ykw -xIp -kYI -kYI -bOg -hFC -xyS -fhu -bLI -ykw -skl -ugA +tGr +tGr +bln +mlE +pop +oNl +bkY +rjx +rjx +rjx +rjx +fzk +wZz +hNs +fFg +tBn +nte +uPk +dKA +bUx +hVt deY -skl -kQE -rab +gbT +jlk +fGA skl skl skl -hDV +khY skl byP ugA @@ -251437,27 +251245,27 @@ txl txl txl txl -txl -txl -txl -txl -txl -txl -txl -txl -txl -ykw -lHu -tIf -tIf -blT -ntq -cWG -ekW -vRN -fEA -uHF -wjj +tGr +tGr +tGr +fPc +aXF +tOp +toN +eHv +eHv +eHv +eHv +oDL +iJu +hXe +fFg +huf +bKU +fxw +gWU +gWU +dtI wjj qdK eqq @@ -251694,33 +251502,33 @@ txl txl txl txl -txl -txl -txl -txl -txl -txl -txl -txl -txl -ykw -kON -rax -wWU -esS -evw -aML -iLv -hSJ -ykw +tGr +tGr +tGr +fPc +lkp +jsI +uLS +sEB +sEB +sEB +sEB +hCK +nXW +hXe +hKr +jdB +jTr +uPk ygL -jTw -ugA -eym -ugA +kQE +rab +iyp +aef +deY aBK fhz -ugA +cSu fhz vjg byP @@ -251952,29 +251760,29 @@ txl txl txl txl -txl -txl -txl -txl -txl -txl -txl -txl -ykw -uFf -pwo -uFf -ykw -uFf -nOb -uFf -ykw -ykw -rFP +tGr +tGr +uPk +iEd +fBY +bkY +rjx +yfu +yfu +rjx +mML +iJu +hXe +fFg +eSQ +jMJ +uPk +skl rFP rFP skl skl +skl wYS tYF skl @@ -252209,28 +252017,28 @@ txl txl txl txl -txl -txl -txl -txl -txl -txl -txl -txl -txl -uFf -bJE -uFf -utC -uFf -bJE -uFf -utC -dHF -utC -utC -dHF -utC +tGr +tGr +uPk +uPk +uPk +kdS +kdS +yhr +kdS +xFn +uPk +uPk +uPk +uPk +uPk +uPk +uPk +lBD +bln +bln +lBD +bln skl dow skl @@ -252467,27 +252275,27 @@ txl txl txl txl -txl -txl -txl -txl -txl -txl -txl -txl -uFf -pMg -uFf -utC -uFf -rXX -uFf -utC -utC -tkU -tUm -tkU -utC +tGr +tGr +tGr +tGr +tGr +bln +bln +bln +bln +qXY +bln +bln +bln +dNT +mQb +bln +bln +mQb +ntK +mQb +bln skl eZW deY @@ -252724,13 +252532,19 @@ txl txl txl txl -txl -txl -txl -txl -txl -txl -txl +tGr +tGr +tGr +tGr +tGr +tGr +bln +bln +uer +stJ +bln +bln +uer bln bln bln @@ -252738,13 +252552,7 @@ bln bln bln bln -bln -bln -bln -bln -bln -utC -vfr +stJ skl sNL skl @@ -252990,6 +252798,11 @@ txl bln bln bln +fsm +bln +bln +bln +mQb bln bln bln @@ -252997,11 +252810,6 @@ bln bln bln bln -bln -bln -bln -utC -utC oUb vbG skl @@ -253244,6 +253052,8 @@ txl txl txl txl +mQb +bln bln bln bln @@ -253257,8 +253067,6 @@ bln bln bln bln -utC -utC utC utC skl @@ -253312,7 +253120,7 @@ cTV bOp lwQ qfi -cus +nvw eHg ahL wVw @@ -253503,6 +253311,7 @@ txl txl bln bln +lBD bln bln bln @@ -253510,12 +253319,11 @@ bln bln bln bln +mQb bln bln +fsm bln -bln -wNO -utC fri utC skl @@ -253762,17 +253570,17 @@ bln bln bln bln +uer +bln +mQb bln bln -bln -bMz +mQb +uer bln bln bln bln -bln -utC -utC vfr utC qtD @@ -254017,6 +253825,7 @@ txl txl txl bln +mQb bln bln bln @@ -254024,6 +253833,7 @@ bln bln bln bln +mQb bln bln bln @@ -254031,8 +253841,6 @@ bln utC utC utC -utC -utC bxS lWG lWG @@ -254284,9 +254092,9 @@ bln bln bln bln -utC -utC -utC +bln +bln +bln utC pUa pUa @@ -254533,7 +254341,7 @@ txl txl utC utC -utC +tkU utC txl txl @@ -254591,7 +254399,7 @@ pKb eTM vkG teZ -tgF +sEt vWm pbW sco @@ -254603,7 +254411,7 @@ dgl evp rEG iEA -iBZ +vMt oyB mcp rpM @@ -255105,7 +254913,7 @@ mJM obG dEf mFl -lCh +bRY iAO niu pZm @@ -255368,14 +255176,14 @@ hDq pZm lwQ gkX -beT +akI aTZ fle pyu oul wRG rsR -bAE +dkM oio kQM upO @@ -255697,7 +255505,7 @@ rlS qaP rlS cfe -mXi +aYl rlS mRI bLz @@ -256903,7 +256711,7 @@ vBG dkg tLp eLn -jOw +miM lQG oxU pxX @@ -258207,11 +258015,11 @@ uKj dDw cyr qgu -haX +ikS vds uhG liz -hsb +vFZ mFE nEc klk @@ -264129,7 +263937,7 @@ tIq tZw bdQ nsZ -pnK +itu cSw cmx yeC @@ -265380,12 +265188,12 @@ jbG nzV cYE dfB -ymj +glj pFg -hXC +sMx qad -kuV -cAi +iLD +jKM qWn dik fOR @@ -265641,14 +265449,14 @@ qPL elw elw elw -pqo -ftJ +rcF +xGN mEJ -jTG +gew mEJ ecw mEJ -jTG +gew mEJ mEJ krY @@ -265898,12 +265706,12 @@ kCs omh peV elw -oOc -nvY +gXF +nOR qpu vZV gGx -jxc +ewf aFt vZV aCO @@ -266164,7 +265972,7 @@ eSJ pUy dNw spg -sca +lsV xiC ciS bUa @@ -266413,15 +266221,15 @@ omh wuC elw vav -mlO +iQt cCu crn tgB kKv fhb -vAP +gTh bsN -sca +lsV gpj oQn nWj @@ -266673,7 +266481,7 @@ elw elw elw elw -ouX +oiN ero itj vAP @@ -266958,7 +266766,7 @@ xLq nsZ rDZ rDZ -rDZ +xbD swa rDZ rDZ @@ -267444,7 +267252,7 @@ gOP omh sHM elw -jqw +jSO axN qvE nhI @@ -267701,7 +267509,7 @@ icV omh sHM elw -bCd +naR elw elw elw diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 069b83e7e13..0f4d1903578 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -297,11 +297,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron/white, /area/station/science/research) -"agc" = ( -/obj/effect/turf_decal/bot, -/mob/living/simple_animal/bot/secbot/beepsky/armsky, -/turf/open/floor/iron/dark, -/area/station/security/armory) "agi" = ( /obj/effect/spawner/random/maintenance, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -322,13 +317,6 @@ /obj/structure/window/spawner/directional/north, /turf/open/floor/iron/dark, /area/station/engineering/atmos) -"agA" = ( -/obj/effect/turf_decal/tile/blue/anticorner/contrasted{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/white/corner, -/area/station/medical/medbay/lobby) "agN" = ( /obj/structure/table/glass, /obj/item/radio/intercom/directional/west, @@ -509,6 +497,11 @@ /obj/machinery/vending/drugs, /turf/open/floor/iron/dark, /area/station/medical/medbay/central) +"ajN" = ( +/obj/effect/turf_decal/tile/purple/fourcorners, +/obj/effect/turf_decal/bot, +/turf/open/floor/iron, +/area/station/hallway/primary/aft) "akb" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -598,6 +591,24 @@ /obj/structure/window/reinforced/spawner/directional/south, /turf/open/floor/circuit, /area/station/ai/upload/chamber) +"akG" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/medical/glass{ + id_tag = "MedbayFoyer"; + name = "Medbay" + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/mapping_helpers/airlock/access/all/medical/general, +/obj/effect/turf_decal/tile/blue/fourcorners, +/obj/effect/mapping_helpers/airlock/unres/delayed{ + dir = 8 + }, +/turf/open/floor/iron/white, +/area/station/medical/medbay/central) "akZ" = ( /obj/machinery/atmospherics/pipe/smart/simple/dark/visible{ dir = 4 @@ -725,11 +736,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/fore) -"amF" = ( -/obj/machinery/atmospherics/pipe/smart/simple/yellow/visible, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/white, -/area/station/science/ordnance/storage) "amP" = ( /obj/structure/cable, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -1084,13 +1090,6 @@ }, /turf/open/floor/plating, /area/station/hallway/secondary/entry) -"auL" = ( -/obj/effect/turf_decal/trimline/blue/filled/line{ - dir = 4 - }, -/obj/structure/sink/directional/west, -/turf/open/floor/iron/white, -/area/station/medical/surgery/theatre) "ava" = ( /obj/effect/spawner/random/structure/closet_maintenance, /obj/item/storage/box/lights/mixed, @@ -1648,18 +1647,6 @@ /obj/effect/turf_decal/tile/red/opposingcorners, /turf/open/floor/iron, /area/station/security/checkpoint/science) -"aFc" = ( -/obj/machinery/door/window/right/directional/west{ - name = "Surgical Supplies"; - req_access = list("surgery") - }, -/obj/structure/table/reinforced, -/obj/item/stack/medical/wrap/sticky_tape/surgical, -/obj/item/stack/medical/bone_gel, -/obj/effect/turf_decal/tile/blue/fourcorners, -/obj/structure/window/reinforced/spawner/directional/north, -/turf/open/floor/iron/white, -/area/station/medical/surgery/theatre) "aFd" = ( /obj/effect/landmark/start/shaft_miner, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -2165,6 +2152,14 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron, /area/station/security/brig) +"aNa" = ( +/obj/effect/landmark/event_spawn, +/obj/effect/turf_decal/trimline/blue/filled/warning{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron/white, +/area/station/medical/medbay/lobby) "aNe" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -2173,6 +2168,12 @@ }, /turf/open/floor/iron/dark, /area/station/command/bridge) +"aNf" = ( +/obj/effect/turf_decal/trimline/blue/filled/warning{ + dir = 8 + }, +/turf/open/floor/iron/white, +/area/station/medical/medbay/lobby) "aNu" = ( /obj/structure/bed, /obj/item/clothing/suit/jacket/straight_jacket, @@ -2193,6 +2194,10 @@ /obj/effect/turf_decal/tile/blue, /turf/open/floor/iron/dark, /area/station/command/bridge) +"aNL" = ( +/obj/structure/sign/directions/evac, +/turf/closed/wall/r_wall, +/area/station/maintenance/aft/lesser) "aNN" = ( /obj/machinery/airalarm/directional/south, /obj/machinery/disposal/bin, @@ -2207,6 +2212,18 @@ /obj/effect/mapping_helpers/airalarm/tlv_kitchen, /turf/open/floor/iron/cafeteria, /area/station/service/kitchen) +"aNQ" = ( +/obj/structure/table, +/obj/item/stack/medical/wrap/gauze, +/obj/item/stack/medical/mesh, +/obj/item/stack/medical/suture, +/obj/machinery/power/apc/auto_name/directional/north, +/obj/structure/cable, +/obj/effect/turf_decal/tile/blue/half/contrasted{ + dir = 1 + }, +/turf/open/floor/iron/white, +/area/station/medical/medbay/lobby) "aNZ" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable, @@ -2253,6 +2270,20 @@ /obj/item/paper/fluff/holodeck/disclaimer, /turf/open/floor/iron, /area/station/commons/fitness/recreation) +"aOx" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Primary Treatment Centre" + }, +/obj/machinery/door/firedoor, +/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/medical/general, +/obj/effect/turf_decal/tile/blue/fourcorners, +/obj/effect/mapping_helpers/airlock/unres/delayed{ + dir = 8 + }, +/turf/open/floor/iron/white, +/area/station/medical/treatment_center) "aOA" = ( /obj/effect/landmark/blobstart, /obj/effect/turf_decal/stripes/line{ @@ -2379,6 +2410,21 @@ /obj/structure/window/reinforced/spawner/directional/north, /turf/open/floor/iron/dark, /area/station/ai/satellite/exterior) +"aQJ" = ( +/obj/structure/table/glass, +/obj/effect/turf_decal/tile/blue/fourcorners, +/obj/item/tgui_book/manual/dsm{ + pixel_y = 3; + pixel_x = -2 + }, +/obj/machinery/newscaster/directional/west, +/obj/item/tgui_book/manual/idc{ + pixel_y = 3; + pixel_x = 3 + }, +/obj/item/book/manual/wiki/medicine, +/turf/open/floor/iron/white, +/area/station/medical/treatment_center) "aQR" = ( /obj/structure/lattice/catwalk, /obj/structure/cable, @@ -2484,21 +2530,6 @@ }, /turf/open/floor/wood/large, /area/station/command/heads_quarters/qm) -"aSy" = ( -/obj/machinery/door/firedoor, -/obj/structure/cable, -/obj/machinery/duct, -/obj/machinery/door/airlock/medical/glass{ - name = "Cryogenics Bay" - }, -/obj/structure/disposalpipe/segment, -/obj/effect/mapping_helpers/airlock/access/all/medical/general, -/obj/effect/turf_decal/tile/blue/fourcorners, -/obj/effect/mapping_helpers/airlock/unres/delayed{ - dir = 1 - }, -/turf/open/floor/iron/white, -/area/station/medical/treatment_center) "aSQ" = ( /obj/structure/table/reinforced, /obj/item/book/manual/wiki/security_space_law{ @@ -3723,12 +3754,6 @@ }, /turf/open/floor/iron/dark, /area/station/ai/satellite/chamber) -"bnH" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/tile/blue/fourcorners, -/turf/open/floor/iron/dark, -/area/station/medical/paramedic) "bnM" = ( /obj/machinery/door/firedoor, /obj/effect/decal/cleanable/dirt, @@ -3900,6 +3925,11 @@ "bqX" = ( /turf/closed/wall/r_wall, /area/station/medical/chemistry) +"bra" = ( +/obj/machinery/light/small/dim/directional/west, +/obj/effect/spawner/random/engineering/atmospherics_portable, +/turf/open/floor/plating, +/area/station/maintenance/aft/lesser) "brc" = ( /obj/structure/table/wood, /obj/item/paper, @@ -4062,6 +4092,11 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/exit/departure_lounge) +"btA" = ( +/obj/machinery/airalarm/directional/north, +/obj/machinery/gizmo/toggle/tucker_tubes, +/turf/open/floor/iron/white, +/area/station/science/explab) "btC" = ( /obj/effect/turf_decal/stripes/line{ dir = 9 @@ -6189,6 +6224,21 @@ /obj/effect/mapping_helpers/airlock/access/all/science/ordnance, /turf/open/floor/iron/dark/airless, /area/station/science/ordnance/freezerchamber) +"che" = ( +/obj/structure/table/glass, +/obj/effect/turf_decal/tile/blue/fourcorners, +/obj/item/radio/intercom/directional/east, +/obj/item/tgui_book/manual/dsm{ + pixel_y = 3; + pixel_x = -2 + }, +/obj/item/tgui_book/manual/idc{ + pixel_y = 3; + pixel_x = 3 + }, +/obj/item/book/manual/wiki/medicine, +/turf/open/floor/iron/white, +/area/station/medical/treatment_center) "chn" = ( /obj/structure/sign/warning/secure_area/directional/south, /obj/structure/table/reinforced, @@ -6311,10 +6361,6 @@ /obj/effect/turf_decal/tile/yellow/half/contrasted, /turf/open/floor/iron, /area/station/engineering/break_room) -"cjD" = ( -/obj/machinery/airalarm/directional/north, -/turf/open/floor/iron/white, -/area/station/science/explab) "cky" = ( /obj/machinery/power/shieldwallgen, /obj/machinery/light/cold/directional/east, @@ -7374,10 +7420,6 @@ }, /turf/open/floor/plating, /area/station/science/robotics/mechbay) -"cBZ" = ( -/obj/structure/railing, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "cCM" = ( /obj/structure/lattice/catwalk, /obj/item/reagent_containers/cup/glass/bottle/rum{ @@ -7435,23 +7477,6 @@ /obj/item/instrument/guitar, /turf/open/space/basic, /area/space/nearstation) -"cDM" = ( -/obj/effect/turf_decal/siding/purple{ - dir = 9 - }, -/obj/structure/table, -/obj/item/paper_bin{ - pixel_x = -2; - pixel_y = 4 - }, -/obj/item/pen{ - pixel_x = -2; - pixel_y = 5 - }, -/obj/machinery/light_switch/directional/north, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/science/genetics) "cDO" = ( /obj/structure/table, /obj/item/stack/cable_coil{ @@ -7875,10 +7900,6 @@ dir = 1 }, /area/station/commons/fitness) -"cLj" = ( -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "cLk" = ( /obj/effect/turf_decal/siding/purple/corner{ dir = 1 @@ -8275,11 +8296,6 @@ /obj/machinery/firealarm/directional/west, /turf/open/floor/iron, /area/station/commons/dorms) -"cUt" = ( -/obj/effect/turf_decal/stripes/line, -/obj/effect/decal/cleanable/dirt/dust, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "cUw" = ( /obj/machinery/power/apc/auto_name/directional/east, /obj/structure/cable, @@ -8405,12 +8421,6 @@ dir = 1 }, /area/station/engineering/atmos/pumproom) -"cWz" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 1 - }, -/turf/open/floor/iron/white, -/area/station/science/research) "cWD" = ( /obj/effect/landmark/generic_maintenance_landmark, /obj/effect/mapping_helpers/broken_floor, @@ -8793,6 +8803,17 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/hidden/layer5, /turf/open/floor/plating, /area/station/hallway/secondary/entry) +"ddK" = ( +/obj/machinery/ai_slipper{ + uses = 10 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable/layer3, +/mob/living/basic/bot/secbot/pingsky, +/turf/open/floor/iron/dark, +/area/station/ai/satellite/interior) "ddO" = ( /obj/effect/turf_decal/trimline/green/filled/corner, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -9085,25 +9106,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/engineering/storage/tech) -"dhv" = ( -/obj/structure/rack, -/obj/item/book/manual/wiki/infections{ - pixel_y = 7 - }, -/obj/item/reagent_containers/syringe/antiviral, -/obj/structure/extinguisher_cabinet/directional/east, -/obj/effect/turf_decal/tile/green/anticorner/contrasted{ - dir = 4 - }, -/obj/machinery/status_display/evac/directional/north, -/obj/item/tgui_book/manual/idc{ - pixel_y = 3; - pixel_x = 3 - }, -/obj/item/reagent_containers/spray/cleaner, -/obj/item/reagent_containers/dropper, -/turf/open/floor/iron/white, -/area/station/medical/virology) "dhw" = ( /obj/machinery/atmospherics/pipe/smart/simple/green/visible{ dir = 10 @@ -9392,20 +9394,16 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/hallway/secondary/command) +"dmO" = ( +/obj/effect/turf_decal/trimline/purple/corner{ + dir = 8 + }, +/turf/open/floor/iron/white, +/area/station/science/research) "dmP" = ( /obj/effect/turf_decal/stripes/line, /turf/open/floor/engine, /area/station/engineering/atmospherics_engine) -"dmT" = ( -/obj/machinery/holopad, -/obj/structure/cable, -/obj/effect/turf_decal/tile/blue/anticorner/contrasted, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/white/corner{ - dir = 1 - }, -/area/station/medical/medbay/lobby) "dni" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -9465,6 +9463,15 @@ /obj/machinery/duct, /turf/open/floor/plating, /area/station/maintenance/port/aft) +"dom" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/iron/textured, +/area/station/cargo/miningoffice) "dox" = ( /obj/structure/rack, /obj/item/screwdriver{ @@ -9905,12 +9912,6 @@ }, /turf/open/floor/wood/parquet, /area/station/medical/psychology) -"dvB" = ( -/obj/effect/turf_decal/trimline/blue/filled/corner, -/obj/machinery/duct, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/white, -/area/station/medical/surgery/theatre) "dvJ" = ( /obj/structure/tank_dispenser, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -10028,16 +10029,6 @@ /obj/machinery/portable_atmospherics/canister/oxygen, /turf/open/floor/plating, /area/station/maintenance/starboard/greater) -"dxo" = ( -/obj/structure/railing{ - dir = 6 - }, -/obj/effect/decal/cleanable/dirt/dust, -/obj/effect/turf_decal/stripes/corner{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "dxq" = ( /obj/structure/chair{ dir = 8 @@ -10149,13 +10140,6 @@ /obj/structure/window/reinforced/spawner/directional/north, /turf/open/floor/iron/cafeteria, /area/station/security/prison) -"dAD" = ( -/obj/effect/spawner/random/entertainment/slot_machine{ - pixel_y = 2 - }, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/plating, -/area/station/maintenance/port/aft) "dAE" = ( /obj/structure/table/glass, /obj/effect/turf_decal/tile/blue/fourcorners, @@ -11693,6 +11677,13 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/iron, /area/station/service/hydroponics) +"ebG" = ( +/obj/effect/spawner/random/entertainment/slot_machine{ + pixel_y = 2 + }, +/obj/effect/mapping_helpers/broken_floor, +/turf/open/floor/wood, +/area/station/maintenance/port/aft) "ebK" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/cable, @@ -11826,19 +11817,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) -"edH" = ( -/obj/structure/table, -/obj/effect/turf_decal/siding/purple{ - dir = 4 - }, -/obj/machinery/computer/records/medical/laptop{ - dir = 8; - pixel_y = 1 - }, -/obj/structure/extinguisher_cabinet/directional/east, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/science/genetics) "edQ" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -12116,6 +12094,14 @@ /obj/machinery/light/small/broken/directional/east, /turf/open/floor/plating, /area/station/maintenance/port/fore) +"eiJ" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "mining" + }, +/obj/machinery/brm, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "eiO" = ( /obj/structure/table, /obj/item/storage/backpack/duffelbag/sec{ @@ -12564,6 +12550,13 @@ }, /turf/open/floor/wood, /area/station/commons/lounge) +"eov" = ( +/obj/effect/spawner/random/entertainment/slot_machine{ + pixel_y = 2 + }, +/obj/effect/mapping_helpers/broken_floor, +/turf/open/floor/plating, +/area/station/maintenance/port/aft) "eoC" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -12894,6 +12887,16 @@ /obj/machinery/light/small/directional/south, /turf/open/floor/iron/white, /area/station/science/xenobiology) +"euc" = ( +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/blue/fourcorners, +/obj/machinery/door/airlock/medical/glass{ + name = "Medbay Staff Entrance" + }, +/obj/effect/mapping_helpers/airlock/access/all/medical/general, +/obj/effect/mapping_helpers/airlock/unres/delayed, +/turf/open/floor/iron/dark, +/area/station/medical/medbay/central) "euj" = ( /obj/machinery/suit_storage_unit/standard_unit, /obj/machinery/light_switch/directional/north, @@ -12919,6 +12922,17 @@ "eut" = ( /turf/closed/wall, /area/station/science/robotics/lab) +"euQ" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/light/directional/north, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/airalarm/directional/north, +/obj/structure/cable, +/turf/open/floor/iron/white, +/area/station/science/research) "euT" = ( /obj/structure/secure_safe/hos, /turf/closed/wall/r_wall, @@ -12983,6 +12997,20 @@ /obj/effect/landmark/start/depsec/medical, /turf/open/floor/iron/dark, /area/station/security/checkpoint/medical) +"ewc" = ( +/obj/machinery/power/apc/auto_name/directional/north, +/obj/structure/cable, +/obj/effect/turf_decal/siding/wood, +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/machinery/light/small/directional/north, +/obj/structure/disposalpipe/trunk{ + dir = 8 + }, +/obj/machinery/disposal/bin, +/turf/open/floor/wood/large, +/area/station/command/heads_quarters/qm) "ewf" = ( /obj/effect/turf_decal/tile/neutral, /turf/open/floor/iron, @@ -13878,6 +13906,13 @@ /obj/structure/plasticflaps, /turf/open/floor/plating, /area/station/cargo/sorting) +"eMv" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/siding/purple{ + dir = 8 + }, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "eMH" = ( /obj/item/radio/intercom/directional/north, /obj/effect/turf_decal/stripes/corner{ @@ -14000,11 +14035,6 @@ /obj/effect/mapping_helpers/airlock/access/all/security/general, /turf/open/floor/iron, /area/station/security/brig) -"eOA" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/science/robotics/lab) "eOJ" = ( /obj/effect/turf_decal/stripes/line, /obj/structure/cable, @@ -14059,19 +14089,20 @@ }, /turf/open/floor/iron/dark/textured_large, /area/station/science/cytology) -"eQc" = ( -/obj/structure/disposalpipe/sorting/mail/flip{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, +"ePZ" = ( +/obj/machinery/door/firedoor, /obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/mapping_helpers/mail_sorting/service/library, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/plating, -/area/station/maintenance/port) +/obj/machinery/door/airlock/medical/glass{ + id_tag = "MedbayFoyer"; + name = "Medbay" + }, +/obj/effect/mapping_helpers/airlock/access/all/medical/general, +/obj/effect/turf_decal/tile/blue/fourcorners, +/obj/effect/mapping_helpers/airlock/unres/delayed{ + dir = 8 + }, +/turf/open/floor/iron/white, +/area/station/medical/medbay/central) "eQe" = ( /obj/structure/cable, /turf/open/floor/wood, @@ -14150,6 +14181,16 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/closed/wall/r_wall, /area/station/science/ordnance/burnchamber) +"eRB" = ( +/obj/machinery/door/airlock/maintenance{ + name = "Genetics 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/science/genetics, +/turf/open/floor/plating, +/area/station/science/genetics) "eRR" = ( /obj/structure/table, /obj/item/screwdriver{ @@ -14403,16 +14444,6 @@ }, /turf/open/floor/iron, /area/station/security/brig) -"eWS" = ( -/obj/item/kirbyplants/random, -/obj/effect/turf_decal/trimline/purple/corner{ - dir = 4 - }, -/obj/effect/turf_decal/siding/purple/corner{ - dir = 1 - }, -/turf/open/floor/iron/white, -/area/station/science/research) "eWW" = ( /obj/structure/disposalpipe/segment{ dir = 9 @@ -14652,13 +14683,6 @@ dir = 1 }, /area/station/science/lobby) -"fao" = ( -/obj/effect/turf_decal/siding/purple{ - dir = 1 - }, -/obj/machinery/light/directional/south, -/turf/open/floor/iron/white, -/area/station/science/research) "faC" = ( /obj/effect/decal/cleanable/blood/splatter/oil, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, @@ -15158,6 +15182,15 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/port/fore) +"fjb" = ( +/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/iron/white, +/area/station/science/research) "fjd" = ( /obj/structure/closet/firecloset, /turf/open/floor/plating, @@ -15222,6 +15255,10 @@ /obj/effect/spawner/random/bureaucracy/pen, /turf/open/floor/wood, /area/station/commons/vacant_room/office) +"fke" = ( +/obj/effect/turf_decal/trimline/purple/line, +/turf/open/floor/iron/white, +/area/station/science/research) "fkl" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/cable, @@ -15672,15 +15709,6 @@ /obj/structure/chair/stool/directional/south, /turf/open/floor/wood, /area/station/commons/lounge) -"fqP" = ( -/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/white, -/area/station/science/research) "fqR" = ( /obj/effect/spawner/random/structure/crate, /turf/open/floor/plating, @@ -15827,12 +15855,6 @@ /obj/machinery/light/small/directional/west, /turf/open/floor/circuit/green/off, /area/station/science/research) -"fud" = ( -/obj/effect/spawner/random/entertainment/slot_machine{ - pixel_y = 2 - }, -/turf/open/floor/wood, -/area/station/maintenance/port/aft) "fuu" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -16226,15 +16248,6 @@ /obj/machinery/firealarm/directional/south, /turf/open/floor/iron, /area/station/security/brig) -"fDV" = ( -/obj/effect/turf_decal/tile/brown/half/contrasted, -/obj/effect/turf_decal/bot, -/obj/structure/disposalpipe/trunk{ - dir = 1 - }, -/obj/machinery/disposal/bin, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "fEg" = ( /obj/machinery/door/airlock{ name = "Service Hall" @@ -16731,6 +16744,15 @@ /obj/effect/landmark/start/depsec/supply, /turf/open/floor/iron/dark, /area/station/security/checkpoint/supply) +"fMP" = ( +/obj/machinery/bouldertech/refinery{ + dir = 1 + }, +/obj/machinery/conveyor{ + id = "mining" + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "fMT" = ( /obj/structure/table, /obj/item/radio/intercom/directional/south, @@ -16868,6 +16890,16 @@ }, /turf/open/space/basic, /area/space) +"fQo" = ( +/obj/item/kirbyplants/random, +/obj/effect/turf_decal/trimline/purple/corner{ + dir = 4 + }, +/obj/effect/turf_decal/siding/purple/corner{ + dir = 1 + }, +/turf/open/floor/iron/white, +/area/station/science/research) "fQD" = ( /obj/structure/chair/stool/directional/north, /obj/effect/mapping_helpers/broken_floor, @@ -17289,20 +17321,6 @@ }, /turf/open/floor/iron, /area/station/security/brig) -"fYP" = ( -/obj/machinery/door/firedoor, -/obj/structure/cable, -/obj/machinery/door/airlock/medical/glass{ - id_tag = "MedbayFoyer"; - name = "Medbay" - }, -/obj/effect/mapping_helpers/airlock/access/all/medical/general, -/obj/effect/turf_decal/tile/blue/fourcorners, -/obj/effect/mapping_helpers/airlock/unres/delayed{ - dir = 8 - }, -/turf/open/floor/iron/white, -/area/station/medical/medbay/central) "fYX" = ( /obj/structure/cable, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -17536,6 +17554,18 @@ }, /turf/open/floor/iron, /area/station/security/office) +"gcU" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/mapping_helpers/airlock/access/all/science/robotics, +/obj/machinery/door/airlock/research{ + name = "Robotics Lab" + }, +/obj/machinery/door/firedoor, +/obj/structure/cable, +/obj/effect/landmark/navigate_destination, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/white, +/area/station/science/robotics/lab) "gcV" = ( /obj/effect/turf_decal/siding/wood{ dir = 8 @@ -18179,15 +18209,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/department/engine) -"gqm" = ( -/obj/effect/spawner/structure/window, -/obj/machinery/door/poddoor/shutters/preopen{ - dir = 1; - id = "rdgene"; - name = "Genetics Lab Shutters" - }, -/turf/open/floor/plating, -/area/station/science/genetics) "gqA" = ( /obj/machinery/suit_storage_unit/standard_unit, /obj/machinery/button/door/directional/south{ @@ -18928,14 +18949,6 @@ /obj/effect/turf_decal/tile/blue/fourcorners, /turf/open/floor/iron, /area/station/hallway/primary/central) -"gDy" = ( -/obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/trimline/blue/filled/warning{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/white, -/area/station/medical/medbay/lobby) "gDH" = ( /obj/effect/turf_decal/stripes/line{ dir = 6 @@ -19015,14 +19028,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/cargo/warehouse) -"gED" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/trimline/blue/filled/line{ - dir = 10 - }, -/turf/open/floor/iron/dark, -/area/station/medical/paramedic) "gEG" = ( /obj/machinery/door/airlock/maintenance, /obj/effect/mapping_helpers/airlock/access/any/science/maintenance, @@ -19517,6 +19522,11 @@ }, /turf/open/floor/iron, /area/station/engineering/main) +"gLT" = ( +/obj/structure/cable, +/obj/effect/turf_decal/siding/white, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "gLU" = ( /obj/structure/table, /obj/effect/turf_decal/siding{ @@ -19822,6 +19832,15 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/hallway/secondary/exit/departure_lounge) +"gRn" = ( +/obj/machinery/bouldertech/refinery/smelter{ + dir = 1 + }, +/obj/machinery/conveyor{ + id = "mining" + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "gRp" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -19888,16 +19907,6 @@ /obj/effect/turf_decal/tile/red/fourcorners, /turf/open/floor/iron, /area/station/security/checkpoint/science) -"gTp" = ( -/obj/machinery/duct, -/obj/structure/disposalpipe/segment{ - dir = 9 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 1 - }, -/turf/open/floor/iron/white/smooth_large, -/area/station/medical/surgery/theatre) "gTt" = ( /turf/open/floor/carpet, /area/station/command/heads_quarters/hos) @@ -20648,6 +20657,18 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/security/prison/safe) +"hfG" = ( +/obj/machinery/camera/directional/south{ + c_tag = "Starboard Primary Hallway - Technical Storage" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/hallway/primary/starboard) "hfH" = ( /obj/structure/table/reinforced, /obj/machinery/microwave/engineering/cell_included, @@ -21017,17 +21038,6 @@ "hlD" = ( /turf/open/floor/carpet, /area/station/command/heads_quarters/captain/private) -"hlE" = ( -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 1 - }, -/obj/machinery/conveyor{ - dir = 8; - id = "mining" - }, -/obj/machinery/light/small/directional/south, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "hlN" = ( /obj/structure/frame/machine{ anchored = 1 @@ -22805,6 +22815,19 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/hidden, /turf/open/floor/iron, /area/station/security/brig) +"hSJ" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/poddoor/shutters/preopen{ + dir = 8; + id = "rdgene2"; + name = "Genetics Lab Shutters" + }, +/obj/machinery/door/airlock/research{ + name = "Genetics Lab" + }, +/obj/effect/mapping_helpers/airlock/access/all/science/genetics, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "hSO" = ( /obj/effect/turf_decal/stripes/corner{ dir = 8 @@ -22956,6 +22979,12 @@ /obj/structure/window/reinforced/spawner/directional/west, /turf/open/floor/engine, /area/station/science/xenobiology) +"hWj" = ( +/obj/effect/spawner/random/entertainment/slot_machine{ + pixel_y = 2 + }, +/turf/open/floor/wood, +/area/station/maintenance/port/aft) "hWx" = ( /obj/structure/disposalpipe/segment{ dir = 9 @@ -23070,6 +23099,16 @@ }, /turf/open/floor/iron, /area/station/engineering/break_room) +"hYr" = ( +/obj/machinery/holopad, +/obj/structure/cable, +/obj/effect/turf_decal/tile/blue/anticorner/contrasted, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron/white/corner{ + dir = 1 + }, +/area/station/medical/medbay/lobby) "hYs" = ( /obj/machinery/atmospherics/pipe/smart/simple/green/visible, /obj/machinery/meter, @@ -23391,20 +23430,6 @@ /obj/machinery/duct, /turf/open/floor/plating, /area/station/maintenance/fore) -"icG" = ( -/obj/machinery/door/airlock/medical/glass{ - name = "Primary Treatment Centre" - }, -/obj/machinery/door/firedoor, -/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/medical/general, -/obj/effect/turf_decal/tile/blue/fourcorners, -/obj/effect/mapping_helpers/airlock/unres/delayed{ - dir = 8 - }, -/turf/open/floor/iron/white, -/area/station/medical/treatment_center) "icO" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 1 @@ -24217,6 +24242,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/cargo/storage) +"iqu" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/siding/purple{ + dir = 8 + }, +/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/science/genetics) "iqx" = ( /obj/machinery/atmospherics/pipe/smart/manifold/scrubbers/visible{ dir = 4 @@ -24308,6 +24342,12 @@ }, /turf/open/space/basic, /area/space) +"ise" = ( +/obj/effect/turf_decal/bot, +/obj/item/robot_suit, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron/dark, +/area/station/science/robotics/lab) "isk" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -24615,12 +24655,6 @@ /obj/machinery/duct, /turf/open/floor/iron/white, /area/station/science/xenobiology) -"ixC" = ( -/obj/effect/turf_decal/tile/blue/half/contrasted{ - dir = 8 - }, -/turf/open/floor/iron/white, -/area/station/medical/medbay/lobby) "ixP" = ( /obj/machinery/firealarm/directional/south, /obj/structure/cable, @@ -24703,6 +24737,16 @@ /obj/effect/spawner/random/techstorage/medical_all, /turf/open/floor/iron/dark, /area/station/engineering/storage/tech) +"izl" = ( +/obj/machinery/duct, +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 1 + }, +/turf/open/floor/iron/white/smooth_large, +/area/station/medical/surgery/theatre) "izp" = ( /turf/open/floor/plating, /area/station/maintenance/starboard/greater) @@ -25184,13 +25228,6 @@ /obj/structure/window/reinforced/spawner/directional/south, /turf/open/floor/engine, /area/station/science/xenobiology) -"iId" = ( -/obj/machinery/conveyor{ - id = "mining" - }, -/obj/machinery/brm, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "iIf" = ( /obj/machinery/camera/directional/north{ c_tag = "Locker Room Entrance" @@ -25282,6 +25319,17 @@ /obj/machinery/light/small/directional/south, /turf/open/floor/iron/dark, /area/station/security/brig) +"iKO" = ( +/obj/effect/turf_decal/siding/purple{ + dir = 9 + }, +/obj/machinery/light_switch/directional/north, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/structure/chair/office{ + dir = 8 + }, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "iKT" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -26036,30 +26084,31 @@ dir = 4 }, /area/station/service/chapel) +"iWy" = ( +/obj/machinery/atmospherics/pipe/smart/simple/yellow/visible, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/white, +/area/station/science/ordnance/storage) "iWB" = ( /obj/item/storage/fancy/candle_box, /obj/machinery/light/small/directional/east, /obj/structure/rack/skeletal, /turf/open/floor/engine/cult, /area/station/service/library) +"iWD" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/trimline/blue/filled/line{ + dir = 10 + }, +/turf/open/floor/iron/dark, +/area/station/medical/paramedic) "iWJ" = ( /obj/effect/turf_decal/stripes/corner, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/hallway/secondary/exit/departure_lounge) -"iWP" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/mapping_helpers/airlock/access/all/science/robotics, -/obj/machinery/door/airlock/research{ - name = "Robotics Lab" - }, -/obj/machinery/door/firedoor, -/obj/structure/cable, -/obj/effect/landmark/navigate_destination, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/white, -/area/station/science/robotics/lab) "iWT" = ( /obj/effect/turf_decal/siding/purple{ dir = 6 @@ -26729,6 +26778,10 @@ }, /turf/open/floor/iron, /area/station/engineering/gravity_generator) +"jhL" = ( +/obj/effect/spawner/random/gizmo, +/turf/open/floor/engine, +/area/station/science/explab) "jhS" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -26954,6 +27007,13 @@ }, /turf/open/floor/iron, /area/station/construction/mining/aux_base) +"jml" = ( +/obj/effect/turf_decal/trimline/blue/filled/line{ + dir = 4 + }, +/obj/structure/sink/directional/west, +/turf/open/floor/iron/white, +/area/station/medical/surgery/theatre) "jmq" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -27521,17 +27581,6 @@ /obj/structure/window/reinforced/spawner/directional/west, /turf/open/floor/engine, /area/station/science/explab) -"jvO" = ( -/obj/machinery/ai_slipper{ - uses = 10 - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable/layer3, -/mob/living/simple_animal/bot/secbot/pingsky, -/turf/open/floor/iron/dark, -/area/station/ai/satellite/interior) "jvQ" = ( /obj/machinery/door/window/left/directional/north{ name = "Petting Zoo" @@ -27746,6 +27795,13 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/aft) +"jyy" = ( +/obj/machinery/conveyor/inverted{ + dir = 5; + id = "mining" + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "jyF" = ( /obj/effect/turf_decal/bot, /obj/effect/turf_decal/tile/neutral/opposingcorners{ @@ -27788,6 +27844,12 @@ /obj/machinery/incident_display/delam/directional/north, /turf/open/floor/iron/dark, /area/station/engineering/main) +"jzd" = ( +/obj/structure/cable, +/obj/structure/railing, +/obj/effect/turf_decal/siding/white, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "jzp" = ( /turf/closed/wall, /area/station/commons/vacant_room/office) @@ -27918,6 +27980,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/cargo/miningoffice) +"jBp" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted, +/obj/effect/turf_decal/bot, +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, +/obj/machinery/disposal/bin, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "jBu" = ( /obj/effect/landmark/start/cargo_technician, /obj/effect/turf_decal/bot_white, @@ -28295,6 +28366,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/port/aft) +"jHg" = ( +/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/white, +/area/station/science/research) "jHm" = ( /obj/machinery/light/small/directional/east, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -28316,6 +28396,12 @@ /obj/structure/sign/warning/directional/southwest, /turf/open/floor/plating/airless, /area/station/science/ordnance/bomb) +"jHA" = ( +/obj/effect/turf_decal/tile/blue/half/contrasted{ + dir = 8 + }, +/turf/open/floor/iron/white, +/area/station/medical/medbay/lobby) "jHB" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -29160,16 +29246,6 @@ }, /turf/open/floor/iron, /area/station/security/brig) -"jVx" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/white, -/area/station/science/robotics/lab) "jVy" = ( /obj/machinery/portable_atmospherics/pump/lil_pump, /obj/effect/turf_decal/siding/purple{ @@ -29381,21 +29457,6 @@ /obj/structure/window/reinforced/spawner/directional/west, /turf/open/floor/iron/dark, /area/station/command/bridge) -"jZi" = ( -/obj/machinery/light/directional/south, -/obj/structure/bed/medical/emergency, -/obj/effect/turf_decal/trimline/blue/filled/warning{ - dir = 1 - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/tile/blue/half/contrasted, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/turf/open/floor/iron/white, -/area/station/medical/medbay/lobby) "jZt" = ( /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 4 @@ -29787,10 +29848,6 @@ /obj/machinery/door/poddoor/incinerator_ordmix, /turf/open/floor/engine/vacuum, /area/station/science/ordnance/burnchamber) -"kgK" = ( -/obj/effect/turf_decal/trimline/purple/corner, -/turf/open/floor/iron/white, -/area/station/science/research) "kgR" = ( /obj/structure/cable, /obj/effect/turf_decal/stripes/line{ @@ -29842,21 +29899,6 @@ /obj/machinery/pdapainter/medbay, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/cmo) -"khi" = ( -/obj/machinery/newscaster/directional/north, -/obj/effect/spawner/random/entertainment/slot_machine{ - pixel_y = 2 - }, -/obj/effect/turf_decal/tile/bar/opposingcorners, -/turf/open/floor/iron, -/area/station/commons/lounge) -"khm" = ( -/obj/effect/turf_decal/trimline/red/filled/line{ - dir = 8 - }, -/mob/living/simple_animal/bot/secbot/beepsky/officer, -/turf/open/floor/iron, -/area/station/security/brig) "kho" = ( /obj/machinery/door/window/left/directional/east{ name = "Mass Driver"; @@ -29914,6 +29956,25 @@ /obj/structure/reagent_dispensers/fueltank, /turf/open/floor/plating, /area/station/maintenance/fore) +"kir" = ( +/obj/structure/disposalpipe/sorting/mail/flip{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/mapping_helpers/mail_sorting/service/library, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/plating, +/area/station/maintenance/port) +"kiy" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron/dark, +/area/station/science/robotics/lab) "kiz" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 1 @@ -29990,23 +30051,6 @@ }, /turf/open/floor/iron, /area/station/cargo/storage) -"kkn" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/white/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/white/line{ - dir = 4 - }, -/obj/machinery/door/firedoor, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/obj/structure/cable, -/turf/open/floor/iron/dark, -/area/station/science/research) "kkr" = ( /obj/structure/plasticflaps/opaque, /obj/machinery/door/poddoor/preopen{ @@ -30150,15 +30194,6 @@ "klt" = ( /turf/open/floor/iron/dark, /area/station/service/chapel/funeral) -"klu" = ( -/obj/effect/turf_decal/siding/purple{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/science/genetics) "klw" = ( /obj/effect/turf_decal/tile/yellow{ dir = 4 @@ -30330,6 +30365,12 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/central) +"koY" = ( +/obj/machinery/airalarm/directional/east, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/turf_decal/tile/brown/opposingcorners, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "kpB" = ( /obj/structure/disposalpipe/segment{ dir = 6 @@ -30472,6 +30513,12 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/science/ordnance/testlab) +"krW" = ( +/obj/structure/cable, +/obj/structure/railing/corner, +/obj/effect/turf_decal/siding/white/corner, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "krZ" = ( /obj/machinery/disposal/bin, /obj/effect/turf_decal/bot, @@ -30815,13 +30862,6 @@ /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) -"kya" = ( -/obj/effect/turf_decal/siding/purple{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/white, -/area/station/science/research) "kyc" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -30998,14 +31038,6 @@ /obj/effect/spawner/random/maintenance, /turf/open/floor/plating, /area/station/maintenance/port/fore) -"kAQ" = ( -/obj/machinery/airalarm/directional/north, -/obj/effect/spawner/random/entertainment/slot_machine{ - pixel_y = 2 - }, -/obj/effect/turf_decal/tile/bar/opposingcorners, -/turf/open/floor/iron, -/area/station/commons/lounge) "kAT" = ( /obj/effect/landmark/start/head_of_security, /obj/structure/chair/comfy/black, @@ -31394,25 +31426,6 @@ }, /turf/open/floor/engine, /area/station/science/xenobiology) -"kHv" = ( -/obj/structure/bed/medical/emergency, -/obj/item/radio/intercom/directional/south, -/obj/machinery/camera/directional/south{ - c_tag = "Medbay Foyer"; - network = list("ss13","medbay") - }, -/obj/effect/turf_decal/trimline/blue/filled/corner{ - dir = 4 - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/tile/blue/half/contrasted, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/turf/open/floor/iron/white, -/area/station/medical/medbay/lobby) "kHN" = ( /obj/structure/window/reinforced/spawner/directional/west, /turf/open/floor/engine, @@ -31945,9 +31958,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/commons/locker) -"kRe" = ( -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "kRf" = ( /obj/structure/railing{ dir = 6 @@ -32172,16 +32182,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/wood, /area/station/service/library) -"kVf" = ( -/obj/machinery/camera/directional/south{ - c_tag = "Science Hallway - RD Office"; - network = list("ss13","rd") - }, -/obj/effect/turf_decal/siding/purple{ - dir = 1 - }, -/turf/open/floor/iron/white, -/area/station/science/research) "kVg" = ( /obj/machinery/computer/pandemic, /obj/structure/cable, @@ -32356,6 +32356,25 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating, /area/station/maintenance/port/fore) +"kXD" = ( +/obj/structure/bed/medical/emergency, +/obj/item/radio/intercom/directional/south, +/obj/machinery/camera/directional/south{ + c_tag = "Medbay Foyer"; + network = list("ss13","medbay") + }, +/obj/effect/turf_decal/trimline/blue/filled/corner{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue/half/contrasted, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/iron/white, +/area/station/medical/medbay/lobby) "kXG" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible/layer2{ dir = 4 @@ -32437,10 +32456,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central) -"kYP" = ( -/obj/machinery/light/small/dim/directional/west, -/turf/open/floor/plating, -/area/station/maintenance/aft/lesser) "kYU" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -32590,16 +32605,6 @@ /obj/structure/plasticflaps/kitchen, /turf/open/floor/iron/cafeteria, /area/station/service/kitchen/coldroom) -"laZ" = ( -/obj/structure/table, -/obj/item/stack/medical/mesh, -/obj/item/stack/medical/wrap/gauze, -/obj/item/stack/medical/suture, -/obj/effect/turf_decal/tile/blue/half/contrasted{ - dir = 8 - }, -/turf/open/floor/iron/white, -/area/station/medical/medbay/lobby) "lbh" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 8 @@ -32766,16 +32771,6 @@ }, /turf/open/floor/iron/white, /area/station/science/research) -"lfT" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/tile/blue/half/contrasted, -/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/white, -/area/station/medical/medbay/lobby) "lfU" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 1 @@ -32847,15 +32842,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, /area/station/medical/medbay/central) -"lhe" = ( -/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/iron/white, -/area/station/science/research) "lhD" = ( /obj/structure/reagent_dispensers/watertank, /obj/effect/spawner/random/trash/janitor_supplies, @@ -32923,6 +32909,11 @@ /obj/machinery/duct, /turf/open/floor/iron, /area/station/engineering/main) +"liD" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron/dark, +/area/station/science/robotics/lab) "liL" = ( /obj/structure/table, /obj/effect/turf_decal/tile/red/opposingcorners, @@ -32945,18 +32936,6 @@ }, /turf/open/floor/iron, /area/station/cargo/storage) -"lje" = ( -/obj/machinery/camera/directional/south{ - c_tag = "Starboard Primary Hallway - Auxiliary Tool Storage" - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/hallway/primary/starboard) "ljf" = ( /obj/structure/table, /obj/item/wirecutters, @@ -33412,6 +33391,21 @@ }, /turf/open/floor/engine/cult, /area/station/service/library) +"lrR" = ( +/obj/machinery/light/directional/south, +/obj/structure/bed/medical/emergency, +/obj/effect/turf_decal/trimline/blue/filled/warning{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue/half/contrasted, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/iron/white, +/area/station/medical/medbay/lobby) "lrZ" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/shutters/preopen{ @@ -33600,6 +33594,16 @@ }, /turf/open/floor/iron, /area/station/cargo/storage) +"lvr" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment, +/obj/effect/landmark/start/shaft_miner, +/obj/structure/railing/corner/end{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "lvs" = ( /obj/machinery/door/airlock/maintenance, /obj/structure/disposalpipe/segment, @@ -34638,6 +34642,16 @@ /obj/effect/spawner/random/trash/caution_sign, /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) +"lQS" = ( +/obj/machinery/light/small/directional/south, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/turf/open/floor/iron/textured, +/area/station/cargo/miningoffice) "lRA" = ( /obj/structure/disposalpipe/segment{ dir = 6 @@ -34867,12 +34881,6 @@ /obj/machinery/meter/layer4, /turf/open/floor/plating, /area/station/maintenance/aft/lesser) -"lVy" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 - }, -/turf/open/floor/iron/white/smooth_large, -/area/station/medical/medbay/lobby) "lVB" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -34948,6 +34956,16 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/maintenance/disposal/incinerator) +"lWG" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue/half/contrasted, +/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/white, +/area/station/medical/medbay/lobby) "lWL" = ( /obj/effect/turf_decal/stripes/line, /obj/structure/disposalpipe/segment{ @@ -35612,16 +35630,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/medbay/central) -"miS" = ( -/obj/machinery/door/firedoor, -/obj/effect/turf_decal/tile/blue/fourcorners, -/obj/machinery/door/airlock/medical/glass{ - name = "Medbay Staff Entrance" - }, -/obj/effect/mapping_helpers/airlock/access/all/medical/general, -/obj/effect/mapping_helpers/airlock/unres/delayed, -/turf/open/floor/iron/dark, -/area/station/medical/medbay/central) "miW" = ( /obj/machinery/camera/directional/north{ c_tag = "Command Hallway - Starboard" @@ -36179,21 +36187,6 @@ /obj/item/reagent_containers/cup/beaker/large, /turf/open/floor/iron/cafeteria, /area/station/service/kitchen) -"mta" = ( -/obj/machinery/camera/directional/north{ - c_tag = "Starboard Primary Hallway - tech_storage" - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/landmark/start/hangover, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/hallway/primary/starboard) "mtb" = ( /obj/structure/table/wood, /obj/structure/extinguisher_cabinet/directional/west, @@ -37038,10 +37031,6 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/exit/departure_lounge) -"mGI" = ( -/obj/effect/spawner/random/engineering/atmospherics_portable, -/turf/open/floor/plating, -/area/station/maintenance/aft/lesser) "mGV" = ( /obj/structure/toilet{ dir = 1 @@ -37104,16 +37093,6 @@ /obj/machinery/vending/modularpc, /turf/open/floor/iron/white, /area/station/science/lobby) -"mHL" = ( -/obj/item/kirbyplants/random, -/obj/effect/turf_decal/siding/purple{ - dir = 6 - }, -/obj/machinery/power/apc/auto_name/directional/east, -/obj/structure/cable, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/science/genetics) "mHO" = ( /obj/machinery/portable_atmospherics/scrubber, /obj/item/radio/intercom/directional/north, @@ -37297,6 +37276,16 @@ }, /turf/open/floor/iron/diagonal, /area/station/cargo/storage) +"mLu" = ( +/obj/machinery/camera/directional/south{ + c_tag = "Science Hallway - RD Office"; + network = list("ss13","rd") + }, +/obj/effect/turf_decal/siding/purple{ + dir = 1 + }, +/turf/open/floor/iron/white, +/area/station/science/research) "mLx" = ( /obj/effect/turf_decal/tile/red/anticorner/contrasted{ dir = 8 @@ -37480,15 +37469,6 @@ /obj/effect/spawner/random/structure/crate, /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) -"mOU" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/duct, -/turf/open/floor/iron/white, -/area/station/medical/virology) "mPe" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -37534,6 +37514,18 @@ /obj/machinery/duct, /turf/open/floor/iron/freezer, /area/station/commons/toilet/restrooms) +"mPF" = ( +/obj/machinery/door/window/right/directional/west{ + name = "Surgical Supplies"; + req_access = list("surgery") + }, +/obj/structure/table/reinforced, +/obj/item/stack/medical/wrap/sticky_tape/surgical, +/obj/item/stack/medical/bone_gel, +/obj/effect/turf_decal/tile/blue/fourcorners, +/obj/structure/window/reinforced/spawner/directional/north, +/turf/open/floor/iron/white, +/area/station/medical/surgery/theatre) "mPG" = ( /obj/structure/table/reinforced, /obj/item/folder/yellow, @@ -37932,12 +37924,6 @@ }, /turf/open/space/basic, /area/space/nearstation) -"mWq" = ( -/obj/effect/turf_decal/trimline/purple/corner{ - dir = 8 - }, -/turf/open/floor/iron/white, -/area/station/science/research) "mWU" = ( /turf/open/floor/iron, /area/station/maintenance/space_hut) @@ -38043,6 +38029,21 @@ /obj/machinery/computer/security/telescreen/interrogation/directional/west, /turf/open/floor/iron/grimy, /area/station/security/interrogation) +"mYf" = ( +/obj/machinery/door/firedoor, +/obj/structure/cable, +/obj/machinery/duct, +/obj/machinery/door/airlock/medical/glass{ + name = "Cryogenics Bay" + }, +/obj/structure/disposalpipe/segment, +/obj/effect/mapping_helpers/airlock/access/all/medical/general, +/obj/effect/turf_decal/tile/blue/fourcorners, +/obj/effect/mapping_helpers/airlock/unres/delayed{ + dir = 1 + }, +/turf/open/floor/iron/white, +/area/station/medical/treatment_center) "mYq" = ( /obj/effect/turf_decal/plaque{ icon_state = "L8" @@ -38156,15 +38157,6 @@ }, /turf/open/floor/iron/dark, /area/station/command/bridge) -"mZO" = ( -/obj/effect/turf_decal/siding/purple/corner{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/science/genetics) "mZP" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -38536,10 +38528,6 @@ /obj/effect/spawner/structure/window, /turf/open/floor/plating, /area/station/medical/break_room) -"ngI" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, -/turf/open/floor/iron/white/smooth_large, -/area/station/medical/medbay/lobby) "ngO" = ( /obj/structure/table, /obj/structure/disposalpipe/segment, @@ -39012,6 +39000,16 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/iron, /area/station/hallway/secondary/entry) +"noN" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/white, +/area/station/science/robotics/lab) "noT" = ( /obj/structure/cable, /obj/machinery/door/airlock/maintenance, @@ -40753,21 +40751,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/science/robotics/lab) -"nST" = ( -/obj/structure/table/glass, -/obj/effect/turf_decal/tile/blue/fourcorners, -/obj/item/radio/intercom/directional/east, -/obj/item/tgui_book/manual/dsm{ - pixel_y = 3; - pixel_x = -2 - }, -/obj/item/tgui_book/manual/idc{ - pixel_y = 3; - pixel_x = 3 - }, -/obj/item/book/manual/wiki/medicine, -/turf/open/floor/iron/white, -/area/station/medical/treatment_center) "nTd" = ( /obj/structure/rack, /obj/effect/spawner/random/food_or_drink/seed, @@ -40860,6 +40843,29 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/cargo/miningoffice) +"nVJ" = ( +/obj/structure/table/glass, +/obj/item/reagent_containers/chem_pack{ + pixel_x = 10; + pixel_y = 10 + }, +/obj/item/storage/box/rxglasses{ + pixel_x = -4; + pixel_y = 8 + }, +/obj/item/stack/medical/wrap/gauze{ + pixel_x = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/siding/white/corner{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue/fourcorners, +/turf/open/floor/iron/white/side{ + dir = 10 + }, +/area/station/medical/treatment_center) "nVL" = ( /obj/structure/grille/broken, /obj/item/bouquet/poppy, @@ -40920,6 +40926,14 @@ }, /turf/open/floor/iron/dark, /area/station/command/bridge) +"nXG" = ( +/obj/machinery/newscaster/directional/north, +/obj/effect/spawner/random/entertainment/slot_machine{ + pixel_y = 2 + }, +/obj/effect/turf_decal/tile/bar/opposingcorners, +/turf/open/floor/iron, +/area/station/commons/lounge) "nXK" = ( /obj/docking_port/stationary/random{ dir = 4; @@ -40960,6 +40974,16 @@ /obj/machinery/light/small/dim/directional/north, /turf/open/floor/plating, /area/station/maintenance/port/aft) +"nYI" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 1 + }, +/obj/machinery/conveyor{ + dir = 10; + id = "mining" + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "nYJ" = ( /obj/structure/lattice, /obj/structure/grille/broken, @@ -41252,6 +41276,25 @@ dir = 4 }, /area/station/security/prison) +"ocN" = ( +/obj/structure/rack, +/obj/item/book/manual/wiki/infections{ + pixel_y = 7 + }, +/obj/item/reagent_containers/syringe/antiviral, +/obj/structure/extinguisher_cabinet/directional/east, +/obj/effect/turf_decal/tile/green/anticorner/contrasted{ + dir = 4 + }, +/obj/machinery/status_display/evac/directional/north, +/obj/item/tgui_book/manual/idc{ + pixel_y = 3; + pixel_x = 3 + }, +/obj/item/reagent_containers/spray/cleaner, +/obj/item/reagent_containers/dropper, +/turf/open/floor/iron/white, +/area/station/medical/virology) "ocP" = ( /obj/machinery/airalarm/directional/west, /turf/open/floor/iron, @@ -41289,6 +41332,12 @@ /obj/machinery/door/firedoor, /turf/open/floor/iron/white, /area/station/security/prison) +"odu" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/tile/blue/fourcorners, +/turf/open/floor/iron/dark, +/area/station/medical/paramedic) "odI" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock{ @@ -41301,6 +41350,15 @@ /obj/effect/mapping_helpers/airlock/access/all/service/hydroponics, /turf/open/floor/iron, /area/station/service/hydroponics) +"odX" = ( +/obj/structure/cable, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/duct, +/turf/open/floor/iron/white, +/area/station/medical/virology) "oet" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 1 @@ -41491,14 +41549,6 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/wood, /area/station/maintenance/port/aft) -"oiR" = ( -/obj/effect/turf_decal/tile/blue/anticorner/contrasted{ - dir = 8 - }, -/turf/open/floor/iron/white/corner{ - dir = 4 - }, -/area/station/medical/medbay/lobby) "ojo" = ( /obj/effect/turf_decal/siding/wood{ dir = 6 @@ -42980,12 +43030,6 @@ }, /turf/open/floor/iron/dark, /area/station/security/lockers) -"oHO" = ( -/obj/structure/rack, -/obj/effect/spawner/random/maintenance, -/obj/machinery/light/small/directional/north, -/turf/open/floor/plating, -/area/station/maintenance/aft/lesser) "oIa" = ( /turf/closed/wall, /area/station/commons/vacant_room/commissary) @@ -43704,6 +43748,19 @@ /obj/machinery/telecomms/server/presets/science, /turf/open/floor/circuit/telecomms/mainframe, /area/station/tcommsat/server) +"oXr" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Primary Treatment Centre" + }, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/access/all/medical/general, +/obj/effect/turf_decal/tile/blue/fourcorners, +/obj/effect/landmark/navigate_destination, +/obj/effect/mapping_helpers/airlock/unres/delayed{ + dir = 8 + }, +/turf/open/floor/iron/white, +/area/station/medical/treatment_center) "oXI" = ( /obj/machinery/door/firedoor, /obj/structure/cable, @@ -43928,6 +43985,16 @@ /obj/machinery/firealarm/directional/south, /turf/open/floor/iron, /area/station/science/research) +"pbc" = ( +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/railing{ + dir = 4 + }, +/obj/effect/turf_decal/siding/white{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "pbf" = ( /obj/effect/turf_decal/siding/blue/corner{ dir = 1 @@ -44690,13 +44757,6 @@ }, /turf/closed/wall, /area/station/security/checkpoint/supply) -"poj" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment, -/obj/effect/landmark/start/shaft_miner, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "pom" = ( /turf/open/floor/iron, /area/station/engineering/storage_shared) @@ -44736,16 +44796,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/medbay/central) -"poS" = ( -/obj/effect/turf_decal/siding/purple{ - dir = 8 - }, -/obj/structure/chair/office/light{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/science/genetics) "ppo" = ( /obj/machinery/light/small/directional/south, /obj/machinery/atmospherics/components/tank/air/layer4{ @@ -44906,6 +44956,12 @@ dir = 1 }, /area/station/engineering/atmos) +"prU" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 1 + }, +/turf/open/floor/iron/white, +/area/station/science/research) "prY" = ( /obj/structure/cable, /turf/open/floor/iron/dark, @@ -46668,6 +46724,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/engine, /area/station/engineering/supermatter/room) +"pWD" = ( +/obj/effect/turf_decal/tile/blue/anticorner/contrasted{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron/white/corner, +/area/station/medical/medbay/lobby) "pWN" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/public/glass{ @@ -46889,20 +46952,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) -"qbq" = ( -/obj/machinery/power/apc/auto_name/directional/north, -/obj/structure/cable, -/obj/effect/turf_decal/siding/wood, -/obj/effect/turf_decal/siding/wood{ - dir = 1 - }, -/obj/machinery/light/small/directional/north, -/obj/structure/disposalpipe/trunk{ - dir = 8 - }, -/obj/machinery/disposal/bin, -/turf/open/floor/wood/large, -/area/station/command/heads_quarters/qm) "qbr" = ( /obj/structure/bed/medical{ dir = 4 @@ -48271,6 +48320,18 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/command) +"qAf" = ( +/obj/effect/turf_decal/tile/blue/anticorner/contrasted{ + dir = 4 + }, +/mob/living/basic/bot/medbot/autopatrol, +/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/white/corner{ + dir = 8 + }, +/area/station/medical/medbay/lobby) "qAA" = ( /obj/machinery/newscaster/directional/east, /obj/machinery/computer/security/mining{ @@ -48633,19 +48694,6 @@ /obj/structure/sign/warning/docking, /turf/closed/wall, /area/station/hallway/secondary/entry) -"qHt" = ( -/obj/structure/railing{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/machinery/conveyor_switch/oneway{ - id = "mining"; - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "qHK" = ( /obj/effect/spawner/random/structure/grille, /turf/open/floor/plating, @@ -48782,6 +48830,16 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central) +"qJV" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/structure/disposalpipe/segment, +/obj/structure/chair/office/light{ + dir = 4 + }, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "qKg" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -48818,6 +48876,17 @@ /obj/machinery/atmospherics/pipe/smart/simple/yellow/visible, /turf/open/floor/plating, /area/station/engineering/atmos) +"qLe" = ( +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/stripes/white/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/white/line{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron/dark, +/area/station/science/research) "qLk" = ( /obj/structure/table/glass, /obj/item/paper_bin, @@ -48848,6 +48917,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/wood, /area/station/service/theater) +"qLu" = ( +/obj/effect/turf_decal/siding/purple{ + dir = 1 + }, +/obj/machinery/light/directional/south, +/turf/open/floor/iron/white, +/area/station/science/research) "qLw" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -49066,16 +49142,6 @@ /obj/machinery/light/cold/directional/south, /turf/open/floor/iron/white, /area/station/medical/surgery/aft) -"qOs" = ( -/obj/machinery/door/airlock/maintenance{ - name = "Genetics 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/science/genetics, -/turf/open/floor/plating, -/area/station/maintenance/aft/lesser) "qOu" = ( /obj/structure/disposalpipe/segment{ dir = 5 @@ -49335,13 +49401,6 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/engineering/atmos) -"qSe" = ( -/obj/effect/spawner/random/entertainment/slot_machine{ - pixel_y = 2 - }, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/wood, -/area/station/maintenance/port/aft) "qSf" = ( /obj/structure/extinguisher_cabinet/directional/east, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -49402,20 +49461,6 @@ /obj/machinery/light_switch/directional/north, /turf/open/floor/iron/dark, /area/station/science/ordnance) -"qTf" = ( -/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ - dir = 1 - }, -/obj/machinery/conveyor{ - dir = 9; - id = "mining" - }, -/obj/structure/railing{ - dir = 8 - }, -/obj/item/radio/intercom/directional/south, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "qTz" = ( /obj/structure/cable, /obj/machinery/light_switch/directional/west, @@ -49490,6 +49535,14 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/port/fore) +"qTR" = ( +/obj/effect/turf_decal/tile/blue/anticorner/contrasted{ + dir = 8 + }, +/turf/open/floor/iron/white/corner{ + dir = 4 + }, +/area/station/medical/medbay/lobby) "qTS" = ( /obj/structure/window/reinforced/spawner/directional/east, /turf/open/floor/iron/dark, @@ -49608,6 +49661,15 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron/white, /area/station/medical/medbay/central) +"qWX" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/structure/cable, +/turf/open/floor/iron/white, +/area/station/science/research) "qXa" = ( /obj/machinery/firealarm/directional/south, /obj/structure/disposalpipe/segment{ @@ -49725,15 +49787,6 @@ /obj/effect/mapping_helpers/airlock/access/all/engineering/tcoms, /turf/open/floor/iron/dark, /area/station/tcommsat/server) -"qYt" = ( -/obj/structure/table/reinforced, -/obj/item/paper_bin{ - pixel_x = -2; - pixel_y = 6 - }, -/obj/effect/turf_decal/tile/purple/fourcorners, -/turf/open/floor/iron, -/area/station/hallway/primary/aft) "qYC" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable, @@ -49890,6 +49943,16 @@ }, /turf/open/floor/plating, /area/station/maintenance/port/fore) +"rbs" = ( +/obj/structure/table, +/obj/item/stack/medical/mesh, +/obj/item/stack/medical/wrap/gauze, +/obj/item/stack/medical/suture, +/obj/effect/turf_decal/tile/blue/half/contrasted{ + dir = 8 + }, +/turf/open/floor/iron/white, +/area/station/medical/medbay/lobby) "rbw" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -49998,6 +50061,29 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos) +"rdQ" = ( +/obj/structure/table/reinforced, +/obj/machinery/door/firedoor, +/obj/machinery/door/poddoor/shutters/preopen{ + dir = 8; + id = "rdgene2"; + name = "Genetics Lab Shutters" + }, +/obj/machinery/door/window/left/directional/east{ + name = "Genetics Desk"; + req_access = list("genetics") + }, +/obj/effect/turf_decal/tile/purple/fourcorners, +/obj/item/paper_bin{ + pixel_x = -2; + pixel_y = 4 + }, +/obj/item/pen{ + pixel_x = -2; + pixel_y = 5 + }, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "rea" = ( /obj/effect/turf_decal/stripes/red/line{ dir = 5 @@ -50110,29 +50196,6 @@ /obj/machinery/duct, /turf/open/floor/iron/white, /area/station/medical/virology) -"rfF" = ( -/obj/structure/table/glass, -/obj/item/reagent_containers/chem_pack{ - pixel_x = 10; - pixel_y = 10 - }, -/obj/item/storage/box/rxglasses{ - pixel_x = -4; - pixel_y = 8 - }, -/obj/item/stack/medical/wrap/gauze{ - pixel_x = 8 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/siding/white/corner{ - dir = 4 - }, -/obj/effect/turf_decal/tile/blue/fourcorners, -/turf/open/floor/iron/white/side{ - dir = 10 - }, -/area/station/medical/treatment_center) "rfY" = ( /obj/structure/lattice, /obj/structure/sign/warning/electric_shock/directional/east, @@ -50615,6 +50678,12 @@ /obj/machinery/light/floor, /turf/open/floor/iron, /area/station/construction/mining/aux_base) +"rps" = ( +/obj/effect/turf_decal/trimline/blue/filled/corner, +/obj/machinery/duct, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/white, +/area/station/medical/surgery/theatre) "rpt" = ( /obj/structure/toilet{ pixel_y = 8 @@ -50647,6 +50716,12 @@ /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/plating, /area/station/maintenance/port) +"rpG" = ( +/obj/machinery/atmospherics/pipe/smart/manifold/yellow/visible, +/obj/machinery/meter, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/white, +/area/station/science/ordnance/storage) "rpT" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 4 @@ -51273,6 +51348,14 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/security/interrogation) +"rzi" = ( +/obj/machinery/airalarm/directional/north, +/obj/effect/spawner/random/entertainment/slot_machine{ + pixel_y = 2 + }, +/obj/effect/turf_decal/tile/bar/opposingcorners, +/turf/open/floor/iron, +/area/station/commons/lounge) "rzk" = ( /obj/structure/sink/kitchen/directional/west, /mob/living/basic/goat/pete, @@ -51457,10 +51540,6 @@ }, /turf/open/floor/iron, /area/station/security/prison) -"rDB" = ( -/obj/effect/mapping_helpers/burnt_floor, -/turf/open/floor/plating, -/area/station/maintenance/aft/lesser) "rDE" = ( /obj/item/target, /obj/item/target, @@ -51770,6 +51849,23 @@ /obj/effect/mapping_helpers/airlock/access/all/service/theatre, /turf/open/floor/wood, /area/station/maintenance/starboard/greater) +"rJA" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/white/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/white/line{ + dir = 4 + }, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/structure/cable, +/turf/open/floor/iron/dark, +/area/station/science/research) "rJB" = ( /turf/closed/wall/r_wall, /area/station/security/evidence) @@ -52170,23 +52266,6 @@ /obj/effect/mapping_helpers/requests_console/supplies, /turf/open/floor/iron/dark, /area/station/security/checkpoint/medical) -"rQl" = ( -/obj/structure/table/reinforced, -/obj/machinery/door/firedoor, -/obj/machinery/door/poddoor/shutters/preopen{ - dir = 8; - id = "rdgene2"; - name = "Genetics Lab Shutters" - }, -/obj/machinery/door/window/left/directional/east{ - name = "Genetics Desk"; - req_access = list("genetics") - }, -/obj/item/folder, -/obj/item/pen, -/obj/effect/turf_decal/tile/purple/fourcorners, -/turf/open/floor/iron, -/area/station/science/genetics) "rQt" = ( /obj/structure/sign/warning/pods/directional/east, /obj/effect/turf_decal/tile/yellow/anticorner/contrasted, @@ -53136,6 +53215,30 @@ /mob/living/basic/mouse/brown/tom, /turf/open/floor/plating, /area/station/security/prison/safe) +"sgQ" = ( +/obj/structure/table, +/obj/effect/turf_decal/siding/purple{ + dir = 4 + }, +/obj/item/storage/box/monkeycubes{ + pixel_x = 6; + pixel_y = 9 + }, +/obj/item/storage/box/gloves{ + pixel_x = 5; + pixel_y = 1 + }, +/obj/item/storage/box/monkeycubes{ + pixel_x = 4 + }, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/machinery/light/directional/east, +/obj/item/tgui_book/manual/infuser{ + pixel_y = 3; + pixel_x = -10 + }, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "sgX" = ( /obj/machinery/atmospherics/pipe/smart/simple/green/visible{ dir = 4 @@ -53508,6 +53611,14 @@ }, /turf/open/floor/iron/white, /area/station/science/ordnance/testlab) +"snR" = ( +/obj/effect/turf_decal/siding/purple{ + dir = 4 + }, +/obj/structure/extinguisher_cabinet/directional/east, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "snZ" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -54049,12 +54160,6 @@ /obj/effect/landmark/start/janitor, /turf/open/floor/iron, /area/station/service/janitor) -"szM" = ( -/obj/effect/turf_decal/bot, -/obj/item/robot_suit, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/science/robotics/lab) "szO" = ( /obj/structure/cable, /turf/open/floor/wood, @@ -54761,16 +54866,6 @@ }, /turf/open/floor/circuit/green, /area/station/ai/satellite/chamber) -"sLO" = ( -/obj/effect/turf_decal/siding/purple{ - dir = 1 - }, -/obj/machinery/dna_infuser, -/obj/item/tgui_book/manual/infuser, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/obj/structure/window/reinforced/spawner/directional/east, -/turf/open/floor/iron/dark, -/area/station/science/genetics) "sLU" = ( /obj/effect/turf_decal/tile/brown/half/contrasted{ dir = 4 @@ -55324,6 +55419,15 @@ /obj/effect/turf_decal/tile/blue/half/contrasted, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) +"sTU" = ( +/obj/effect/turf_decal/siding/purple{ + dir = 6 + }, +/obj/machinery/power/apc/auto_name/directional/east, +/obj/structure/cable, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "sTW" = ( /obj/effect/turf_decal/tile/yellow, /obj/structure/disposalpipe/segment{ @@ -56045,10 +56149,14 @@ dir = 1 }, /area/station/engineering/atmos/pumproom) -"thm" = ( -/obj/effect/turf_decal/trimline/purple/line, -/turf/open/floor/iron/white, -/area/station/science/research) +"thl" = ( +/obj/structure/cable, +/obj/structure/railing/corner/end/flip{ + dir = 8 + }, +/obj/effect/turf_decal/siding/white, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "thw" = ( /obj/structure/bodycontainer/morgue{ dir = 1 @@ -56072,15 +56180,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/port) -"tid" = ( -/obj/structure/railing/corner/end, -/obj/effect/turf_decal/delivery, -/obj/effect/decal/cleanable/rubble, -/obj/structure/railing/corner/end{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "tik" = ( /obj/structure/disposalpipe/segment, /obj/effect/turf_decal/trimline/brown/filled/line{ @@ -56196,13 +56295,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) -"tkf" = ( -/obj/structure/extinguisher_cabinet/directional/east, -/obj/machinery/conveyor{ - id = "mining" - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "tkg" = ( /obj/machinery/atmospherics/pipe/smart/simple/supply/visible{ dir = 4 @@ -56496,12 +56588,6 @@ /obj/structure/window/reinforced/spawner/directional/south, /turf/open/floor/iron/dark, /area/station/ai/satellite/exterior) -"tpv" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/science/robotics/lab) "tpA" = ( /obj/machinery/cell_charger{ pixel_y = 4 @@ -57193,18 +57279,6 @@ "tBJ" = ( /turf/closed/wall, /area/station/medical/abandoned) -"tBL" = ( -/obj/effect/turf_decal/tile/blue/anticorner/contrasted{ - dir = 4 - }, -/mob/living/basic/bot/medbot/autopatrol, -/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/white/corner{ - dir = 8 - }, -/area/station/medical/medbay/lobby) "tBM" = ( /obj/machinery/atmospherics/pipe/smart/simple/cyan/visible/layer5, /obj/machinery/atmospherics/pipe/smart/simple/purple/visible{ @@ -58774,6 +58848,13 @@ /obj/structure/bed/medical/emergency, /turf/open/floor/iron/white, /area/station/medical/medbay/central) +"ucd" = ( +/obj/machinery/status_display/evac/directional/south, +/obj/effect/turf_decal/siding/purple{ + dir = 1 + }, +/turf/open/floor/iron/white, +/area/station/science/research) "ucf" = ( /obj/structure/table/reinforced, /obj/item/tank/internals/anesthetic{ @@ -58865,6 +58946,11 @@ }, /turf/open/floor/iron, /area/station/construction/storage_wing) +"udY" = ( +/obj/effect/turf_decal/bot, +/mob/living/basic/bot/secbot/beepsky/armsky, +/turf/open/floor/iron/dark, +/area/station/security/armory) "ueh" = ( /obj/machinery/light/small/directional/east, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -59211,6 +59297,19 @@ /obj/machinery/light_switch/directional/east, /turf/open/floor/plating, /area/station/maintenance/disposal) +"ulv" = ( +/obj/effect/turf_decal/stripes/white/line, +/obj/effect/turf_decal/stripes/white/line{ + dir = 1 + }, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/structure/cable, +/turf/open/floor/iron/dark, +/area/station/science/research) "ulA" = ( /obj/structure/lattice, /obj/structure/window/reinforced/spawner/directional/west, @@ -60003,24 +60102,6 @@ }, /turf/open/floor/iron, /area/station/cargo/sorting) -"uyS" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/medical/glass{ - id_tag = "MedbayFoyer"; - name = "Medbay" - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/mapping_helpers/airlock/access/all/medical/general, -/obj/effect/turf_decal/tile/blue/fourcorners, -/obj/effect/mapping_helpers/airlock/unres/delayed{ - dir = 8 - }, -/turf/open/floor/iron/white, -/area/station/medical/medbay/central) "uyY" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -60583,6 +60664,13 @@ /obj/effect/turf_decal/tile/blue/opposingcorners, /turf/open/floor/iron, /area/station/service/hydroponics) +"uHA" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/iron/white, +/area/station/science/ordnance/storage) "uHD" = ( /obj/effect/turf_decal/stripes/line, /obj/structure/disposalpipe/segment, @@ -60875,6 +60963,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/security/execution/transfer) +"uNg" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/iron/textured, +/area/station/cargo/miningoffice) "uNl" = ( /obj/machinery/atmospherics/pipe/smart/simple/orange/visible{ dir = 4 @@ -61338,6 +61435,13 @@ /obj/effect/turf_decal/trimline/red/filled/corner, /turf/open/floor/iron, /area/station/security/brig) +"uWr" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "mining" + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "uWs" = ( /obj/machinery/computer/mech_bay_power_console{ dir = 1 @@ -62277,12 +62381,6 @@ /obj/effect/mapping_helpers/airlock/access/all/engineering/general, /turf/open/floor/plating, /area/station/maintenance/solars/starboard/aft) -"vmb" = ( -/obj/effect/turf_decal/trimline/blue/filled/warning{ - dir = 8 - }, -/turf/open/floor/iron/white, -/area/station/medical/medbay/lobby) "vmk" = ( /obj/machinery/status_display/ai/directional/west, /turf/open/floor/circuit, @@ -62367,6 +62465,20 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/iron, /area/station/commons/vacant_room/commissary) +"vnI" = ( +/obj/effect/turf_decal/tile/purple/fourcorners, +/obj/effect/turf_decal/loading_area{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/hallway/primary/aft) +"vnN" = ( +/obj/effect/turf_decal/siding/purple{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "vnV" = ( /obj/machinery/airalarm/directional/west, /obj/effect/turf_decal/siding/wood{ @@ -62431,19 +62543,6 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/iron, /area/station/engineering/main) -"vpe" = ( -/obj/machinery/door/airlock/medical/glass{ - name = "Primary Treatment Centre" - }, -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/access/all/medical/general, -/obj/effect/turf_decal/tile/blue/fourcorners, -/obj/effect/landmark/navigate_destination, -/obj/effect/mapping_helpers/airlock/unres/delayed{ - dir = 8 - }, -/turf/open/floor/iron/white, -/area/station/medical/treatment_center) "vpg" = ( /obj/machinery/door/poddoor/preopen{ id = "bridge blast"; @@ -62554,6 +62653,13 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/service) +"vqy" = ( +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 8 + }, +/mob/living/basic/bot/secbot/beepsky/officer, +/turf/open/floor/iron, +/area/station/security/brig) "vqU" = ( /obj/structure/cable, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -63304,15 +63410,6 @@ /obj/effect/landmark/start/paramedic, /turf/open/floor/iron/dark/smooth_large, /area/station/medical/paramedic) -"vDL" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/disposalpipe/segment{ - dir = 5 - }, -/obj/structure/cable, -/turf/open/floor/iron/white, -/area/station/science/research) "vDV" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -63430,6 +63527,11 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central) +"vEU" = ( +/obj/structure/rack, +/obj/effect/spawner/random/maintenance, +/turf/open/floor/plating, +/area/station/maintenance/aft/lesser) "vEV" = ( /obj/machinery/space_heater, /obj/effect/decal/cleanable/cobweb, @@ -63842,6 +63944,19 @@ /obj/item/storage/dice, /turf/open/floor/wood, /area/station/commons/lounge) +"vLV" = ( +/obj/machinery/conveyor_switch/oneway{ + id = "mining"; + dir = 1 + }, +/obj/structure/railing{ + dir = 4 + }, +/obj/effect/turf_decal/siding/white{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "vLW" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -64108,17 +64223,6 @@ /obj/machinery/firealarm/directional/south, /turf/open/floor/iron/dark, /area/station/engineering/storage/tech) -"vQy" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/light/directional/north, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/airalarm/directional/north, -/obj/structure/cable, -/turf/open/floor/iron/white, -/area/station/science/research) "vQA" = ( /obj/item/radio/intercom/directional/east, /turf/open/floor/wood, @@ -64613,6 +64717,15 @@ /obj/effect/spawner/random/trash/mess, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) +"vXW" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "vXZ" = ( /obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -64720,10 +64833,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/space_hut) -"vZB" = ( -/obj/structure/sign/directions/evac, -/turf/closed/wall, -/area/station/maintenance/aft/lesser) "vZE" = ( /obj/effect/spawner/random/structure/crate, /turf/open/floor/plating, @@ -64872,13 +64981,6 @@ /obj/effect/turf_decal/tile/blue/fourcorners, /turf/open/floor/iron/white, /area/station/medical/storage) -"waP" = ( -/obj/machinery/status_display/evac/directional/south, -/obj/effect/turf_decal/siding/purple{ - dir = 1 - }, -/turf/open/floor/iron/white, -/area/station/science/research) "wbF" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -65508,38 +65610,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/dark, /area/station/science/ordnance) -"wnl" = ( -/obj/structure/table, -/obj/effect/turf_decal/siding/purple{ - dir = 4 - }, -/obj/item/storage/box/monkeycubes{ - pixel_x = 6; - pixel_y = 9 - }, -/obj/item/storage/box/gloves{ - pixel_x = 5; - pixel_y = 1 - }, -/obj/item/storage/box/monkeycubes{ - pixel_x = 4 - }, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/obj/machinery/light/directional/east, -/turf/open/floor/iron/dark, -/area/station/science/genetics) -"wns" = ( -/obj/structure/table, -/obj/item/stack/medical/wrap/gauze, -/obj/item/stack/medical/mesh, -/obj/item/stack/medical/suture, -/obj/machinery/power/apc/auto_name/directional/north, -/obj/structure/cable, -/obj/effect/turf_decal/tile/blue/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron/white, -/area/station/medical/medbay/lobby) "wnQ" = ( /obj/structure/tank_dispenser{ pixel_x = -1 @@ -66243,17 +66313,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) -"wyP" = ( -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 1 - }, -/obj/machinery/conveyor{ - dir = 8; - id = "mining" - }, -/obj/machinery/bouldertech/refinery/smelter, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "wyV" = ( /turf/open/floor/carpet/orange, /area/station/command/heads_quarters/qm) @@ -66461,21 +66520,6 @@ /obj/structure/sign/warning/vacuum/directional/west, /turf/open/floor/plating, /area/station/maintenance/disposal) -"wCi" = ( -/obj/structure/table/glass, -/obj/effect/turf_decal/tile/blue/fourcorners, -/obj/item/tgui_book/manual/dsm{ - pixel_y = 3; - pixel_x = -2 - }, -/obj/machinery/newscaster/directional/west, -/obj/item/tgui_book/manual/idc{ - pixel_y = 3; - pixel_x = 3 - }, -/obj/item/book/manual/wiki/medicine, -/turf/open/floor/iron/white, -/area/station/medical/treatment_center) "wCl" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -66891,6 +66935,15 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/iron, /area/station/hallway/secondary/entry) +"wLk" = ( +/obj/structure/railing{ + dir = 6 + }, +/obj/effect/turf_decal/siding/white{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "wLu" = ( /obj/structure/chair/office{ dir = 8 @@ -66925,6 +66978,16 @@ dir = 8 }, /area/station/medical/chem_storage) +"wMh" = ( +/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron/textured, +/area/station/cargo/miningoffice) "wMx" = ( /obj/effect/turf_decal/bot, /obj/effect/landmark/start/hangover, @@ -66954,6 +67017,17 @@ /obj/structure/window/reinforced/spawner/directional/north, /turf/open/floor/iron/dark/corner, /area/station/engineering/atmos/storage/gas) +"wMZ" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron/dark, +/area/station/science/genetics) +"wNa" = ( +/obj/effect/turf_decal/siding/purple{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron/white, +/area/station/science/research) "wNh" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/blue{ @@ -67478,6 +67552,15 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/iron, /area/station/commons/fitness/recreation) +"wVZ" = ( +/obj/machinery/door/poddoor/shutters/preopen{ + dir = 1; + id = "rdgene"; + name = "Genetics Lab Shutters" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/station/science/genetics) "wWe" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -67630,18 +67713,6 @@ }, /turf/open/floor/iron/grimy, /area/station/tcommsat/computer) -"wZo" = ( -/obj/machinery/airalarm/directional/east, -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 1 - }, -/obj/machinery/conveyor{ - dir = 10; - id = "mining" - }, -/obj/machinery/bouldertech/refinery, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "wZw" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -67789,12 +67860,6 @@ /obj/structure/window/spawner/directional/south, /turf/open/floor/iron, /area/station/engineering/atmos) -"xcX" = ( -/obj/machinery/atmospherics/pipe/smart/manifold/yellow/visible, -/obj/machinery/meter, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/white, -/area/station/science/ordnance/storage) "xdm" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/cable, @@ -68015,19 +68080,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/ai/satellite/maintenance/storage) -"xgF" = ( -/obj/effect/turf_decal/stripes/white/line, -/obj/effect/turf_decal/stripes/white/line{ - dir = 1 - }, -/obj/machinery/door/firedoor, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/obj/structure/cable, -/turf/open/floor/iron/dark, -/area/station/science/research) "xgG" = ( /obj/effect/decal/cleanable/cobweb/cobweb2, /obj/structure/rack, @@ -68331,13 +68383,6 @@ }, /turf/open/floor/iron/dark, /area/station/service/chapel) -"xlC" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/iron/white, -/area/station/science/ordnance/storage) "xlF" = ( /turf/open/floor/iron, /area/station/service/hydroponics) @@ -68877,17 +68922,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/hidden/layer4, /turf/closed/wall/r_wall, /area/station/maintenance/aft/lesser) -"xuY" = ( -/obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/white/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/white/line{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/science/research) "xvd" = ( /obj/structure/closet/emcloset, /obj/effect/turf_decal/delivery, @@ -68912,15 +68946,6 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/iron, /area/station/commons/fitness/recreation) -"xvI" = ( -/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/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/station/science/genetics) "xvQ" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -69072,6 +69097,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, /area/station/medical/medbay/central) +"xxY" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/siding/purple/corner{ + dir = 8 + }, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "xxZ" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 8 @@ -69475,6 +69509,10 @@ }, /turf/open/floor/iron, /area/station/service/hydroponics) +"xEf" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, +/turf/open/floor/iron/white/smooth_large, +/area/station/medical/medbay/lobby) "xEg" = ( /obj/machinery/light/small/directional/south, /turf/open/floor/engine/plasma, @@ -69700,6 +69738,15 @@ }, /turf/open/floor/iron/dark, /area/station/security/checkpoint/supply) +"xJp" = ( +/obj/structure/extinguisher_cabinet/directional/east, +/obj/effect/decal/cleanable/greenglow/waste{ + opacity = 1; + alpha = 50 + }, +/obj/effect/turf_decal/tile/brown/opposingcorners, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "xJv" = ( /obj/machinery/light/directional/north, /turf/open/floor/iron/recharge_floor, @@ -70110,6 +70157,12 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/wood, /area/station/security/office) +"xQY" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, +/turf/open/floor/iron/white/smooth_large, +/area/station/medical/medbay/lobby) "xRa" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -70211,6 +70264,21 @@ /obj/effect/turf_decal/tile/purple/opposingcorners, /turf/open/floor/iron, /area/station/science/research) +"xTn" = ( +/obj/machinery/camera/directional/north{ + c_tag = "Starboard Primary Hallway - Auxiliary Tool Storage" + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/landmark/start/hangover, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/hallway/primary/starboard) "xTw" = ( /turf/closed/wall/r_wall, /area/station/medical/medbay/central) @@ -70335,6 +70403,10 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos/pumproom) +"xVD" = ( +/obj/effect/turf_decal/trimline/purple/corner, +/turf/open/floor/iron/white, +/area/station/science/research) "xWm" = ( /obj/structure/rack, /obj/item/restraints/handcuffs{ @@ -70689,6 +70761,16 @@ /obj/machinery/firealarm/directional/south, /turf/open/floor/iron, /area/station/security/prison/work) +"ybf" = ( +/obj/machinery/dna_infuser, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/structure/window/reinforced/spawner/directional/west, +/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/siding/purple{ + dir = 1 + }, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "ybl" = ( /obj/structure/closet/secure_closet/engineering_personal, /obj/effect/turf_decal/delivery, @@ -70850,11 +70932,6 @@ }, /turf/open/floor/iron/dark, /area/station/engineering/atmos) -"ydi" = ( -/obj/structure/railing/corner/end/flip, -/obj/effect/turf_decal/stripes/corner, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "ydj" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/manifold4w/dark/visible, @@ -70974,6 +71051,18 @@ /obj/structure/cable, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/hos) +"yfa" = ( +/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ + dir = 1 + }, +/obj/item/radio/intercom/directional/south, +/obj/effect/decal/cleanable/rubble, +/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/siding/white{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "yfg" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/shutters/preopen{ @@ -71249,6 +71338,18 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central) +"ylb" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/siding/purple{ + dir = 4 + }, +/obj/structure/table, +/obj/machinery/computer/records/medical/laptop{ + dir = 8; + pixel_y = 1 + }, +/turf/open/floor/iron/dark, +/area/station/science/genetics) "ylf" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 4 @@ -85842,7 +85943,7 @@ vZE tYi ndN jUb -qSe +ebG fQD uxS uxS @@ -86099,7 +86200,7 @@ wvr vzY tYi jUb -dAD +eov ruz ehn uxS @@ -86356,7 +86457,7 @@ sXI cYY tYZ jUb -fud +hWj coJ uxS fNI @@ -86635,7 +86736,7 @@ rjB jUb aaa xjH -dhv +ocN gbz uGq iam @@ -88435,7 +88536,7 @@ jUb huF xjH cQo -mOU +odX vYJ xjH aaa @@ -89133,7 +89234,7 @@ unc xyz jGb uMj -poj +lvr hnV tPt gUH @@ -89387,11 +89488,11 @@ beo sLU aZj cSP -cLj -kRe -kRe -tid -qTf +krW +pbc +vLV +wLk +yfa hKg cbz cKD @@ -89644,11 +89745,11 @@ jXu jXu jXu hzb -cLj -kRe -kRe -cBZ -wyP +jzd +jyy +fMP +gRn +nYI hKg kyf kFQ @@ -89900,12 +90001,12 @@ duG omV kts cuh -fDV -cLj -ydi -qHt -dxo -hlE +jBp +thl +uWr +wMh +uNg +lQS hKg ljT jrQ @@ -90158,11 +90259,11 @@ cAf dve jXu pVV -cLj -cUt -iId -tkf -wZo +gLT +eiJ +dom +xJp +koY hKg rgW nkq @@ -90478,8 +90579,8 @@ pHv saA hmo gXv -gTp -dvB +izl +rps eme eyl jUb @@ -90735,9 +90836,9 @@ jUb jsj bNa ixv -auL +jml wRZ -aFc +mPF ucf jUb oOZ @@ -91253,7 +91354,7 @@ guC fTE hBY bKl -wCi +aQJ vun abF uLs @@ -92007,7 +92108,7 @@ anv rur knK sQx -eQc +kir nPt sHd pBs @@ -92021,7 +92122,7 @@ iMv nKE vSu jtA -rfF +nVJ bHE ktD bbd @@ -92223,7 +92324,7 @@ pNC uqX loR kQP -qbq +ewc dFg wyV wyV @@ -92272,7 +92373,7 @@ jkT fUu uPi sfF -aSy +mYf hcU isu ekk @@ -93040,7 +93141,7 @@ pOa bMY haX fFV -bnH +odu rEu azW sSp @@ -93297,7 +93398,7 @@ lvU bMY rvq fFi -gED +iWD vDz pBN sSp @@ -93309,7 +93410,7 @@ ckE gHq bJk mpk -nST +che vun eFG lWX @@ -93561,9 +93662,9 @@ sSp sSp sSp jxc -vpe +oXr jxc -icG +aOx jxc sSp sSp @@ -94065,7 +94166,7 @@ vVV htd tAG gDv -miS +euc iPM mvY oYp @@ -94843,8 +94944,8 @@ qPJ qPJ qPJ fEK -uyS -fYP +akG +ePZ duu pKP nGJ @@ -96123,8 +96224,8 @@ ebM uRA mTk nTD -laZ -ixC +rbs +jHA lln nBB nbT @@ -96381,8 +96482,8 @@ lYL xIG ryo nxy -ngI -lfT +xEf +lWG gsW izA bHQ @@ -96639,7 +96740,7 @@ mTk asm vLf vLf -kHv +kXD kWO rvE whx @@ -96894,9 +96995,9 @@ iKT ceM axW xEX -dmT -tBL -jZi +hYr +qAf +lrR qwI xJI tIx @@ -97151,8 +97252,8 @@ tHR lYL pbL mum -oiR -agA +qTR +pWD sTQ hEc hGF @@ -97408,8 +97509,8 @@ tHR lYL mTk noD -vmb -gDy +aNf +aNa xiv dwZ cJv @@ -97666,7 +97767,7 @@ sTz xIG bKB nxy -lVy +xQY kcF cYJ oar @@ -97921,7 +98022,7 @@ sNl aZR lYL pBa -wns +aNQ nxy nxy aYJ @@ -98117,7 +98218,7 @@ loY tTP fdQ uou -agc +udY apM aeq dFW @@ -98976,8 +99077,8 @@ gmt qhx ceZ ceZ +ceZ lGT -gmt xDz gmt rDM @@ -99231,7 +99332,8 @@ kor aQS qCY kQe -qYt +vnI +ajN qDa oIg oIg @@ -99239,10 +99341,9 @@ oIg oIg oIg oIg -svS -vZB +aNL +dKC dKC -vZB dKC dKC ufZ @@ -99408,7 +99509,7 @@ ahj jxV ayV gFR -khm +vqy uok vMj ezg @@ -99488,8 +99589,9 @@ orv dPY xWJ oIg +rdQ cId -rQl +hSJ oIg wBq bEC @@ -99498,8 +99600,7 @@ aXW jxW svS rhU -kYP -mGI +nFa jjs dKC gFC @@ -99745,8 +99846,9 @@ ujJ ujJ ujJ oIg -cDM -poS +iKO +vnN +eMv byf kBu oir @@ -99755,7 +99857,6 @@ tzg jxW svS tjE -rDB xpE lqh dKC @@ -99993,7 +100094,7 @@ kFS uqv ctn reL -szM +ise wqh ekB aJa @@ -100001,9 +100102,10 @@ eut gle xYV syC -gqm -sLO +wVZ +ybf lOr +wMZ sNS qXK xoa @@ -100013,7 +100115,6 @@ oCE svS dKC dKC -dKC tNM dKC gtm @@ -100250,7 +100351,7 @@ uwK wmg jAt mET -eOA +liD iAk nSB fXd @@ -100261,14 +100362,14 @@ cSN eZz sAF hZO -xvI -jBk +qJV +vXW qNz -mZO -klu +jBk +xxY +iqu vjk -qOs -kZk +eRB kZk kZk kZk @@ -100515,20 +100616,20 @@ dpg bBo gwf gfZ -gqm +wVZ jZP aIO jrb -wnl +sgQ eOo rRJ -edH -mHL -svS -oHO +snR +ylb +sTU +oIg ove lJw -nFa +vEU xhs goF lXC @@ -100764,7 +100865,7 @@ wfm eut eut xhO -tpv +kiy qDy voE deH @@ -100781,8 +100882,8 @@ oIg oIg oIg oIg -svS -svS +oIg +oIg svS svS svS @@ -101019,8 +101120,8 @@ uqp kaF bse eIV -iWP -jVx +gcU +noN bCc bCc jaQ @@ -102306,10 +102407,10 @@ gwf gwf gwf gwf -kya +wNa nmZ pLs -kgK +xVD swV ili cpW @@ -102564,9 +102665,9 @@ rWL htn muB iRc -xgF -vDL -thm +ulv +qWX +fke eMW dGa wwW @@ -102822,16 +102923,16 @@ vcE oBz xKK xKK -vQy -thm +euQ +fke uLK aYb wwW lrp rYI fmM -amF -xcX +iWy +rpG qKn gJl gyQ @@ -103079,15 +103180,15 @@ qdT vTK tEt xKk -fqP -mWq +jHg +dmO kXY kXY lfG lrp rYI cml -xlC +uHA btL iAp sUP @@ -103336,8 +103437,8 @@ mzg rHh tEt tKR -lhe -cWz +fjb +prU aJd afZ sds @@ -103593,8 +103694,8 @@ pke msJ xKK xKK -kkn -xuY +rJA +qLe oaB mMX mMX @@ -103876,7 +103977,7 @@ qXW dKC rzx hcP -kYP +bra lDs dKC aaa @@ -104351,7 +104452,7 @@ kMG tUn hKV wXF -cjD +btA dJo rCx nBj @@ -105603,7 +105704,7 @@ ksk mxt ksk dZm -mta +xTn pxl tUu jKi @@ -105651,7 +105752,7 @@ lAe tAg pbt gwf -kVf +mLu oWk xuD fFa @@ -105893,7 +105994,7 @@ jgK tUn dQT wXF -jSk +jhL ukF sIW jSk @@ -105908,7 +106009,7 @@ nfs tAg sWB gwf -fao +qLu oWk xuD sip @@ -106422,7 +106523,7 @@ ewh elJ qNA gwf -waP +ucd oWk xuD qZg @@ -106892,7 +106993,7 @@ egn tqU kLh rac -khi +nXG eoo fqD qcQ @@ -106936,7 +107037,7 @@ aPX elJ wGH emh -eWS +fQo oWk xuD qZg @@ -107149,7 +107250,7 @@ hJI fRS tUv rac -kAQ +rzi eoo wkX qcQ @@ -107918,7 +108019,7 @@ lkW xww aSk tlZ -lje +hfG klZ bqC fqD @@ -126166,7 +126267,7 @@ nFe bhc mgj piw -jvO +ddK wNm shc art diff --git a/_maps/map_files/Mining/Lavaland.dmm b/_maps/map_files/Mining/Lavaland.dmm index a1c171b5ebd..3912d3676aa 100644 --- a/_maps/map_files/Mining/Lavaland.dmm +++ b/_maps/map_files/Mining/Lavaland.dmm @@ -87,6 +87,10 @@ }, /turf/open/floor/carpet/neon/simple/red/nodots, /area/mine/cafeteria) +"ay" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/turf/open/floor/iron/dark/textured_large, +/area/mine/eva) "aD" = ( /obj/structure/lattice/catwalk, /obj/structure/cable, @@ -226,7 +230,6 @@ /turf/open/floor/iron/smooth, /area/mine/laborcamp) "bK" = ( -/obj/item/kirbyplants/random, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/turf_decal/trimline/blue/filled/line{ @@ -236,6 +239,7 @@ dir = 4 }, /obj/structure/sign/poster/official/corporate_perks_vacation/directional/west, +/obj/item/kirbyplants/random, /turf/open/floor/iron/edge{ dir = 4 }, @@ -427,6 +431,14 @@ dir = 1 }, /area/mine/lounge) +"cL" = ( +/obj/effect/turf_decal/trimline/brown/filled/line, +/obj/structure/table, +/obj/item/paper/fluff/stations/lavaland/orm_notice, +/turf/open/floor/iron/dark/smooth_edge{ + dir = 1 + }, +/area/mine/production) "cM" = ( /obj/structure/closet/emcloset, /obj/effect/turf_decal/trimline/yellow/filled/arrow_cw{ @@ -457,16 +469,6 @@ dir = 1 }, /area/mine/laborcamp/quarters) -"cR" = ( -/obj/structure/cable, -/obj/machinery/airalarm/directional/east, -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 4 - }, -/turf/open/floor/iron/dark/smooth_edge{ - dir = 8 - }, -/area/mine/production) "cU" = ( /obj/structure/lattice/catwalk/mining, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -609,9 +611,6 @@ pixel_y = 12; pixel_x = 10 }, -/obj/structure/chair/plastic{ - dir = 4 - }, /turf/open/misc/hay/lavaland, /area/lavaland/surface/outdoors) "dI" = ( @@ -698,6 +697,13 @@ }, /turf/open/misc/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) +"eu" = ( +/obj/structure/lattice/catwalk/mining, +/obj/structure/railing/corner{ + dir = 8 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors) "ey" = ( /obj/structure/lattice/catwalk/mining, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -966,7 +972,7 @@ "fS" = ( /obj/structure/cable, /obj/effect/turf_decal/trimline/red/filled/line, -/mob/living/simple_animal/bot/secbot/beepsky/ofitser, +/mob/living/basic/bot/secbot/beepsky/ofitser, /turf/open/floor/iron/dark/smooth_edge{ dir = 1 }, @@ -1332,6 +1338,10 @@ /obj/structure/lattice/catwalk, /turf/open/misc/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) +"hA" = ( +/obj/structure/flora/bush/jungle/b/style_random, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) "hB" = ( /obj/structure/cable, /obj/machinery/light/directional/north, @@ -1569,12 +1579,6 @@ }, /turf/open/floor/iron/checker, /area/mine/cafeteria) -"iI" = ( -/obj/machinery/power/weather_tower, -/obj/structure/lattice/catwalk, -/obj/structure/cable, -/turf/open/misc/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) "iN" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -1883,6 +1887,14 @@ /obj/structure/cable, /turf/open/floor/plating, /area/mine/maintenance/living/north) +"kx" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/lattice/catwalk/mining, +/obj/structure/railing/corner, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors) "kB" = ( /obj/structure/stone_tile/surrounding_tile, /obj/structure/stone_tile/surrounding_tile{ @@ -1969,10 +1981,18 @@ /turf/open/lava/smooth/lava_land_surface, /area/lavaland/surface/outdoors) "kK" = ( -/obj/structure/table, /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 1 }, +/obj/machinery/camera/autoname/directional/north{ + network = list("mine") + }, +/obj/machinery/light/small/directional/north, +/obj/structure/sign/directions/evac/directional/east{ + pixel_x = 0; + pixel_y = 24 + }, +/obj/structure/table, /obj/item/camera_film{ pixel_x = 5; pixel_y = 5 @@ -2441,6 +2461,21 @@ dir = 1 }, /area/mine/laborcamp/security) +"mG" = ( +/obj/machinery/door/airlock/external/glass{ + name = "Mining External Airlock" + }, +/obj/effect/turf_decal/trimline/blue/filled/line{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/blue/filled/mid_joiner{ + dir = 1 + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{ + cycle_id = "lavaland_living_north" + }, +/turf/open/floor/iron/textured_large, +/area/mine/lounge) "mJ" = ( /obj/docking_port/stationary{ dwidth = 2; @@ -2893,6 +2928,13 @@ }, /turf/open/misc/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) +"oE" = ( +/obj/structure/lattice/catwalk/mining, +/obj/structure/railing{ + dir = 6 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors) "oI" = ( /obj/structure/bed, /obj/effect/decal/cleanable/dirt, @@ -2982,6 +3024,10 @@ /obj/effect/spawner/random/trash/hobo_squat, /turf/open/floor/plating, /area/mine/maintenance/public/south) +"ph" = ( +/obj/structure/flora/bush/jungle/c/style_random, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) "pm" = ( /obj/structure/stone_tile/block/cracked{ dir = 8 @@ -3010,15 +3056,6 @@ /obj/effect/spawner/random/trash/mess, /turf/open/floor/iron/white, /area/mine/laborcamp/production) -"ps" = ( -/obj/structure/cable, -/obj/machinery/power/smes/super/full{ - output_level = 100000; - input_level = 100000 - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/mine/maintenance/service) "pu" = ( /obj/item/chair/stool{ pixel_x = -2; @@ -3638,7 +3675,6 @@ /turf/open/floor/plating, /area/mine/maintenance/service) "ti" = ( -/obj/structure/table, /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 1 }, @@ -3651,6 +3687,9 @@ }, /turf/open/misc/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) +"tl" = ( +/turf/open/water/lavaland_atmos/basalt, +/area/lavaland/surface/outdoors) "tr" = ( /obj/structure/closet/secure_closet/brig, /obj/effect/decal/cleanable/dirt, @@ -4130,6 +4169,10 @@ }, /turf/open/floor/iron/checker, /area/mine/cafeteria) +"wc" = ( +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/iron/textured_large, +/area/mine/lounge) "wg" = ( /obj/structure/chair/sofa/corp{ dir = 1 @@ -4231,10 +4274,6 @@ /obj/item/chair/wood, /turf/open/misc/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) -"wG" = ( -/obj/structure/lattice/catwalk, -/turf/open/misc/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) "wJ" = ( /obj/structure/table/wood/poker, /obj/item/toy/cards/deck{ @@ -4582,6 +4621,10 @@ /obj/structure/lattice/catwalk/mining, /turf/open/lava/smooth/lava_land_surface, /area/lavaland/surface/outdoors) +"yW" = ( +/obj/structure/flora/bush/jungle, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) "yX" = ( /obj/effect/spawner/structure/window, /turf/open/floor/plating, @@ -4676,6 +4719,16 @@ /obj/structure/lattice/catwalk/mining, /turf/open/lava/smooth/lava_land_surface, /area/lavaland/surface/outdoors) +"zt" = ( +/obj/machinery/power/apc/auto_name/directional/south, +/obj/structure/cable, +/obj/effect/turf_decal/trimline/brown/filled/line, +/obj/structure/table, +/obj/item/storage/medkit/regular, +/turf/open/floor/iron/dark/smooth_edge{ + dir = 1 + }, +/area/mine/production) "zw" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -4703,10 +4756,12 @@ /turf/open/floor/iron/dark, /area/mine/production) "zF" = ( -/obj/item/kirbyplants/random, /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 6 }, +/obj/machinery/computer/shuttle/mining/common{ + dir = 8 + }, /turf/open/floor/iron, /area/mine/lounge) "zH" = ( @@ -4770,6 +4825,13 @@ /obj/structure/railing/corner, /turf/open/misc/hay/lavaland, /area/lavaland/surface/outdoors) +"Ac" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 6 + }, +/obj/item/radio/intercom/directional/east, +/turf/open/floor/iron/dark, +/area/mine/production) "Ae" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -4950,6 +5012,13 @@ }, /turf/open/misc/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) +"BE" = ( +/obj/structure/lattice/catwalk/mining, +/obj/structure/railing{ + dir = 4 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors) "BH" = ( /obj/structure/window/spawner/directional/south, /obj/effect/turf_decal/trimline/green/filled/line{ @@ -5152,6 +5221,10 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/mine/maintenance/living/north) +"CY" = ( +/obj/structure/flora/ash/cacti, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) "CZ" = ( /obj/structure/disposalpipe/segment, /obj/structure/lattice/catwalk/mining, @@ -5298,6 +5371,10 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/plating, /area/mine/maintenance/living/north) +"El" = ( +/obj/structure/lattice/catwalk, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) "Eo" = ( /obj/machinery/conveyor{ id = "mining_disposals" @@ -5463,6 +5540,13 @@ }, /turf/open/misc/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) +"Fo" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/lattice/catwalk/mining, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors) "Fp" = ( /obj/structure/table, /obj/machinery/recharger, @@ -6104,10 +6188,6 @@ }, /turf/open/floor/plating, /area/mine/laborcamp/security/maintenance) -"Jp" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/turf/open/floor/iron/dark/textured_large, -/area/mine/eva) "Jt" = ( /obj/machinery/disposal/bin, /obj/structure/disposalpipe/trunk{ @@ -6138,14 +6218,9 @@ /turf/open/lava/smooth/lava_land_surface, /area/lavaland/surface/outdoors) "JA" = ( -/obj/machinery/computer/shuttle/mining/common, -/obj/machinery/camera/autoname/directional/north{ - network = list("mine") - }, /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 5 }, -/obj/machinery/light/small/directional/north, /turf/open/floor/iron, /area/mine/lounge) "JB" = ( @@ -6267,6 +6342,12 @@ /obj/structure/stone_tile, /turf/open/misc/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) +"JX" = ( +/obj/machinery/power/weather_tower, +/obj/structure/lattice/catwalk, +/obj/structure/cable, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) "JZ" = ( /obj/structure/displaycase, /turf/open/floor/carpet/executive, @@ -6289,6 +6370,11 @@ dir = 4 }, /area/mine/eva) +"Ke" = ( +/obj/structure/lattice/catwalk/mining, +/obj/structure/railing/corner, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors) "Kf" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -6351,6 +6437,18 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/smooth_large, /area/mine/laborcamp) +"Kr" = ( +/obj/structure/table, +/obj/item/storage/toolbox/mechanical{ + pixel_x = -2; + pixel_y = 4 + }, +/obj/effect/turf_decal/trimline/brown/filled/line, +/obj/item/storage/medkit/regular, +/turf/open/floor/iron/dark/smooth_edge{ + dir = 1 + }, +/area/mine/eva) "Kt" = ( /obj/structure/stone_tile/cracked, /obj/structure/stone_tile/cracked{ @@ -6413,6 +6511,16 @@ }, /turf/open/floor/iron/checker, /area/mine/cafeteria) +"KT" = ( +/obj/structure/cable, +/obj/machinery/airalarm/directional/east, +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 4 + }, +/turf/open/floor/iron/dark/smooth_edge{ + dir = 8 + }, +/area/mine/production) "KV" = ( /obj/structure/table, /obj/machinery/light/directional/east, @@ -6551,6 +6659,13 @@ /obj/machinery/portable_atmospherics/canister/oxygen, /turf/open/floor/plating, /area/mine/storage) +"LB" = ( +/obj/structure/lattice/catwalk/mining, +/obj/structure/railing/corner{ + dir = 1 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors) "LE" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 8 @@ -6721,6 +6836,13 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/smooth_large, /area/mine/laborcamp) +"MC" = ( +/obj/item/bait_can/worm/premium{ + pixel_y = 8; + pixel_x = -9 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) "MD" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -6983,13 +7105,6 @@ }, /turf/open/floor/plating/lavaland_atmos, /area/lavaland/surface/outdoors) -"Ob" = ( -/obj/machinery/suit_storage_unit/mining, -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 5 - }, -/turf/open/floor/iron/dark, -/area/mine/eva) "Og" = ( /obj/machinery/power/apc/auto_name/directional/west, /obj/structure/cable, @@ -7324,6 +7439,13 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/smooth, /area/mine/laborcamp/production) +"Qh" = ( +/obj/machinery/suit_storage_unit/mining, +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 5 + }, +/turf/open/floor/iron/dark, +/area/mine/eva) "Qi" = ( /obj/machinery/door/airlock/research/glass{ name = "Mining Station Mech Bay" @@ -7364,6 +7486,12 @@ /obj/effect/turf_decal/stripes/corner, /turf/open/floor/plating/lavaland_atmos, /area/lavaland/surface/outdoors) +"QE" = ( +/obj/structure/chair/plastic{ + pixel_y = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) "QG" = ( /obj/machinery/door/airlock/public/glass{ id_tag = "gulag2"; @@ -7680,6 +7808,10 @@ dir = 1 }, /area/mine/laborcamp/security) +"Sw" = ( +/obj/structure/flora/rock/pile/style_random, +/turf/open/water/lavaland_atmos/basalt, +/area/lavaland/surface/outdoors) "Sz" = ( /obj/machinery/hydroponics/constructable, /obj/machinery/light/small/directional/west, @@ -7784,14 +7916,6 @@ }, /turf/open/floor/iron/dark/smooth_edge, /area/mine/eva) -"Ti" = ( -/obj/effect/turf_decal/trimline/brown/filled/line, -/obj/structure/table, -/obj/item/paper/fluff/stations/lavaland/orm_notice, -/turf/open/floor/iron/dark/smooth_edge{ - dir = 1 - }, -/area/mine/production) "To" = ( /obj/structure/table, /obj/machinery/reagentgrinder, @@ -7851,6 +7975,13 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/mine/maintenance/living/north) +"Ty" = ( +/obj/item/book/manual/fish_catalog{ + pixel_y = -6; + pixel_x = 14 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) "TD" = ( /obj/effect/turf_decal/trimline/brown/filled/line{ dir = 1 @@ -7880,17 +8011,6 @@ /obj/effect/turf_decal/tile/brown/fourcorners, /turf/open/floor/iron/dark, /area/mine/production) -"TQ" = ( -/obj/structure/table, -/obj/item/storage/toolbox/mechanical{ - pixel_x = -2; - pixel_y = 4 - }, -/obj/effect/turf_decal/trimline/brown/filled/line, -/turf/open/floor/iron/dark/smooth_edge{ - dir = 1 - }, -/area/mine/eva) "TR" = ( /obj/structure/fence/cut/large{ dir = 4 @@ -8053,6 +8173,10 @@ /obj/structure/sign/poster/official/no_erp/directional/south, /turf/open/floor/iron/smooth, /area/mine/laborcamp/quarters) +"UP" = ( +/obj/effect/landmark/river_waypoint, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors) "UQ" = ( /obj/structure/cable, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, @@ -8296,16 +8420,6 @@ }, /turf/open/floor/iron/dark/textured_large, /area/mine/laborcamp) -"VZ" = ( -/obj/machinery/power/apc/auto_name/directional/south, -/obj/structure/cable, -/obj/effect/turf_decal/trimline/brown/filled/line, -/obj/structure/table, -/obj/item/storage/medkit/regular, -/turf/open/floor/iron/dark/smooth_edge{ - dir = 1 - }, -/area/mine/production) "Wb" = ( /obj/structure/cable, /turf/open/floor/iron/dark/textured_large, @@ -8617,6 +8731,14 @@ /obj/item/seeds/apple, /turf/open/floor/iron/dark, /area/mine/laborcamp) +"XK" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/lattice/catwalk/mining, +/obj/structure/railing, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors) "XP" = ( /obj/structure/stone_tile/cracked, /obj/structure/stone_tile/block{ @@ -8770,13 +8892,6 @@ dir = 1 }, /area/mine/laborcamp/quarters) -"YD" = ( -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 6 - }, -/obj/item/radio/intercom/directional/east, -/turf/open/floor/iron/dark, -/area/mine/production) "YF" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -8836,9 +8951,13 @@ /turf/open/floor/iron, /area/mine/lounge) "Zg" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/sign/directions/evac/directional/east, -/turf/open/floor/plating, +/obj/machinery/door/airlock/external/glass{ + name = "Mining External Airlock" + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{ + cycle_id = "lavaland_living_north" + }, +/turf/open/floor/iron/textured_large, /area/mine/lounge) "Zh" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -8944,6 +9063,15 @@ }, /turf/open/misc/hay/lavaland, /area/lavaland/surface/outdoors) +"ZG" = ( +/obj/structure/cable, +/obj/machinery/power/smes/super/full{ + output_level = 100000; + input_level = 100000 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/mine/maintenance/service) "ZH" = ( /obj/structure/closet/secure_closet/labor_camp_security, /obj/effect/turf_decal/trimline/red/filled/line{ @@ -35930,7 +36058,7 @@ pU pU pU pU -iI +JX pU pU pU @@ -36188,8 +36316,8 @@ aD aD aD aD -wG -wG +El +El pU pU pU @@ -39012,7 +39140,7 @@ Ue AA gB ON -ps +ZG gq ER vc @@ -39263,7 +39391,7 @@ ZY ZY pU pU -iI +JX aD Qz ON @@ -40034,7 +40162,7 @@ ZY ZY pU pU -iI +JX aD aD ON @@ -42897,9 +43025,9 @@ iu pU aj aj -aj -pU +Zq SP +Zq kK Sm Vz @@ -43151,11 +43279,11 @@ kC ho aj pU -pU -pU -tF -tF -pU +aj +LV +ZM +mG +wc Zg ti DZ @@ -43408,12 +43536,12 @@ cC iu aj aj -pU -pU +aj +yV tF -aj -aj -Zq +mG +wc +Zg JA wp zF @@ -43661,19 +43789,19 @@ di di tF yV -Yq -aj -aj -pU -pU -aj -tF -aj -aj +Fo +eu +oy +ZM +ZM +LB +Ke Zq SP +Zq +Zq bL -SP +Zq Zq aj aj @@ -43918,13 +44046,13 @@ di aj aj yV -Yq -aj -aj -pU -aj -aj -tF +kx +BE +BE +VK +BE +BE +oE aj aj aj @@ -44175,7 +44303,7 @@ di aj aj yV -Yq +XK aj aj aj @@ -44185,9 +44313,9 @@ pU Pd NY NY -SP +Zq xN -SP +Zq NY NY LS @@ -45993,7 +46121,7 @@ Lw pU pU pU -aj +pU aj aj aj @@ -46507,7 +46635,7 @@ NY NY gQ pU -pU +aj aj aj aj @@ -46764,10 +46892,10 @@ BP BP Lw pU +aj +aj +aj pU -aj -aj -aj pU pU DB @@ -47021,9 +47149,9 @@ BP BP Lw pU +aj +aj pU -aj -aj pU pU pU @@ -47280,7 +47408,7 @@ Lw pU aj aj -aj +pU pU pU ai @@ -47537,7 +47665,7 @@ Lw pU aj aj -aj +pU pU ai ad @@ -47768,7 +47896,7 @@ Bb Ye GF nv -cR +KT Vt jW Fc @@ -48539,7 +48667,7 @@ zD TD Vw wl -Ti +cL pK lg se @@ -48796,12 +48924,12 @@ zJ oi Ts Wb -VZ +zt pK Tf -Jp +ay Yg -TQ +Kr dK pU pU @@ -49053,9 +49181,9 @@ RY RY dQ Cg -YD +Ac pK -Ob +Qh IL IL KV @@ -49071,6 +49199,7 @@ pU pU pU pU +yW pU pU pU @@ -49080,7 +49209,6 @@ pU aj aj aj -aj yV tF NL @@ -49326,16 +49454,16 @@ aj pU pU pU +CY +tl +tl +Sw +tl pU pU pU pU pU -pU -aj -aj -aj -aj aj aj zs @@ -49581,20 +49709,20 @@ NL aj aj aj -aj +pU +pU +tl +Sw +tl +tl +tl +tl pU pU pU pU pU aj -aj -aj -aj -pU -pU -aj -aj DB BP DB @@ -49838,20 +49966,20 @@ NL aj aj pU -aj -aj -aj -aj pU -aj -aj -aj -aj +pU +tl +tl +tl +tl +Sw +tl +pU +pU pU pU pU pU -aj pU pU pU @@ -50095,14 +50223,14 @@ NL aj pU pU -aj -aj -aj -aj -aj -aj -aj -aj +pU +ph +Sw +tl +tl +tl +tl +pU pU pU pU @@ -50350,16 +50478,16 @@ aj Ah aF aj -aj -aj -aj -aj pU -aj -aj -aj -aj -aj +pU +pU +pU +Ty +tl +tl +tl +hA +pU pU pU pU @@ -50607,15 +50735,15 @@ aj RO kf pU -aj -aj -aj -aj -aj -aj -aj -aj -aj +pU +pU +pU +pU +QE +tl +tl +tl +pU pU pU pU @@ -50865,14 +50993,14 @@ YP BP pU pU -aj -aj pU pU +CY +MC +tl +Sw pU pU -aj -pU pU pU ai @@ -53932,7 +54060,7 @@ ZY ZY pU pU -pU +aj aj aj aj @@ -54188,10 +54316,10 @@ ZY ZY ZY ZY -ZY -pU -pU -pU +aj +aj +aj +aj aj aj aj @@ -54444,11 +54572,11 @@ ZY ZY ZY ZY -ZY -ZY -ZY -pU -pU +aj +aj +aj +aj +aj pU pU pU @@ -54700,11 +54828,11 @@ ZY ZY ZY ZY -ZY -ZY -ZY -ZY -ZY +aj +aj +aj +aj +aj pU pU pU @@ -54957,10 +55085,10 @@ fQ ZY ZY ZY -ZY -ZY -ZY -ZY +aj +UP +aj +aj ZY ZY ZY @@ -55215,8 +55343,8 @@ fQ fQ ZY ZY -ZY -ZY +aj +aj ZY ZY ZY diff --git a/_maps/map_files/NebulaStation/NebulaStation.dmm b/_maps/map_files/NebulaStation/NebulaStation.dmm index ab864f64bd2..2954f596154 100644 --- a/_maps/map_files/NebulaStation/NebulaStation.dmm +++ b/_maps/map_files/NebulaStation/NebulaStation.dmm @@ -10187,20 +10187,16 @@ /turf/open/floor/iron/dark, /area/station/hallway/primary/port) "bBq" = ( -/obj/structure/table/reinforced, -/obj/item/folder{ - pixel_x = -6 - }, -/obj/structure/desk_bell{ - pixel_x = 6 - }, -/obj/item/pen{ - pixel_x = -5 - }, -/obj/machinery/door/window/left/directional/east{ - name = "Genetics Desk"; - req_access = list("genetics") +/obj/structure/flora/bush/snow{ + pixel_y = -3; + pixel_x = -3 }, +/obj/structure/flora/bush/flowers_br/style_random, +/obj/structure/window/reinforced/spawner/directional/north, +/obj/structure/window/reinforced/spawner/directional/east, +/obj/structure/window/reinforced/spawner/directional/west, +/obj/structure/window/reinforced/spawner/directional/south, +/obj/structure/flora/grass/both/style_2, /obj/machinery/door/poddoor/shutters/preopen{ dir = 8; id = "rdgene"; @@ -10209,8 +10205,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/door/firedoor, -/turf/open/floor/iron/dark, +/turf/open/misc/asteroid/snow/standard_air, /area/station/science/genetics) "bBr" = ( /obj/machinery/atmospherics/components/unary/thermomachine/heater/on, @@ -21212,6 +21207,13 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron/dark, /area/station/commons/fitness) +"dgS" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/structure/cable, +/turf/open/floor/iron/dark/textured_large, +/area/station/cargo/miningfoundry) "dgZ" = ( /obj/effect/turf_decal/siding/dark/corner{ dir = 4 @@ -25007,19 +25009,27 @@ /turf/open/floor/iron/dark, /area/station/hallway/primary/port) "dJT" = ( -/obj/structure/window/reinforced/spawner/directional/north, -/obj/structure/window/reinforced/spawner/directional/west, -/obj/structure/window/reinforced/spawner/directional/east, -/obj/structure/window/reinforced/spawner/directional/south, -/obj/structure/flora/grass/both/style_3, -/obj/structure/flora/bush/snow/style_2, -/obj/structure/flora/bush/flowers_br/style_random, +/obj/structure/table/reinforced, +/obj/item/folder{ + pixel_x = -6 + }, +/obj/structure/desk_bell{ + pixel_x = 6 + }, +/obj/item/pen{ + pixel_x = -5 + }, +/obj/machinery/door/window/left/directional/east{ + name = "Genetics Desk"; + req_access = list("genetics") + }, /obj/machinery/door/poddoor/shutters/preopen{ dir = 8; id = "rdgene"; name = "Genetics Lab Shutters" }, -/turf/open/misc/asteroid/snow/standard_air, +/obj/machinery/door/firedoor, +/turf/open/floor/iron/dark, /area/station/science/genetics) "dJU" = ( /obj/effect/turf_decal/siding/wood{ @@ -30658,9 +30668,6 @@ }, /area/station/security/mechbay) "eAs" = ( -/obj/structure/railing/corner/end{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/turf_decal/siding/brown{ dir = 10 @@ -30671,6 +30678,7 @@ /obj/effect/turf_decal/trimline/brown/corner{ dir = 4 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/cargo/miningoffice) "eAw" = ( @@ -38652,6 +38660,15 @@ /obj/structure/cable, /turf/open/floor/iron/dark/telecomms, /area/station/tcommsat/server) +"fIR" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 8 + }, +/obj/effect/turf_decal/siding/brown{ + dir = 6 + }, +/turf/open/floor/iron/dark/textured_large, +/area/station/cargo/miningfoundry) "fIU" = ( /obj/structure/table/wood/fancy/green, /obj/machinery/light/directional/east, @@ -42868,9 +42885,7 @@ /obj/structure/railing{ dir = 8 }, -/obj/effect/turf_decal/delivery, -/obj/effect/decal/cleanable/plasma, -/obj/effect/decal/cleanable/rubble, +/obj/machinery/computer/order_console/mining, /turf/open/floor/iron/dark/textured_large, /area/station/cargo/miningoffice) "gnM" = ( @@ -45199,7 +45214,6 @@ /turf/open/floor/grass, /area/station/security/checkpoint/customs) "gFS" = ( -/obj/structure/hedge, /obj/effect/turf_decal/trimline/purple/filled/line{ dir = 1 }, @@ -45208,6 +45222,7 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/sign/poster/random/directional/north, +/obj/machinery/gizmo/toggle/tucker_tubes, /turf/open/floor/iron/dark, /area/station/science/explab) "gFU" = ( @@ -45528,6 +45543,14 @@ dir = 8 }, /area/station/hallway/primary/fore) +"gIP" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/dark/textured_large, +/area/station/cargo/miningfoundry) "gIQ" = ( /turf/closed/wall/r_wall, /area/station/science/explab) @@ -48553,8 +48576,9 @@ /area/station/command/heads_quarters/ce) "hfN" = ( /obj/structure/table/reinforced/rglass, -/obj/item/folder, -/obj/item/pen, +/obj/machinery/computer/records/medical/laptop{ + dir = 4 + }, /turf/open/floor/iron/dark/textured, /area/station/science/genetics) "hfO" = ( @@ -49753,6 +49777,16 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/white, /area/station/medical/lower) +"hoC" = ( +/obj/effect/decal/cleanable/plasma, +/obj/effect/decal/cleanable/rubble, +/obj/structure/cable, +/obj/effect/turf_decal/trimline/brown/filled/arrow_cw, +/obj/effect/turf_decal/trimline/brown/filled/arrow_ccw{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "hoE" = ( /obj/structure/cable, /obj/effect/decal/cleanable/dirt/dust, @@ -57537,6 +57571,9 @@ dir = 9 }, /obj/effect/turf_decal/trimline/brown/corner, +/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/miningoffice) "iwP" = ( @@ -63796,10 +63833,6 @@ /obj/structure/flora/bush/flowers_yw/style_random, /turf/open/floor/grass, /area/station/ai/satellite/exterior) -"juB" = ( -/obj/machinery/computer/order_console/mining, -/turf/open/floor/iron/dark/textured_large, -/area/station/cargo/miningoffice) "juD" = ( /obj/structure/railing{ dir = 1 @@ -64561,17 +64594,10 @@ /turf/open/floor/catwalk_floor/iron_dark, /area/station/maintenance/department/bridge) "jzQ" = ( -/obj/effect/turf_decal/siding/brown, -/obj/effect/turf_decal/trimline/brown/filled/line, /obj/machinery/firealarm/directional/south, -/obj/effect/turf_decal/stripes/line{ +/obj/structure/chair/sofa/bench/solo{ dir = 1 }, -/obj/machinery/conveyor{ - dir = 8; - id = "mining" - }, -/obj/machinery/bouldertech/refinery/smelter, /turf/open/floor/iron/dark/textured_large, /area/station/cargo/miningoffice) "jzZ" = ( @@ -67185,7 +67211,7 @@ /area/station/medical/lower) "jSP" = ( /obj/structure/cable, -/mob/living/simple_animal/bot/secbot/beepsky/officer, +/mob/living/basic/bot/secbot/beepsky/officer, /turf/open/floor/iron/dark/small, /area/station/security/brig) "jSZ" = ( @@ -75955,6 +75981,9 @@ dir = 1 }, /obj/effect/turf_decal/trimline/brown/line, +/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/miningoffice) "lhK" = ( @@ -78731,6 +78760,7 @@ "lCa" = ( /obj/machinery/holopad, /obj/effect/landmark/event_spawn, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/glass/reinforced, /area/station/cargo/miningoffice) "lCd" = ( @@ -78772,14 +78802,6 @@ /turf/open/floor/iron/dark/small, /area/station/engineering/atmos/project) "lCS" = ( -/obj/structure/railing{ - dir = 6 - }, -/obj/machinery/conveyor_switch/oneway{ - id = "mining"; - name = "mining conveyor"; - pixel_y = 12 - }, /obj/effect/turf_decal/siding/brown{ dir = 6 }, @@ -83095,6 +83117,15 @@ }, /turf/open/floor/plating, /area/station/maintenance/starboard/central) +"mmF" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, +/obj/effect/turf_decal/siding/brown{ + dir = 5 + }, +/turf/open/floor/iron/dark/textured_large, +/area/station/cargo/miningfoundry) "mmG" = ( /obj/machinery/camera/directional/north{ c_tag = "Xenobiology Lab - Pen #4"; @@ -85374,16 +85405,16 @@ /turf/open/floor/iron/white, /area/station/science/lab) "mFl" = ( -/obj/machinery/mining_weather_monitor/directional/east, -/obj/machinery/conveyor{ - id = "mining" +/obj/machinery/mining_weather_monitor/directional/north, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/machinery/door/window/right/directional/east{ + req_access = list("mining"); + name = "Foundry Gate" }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/machinery/brm, /turf/open/floor/iron/dark/textured_large, -/area/station/cargo/miningoffice) +/area/station/cargo/miningfoundry) "mFr" = ( /obj/effect/turf_decal/siding/thinplating_new/dark{ dir = 10 @@ -86566,14 +86597,6 @@ /area/space/nearstation) "mOI" = ( /obj/structure/sign/poster/random/directional/east, -/obj/machinery/conveyor{ - dir = 10; - id = "mining" - }, -/obj/effect/turf_decal/stripes/corner{ - dir = 1 - }, -/obj/machinery/bouldertech/refinery, /turf/open/floor/iron/dark/textured_large, /area/station/cargo/miningoffice) "mOJ" = ( @@ -88233,6 +88256,9 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) +"nbS" = ( +/turf/closed/wall, +/area/station/cargo/miningfoundry) "nbU" = ( /obj/effect/turf_decal/trimline/yellow/line{ dir = 4 @@ -90129,6 +90155,20 @@ dir = 1 }, /area/station/security/brig) +"nrD" = ( +/obj/machinery/conveyor_switch/oneway{ + id = "mining"; + name = "mining conveyor"; + pixel_y = 12 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/turf_decal/siding/brown{ + dir = 9 + }, +/obj/machinery/airalarm/directional/west, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/dark/textured_large, +/area/station/cargo/miningfoundry) "nrG" = ( /obj/machinery/holopad, /obj/effect/turf_decal/trimline/purple/corner{ @@ -91675,7 +91715,7 @@ /obj/effect/turf_decal/siding/thinplating_new/dark{ dir = 4 }, -/mob/living/simple_animal/bot/secbot/pingsky, +/mob/living/basic/bot/secbot/pingsky, /obj/machinery/ai_slipper{ uses = 10 }, @@ -92242,6 +92282,14 @@ /obj/item/clothing/glasses/welding, /turf/open/floor/plating, /area/station/maintenance/port/central) +"nIe" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/power/apc/auto_name/directional/north, +/obj/structure/cable, +/turf/open/floor/iron/dark/textured_large, +/area/station/cargo/miningfoundry) "nIf" = ( /obj/effect/turf_decal/box/white, /turf/open/floor/engine, @@ -92768,6 +92816,14 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/carpet/red, /area/station/service/library) +"nMH" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/dark/textured_large, +/area/station/cargo/miningfoundry) "nMJ" = ( /obj/effect/turf_decal/tile/dark_blue/half/contrasted, /obj/effect/turf_decal/trimline/dark/corner, @@ -97020,6 +97076,14 @@ dir = 4 }, /area/station/service/chapel/funeral) +"oqz" = ( +/obj/machinery/conveyor{ + id = "mining"; + dir = 4 + }, +/obj/machinery/brm, +/turf/open/floor/iron/dark/textured_large, +/area/station/cargo/miningfoundry) "oqE" = ( /obj/structure/chair/stool/directional/west, /turf/open/floor/plating, @@ -97034,6 +97098,10 @@ color = "#3d3e42" }, /area/station/engineering/engine_smes) +"oqM" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/station/cargo/miningfoundry) "oqS" = ( /obj/effect/turf_decal/siding/wood{ dir = 4 @@ -105901,6 +105969,7 @@ }, /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/dark/smooth_edge{ dir = 8 }, @@ -107378,11 +107447,8 @@ "pOD" = ( /obj/machinery/status_display/ai/directional/east, /obj/machinery/light/directional/east, -/obj/machinery/conveyor{ - id = "mining" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 +/obj/effect/turf_decal/stripes/corner{ + dir = 4 }, /turf/open/floor/iron/dark/textured_large, /area/station/cargo/miningoffice) @@ -108347,6 +108413,14 @@ /obj/effect/turf_decal/siding/wood, /turf/open/floor/wood/large, /area/station/service/library/upper) +"pVC" = ( +/obj/machinery/conveyor{ + id = "mining"; + dir = 6 + }, +/obj/machinery/light/directional/north, +/turf/open/floor/iron/dark/textured_large, +/area/station/cargo/miningfoundry) "pVH" = ( /obj/effect/turf_decal/trimline/red/line, /obj/effect/turf_decal/siding/thinplating_new/dark{ @@ -110897,7 +110971,7 @@ location = "F10-Cargo"; codes_txt = "patrol;next_patrol=F11-Cargo" }, -/mob/living/simple_animal/bot/secbot/beepsky/officer{ +/mob/living/basic/bot/secbot/beepsky/officer{ name = "Beepsky the Third" }, /turf/open/floor/iron, @@ -113592,7 +113666,7 @@ /turf/open/floor/iron/dark/herringbone, /area/station/service/chapel/funeral) "qKN" = ( -/mob/living/simple_animal/bot/secbot/beepsky/armsky, +/mob/living/basic/bot/secbot/beepsky/armsky, /turf/open/floor/glass/reinforced, /area/station/security/armory) "qKR" = ( @@ -115883,14 +115957,9 @@ }, /area/station/security/range) "red" = ( -/obj/item/radio/intercom/directional/west, /obj/structure/railing{ dir = 1 }, -/obj/machinery/camera/autoname/directional/west{ - dir = 10; - network = list("ss13","rd") - }, /obj/effect/turf_decal/siding/thinplating_new/dark{ dir = 9 }, @@ -125899,6 +125968,15 @@ dir = 8 }, /area/station/security/prison) +"sDq" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "sDr" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 1 @@ -127959,6 +128037,13 @@ /obj/structure/bookcase/random/reference, /turf/open/floor/iron/dark, /area/station/security/breakroom) +"sTD" = ( +/obj/machinery/conveyor{ + id = "mining"; + dir = 4 + }, +/turf/open/floor/iron/dark/textured_large, +/area/station/cargo/miningfoundry) "sTG" = ( /obj/item/banner/command/mundane, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -132275,13 +132360,11 @@ /turf/open/floor/iron/dark, /area/station/construction/mining/aux_base) "tAb" = ( -/obj/structure/chair/office/light{ +/obj/effect/turf_decal/delivery, +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk{ dir = 8 }, -/obj/effect/landmark/start/geneticist, -/obj/structure/disposalpipe/segment{ - dir = 10 - }, /turf/open/floor/iron/dark/textured_large, /area/station/science/genetics) "tAe" = ( @@ -132886,11 +132969,13 @@ /turf/open/floor/wood/large, /area/station/commons/dorms) "tDP" = ( -/obj/machinery/disposal/bin, -/obj/structure/disposalpipe/trunk{ - dir = 1 +/obj/structure/chair/office/light{ + dir = 8 + }, +/obj/effect/landmark/start/geneticist, +/obj/machinery/camera/autoname/directional/south{ + network = list("ss13","rd") }, -/obj/effect/turf_decal/delivery, /turf/open/floor/iron/dark/textured_large, /area/station/science/genetics) "tDQ" = ( @@ -133473,6 +133558,19 @@ dir = 6 }, /area/station/maintenance/disposal) +"tHC" = ( +/obj/structure/rack, +/obj/item/stack/ducts{ + pixel_y = -1 + }, +/obj/item/stack/ducts{ + pixel_y = 3 + }, +/obj/item/stack/ducts{ + pixel_y = 7 + }, +/turf/open/floor/iron/dark/textured_large, +/area/station/cargo/miningoffice) "tHJ" = ( /obj/machinery/light/floor, /obj/effect/landmark/event_spawn, @@ -140677,6 +140775,14 @@ /obj/structure/cable, /turf/open/floor/engine/hull/reinforced, /area/space/nearstation) +"uOS" = ( +/obj/machinery/conveyor{ + dir = 10; + id = "mining" + }, +/obj/structure/cable, +/turf/open/floor/iron/dark/textured_large, +/area/station/cargo/miningfoundry) "uOX" = ( /obj/structure/railing{ dir = 4 @@ -141749,6 +141855,10 @@ /obj/machinery/airalarm/directional/north, /turf/open/floor/iron/dark/textured, /area/station/engineering/atmos/storage) +"uWr" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/station/cargo/lower) "uWt" = ( /obj/effect/turf_decal/siding/thinplating_new/dark{ dir = 4 @@ -142088,6 +142198,15 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/iron/dark, /area/station/science/robotics/lab) +"uYW" = ( +/obj/machinery/conveyor{ + id = "mining" + }, +/obj/machinery/bouldertech/refinery/smelter{ + dir = 1 + }, +/turf/open/floor/iron/dark/textured_large, +/area/station/cargo/miningfoundry) "uYZ" = ( /obj/effect/turf_decal/siding/thinplating_new/dark/corner, /obj/effect/turf_decal/siding/thinplating_new/dark/corner{ @@ -145795,10 +145914,10 @@ /turf/open/floor/grass, /area/station/commons/fitness/recreation) "vxO" = ( -/obj/structure/table, -/obj/machinery/computer/records/medical/laptop{ - pixel_y = 1 +/obj/effect/turf_decal/trimline/purple/end{ + dir = 4 }, +/obj/item/radio/intercom/directional/north, /turf/open/floor/iron/dark/textured_large, /area/station/science/genetics) "vxQ" = ( @@ -151841,6 +151960,14 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark/textured_large, /area/station/ai/satellite/service) +"wvQ" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/turf_decal/siding/brown{ + dir = 10 + }, +/turf/open/floor/iron/dark/textured_large, +/area/station/cargo/miningfoundry) "wvS" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -153826,6 +153953,15 @@ }, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) +"wLi" = ( +/obj/machinery/bouldertech/refinery{ + dir = 1 + }, +/obj/machinery/conveyor{ + id = "mining" + }, +/turf/open/floor/iron/dark/textured_large, +/area/station/cargo/miningfoundry) "wLk" = ( /obj/effect/turf_decal/siding/dark, /obj/machinery/chem_dispenser, @@ -155678,11 +155814,7 @@ /area/station/commons/dorms) "xbk" = ( /obj/item/radio/intercom/directional/south, -/obj/machinery/conveyor{ - dir = 8; - id = "mining" - }, -/obj/effect/turf_decal/stripes/line{ +/obj/structure/chair/sofa/bench/solo{ dir = 1 }, /turf/open/floor/iron/dark/textured_large, @@ -155973,22 +156105,17 @@ }, /area/station/maintenance/central) "xdw" = ( -/obj/structure/flora/bush/snow{ - pixel_y = -3; - pixel_x = -3 - }, -/obj/structure/flora/bush/flowers_br/style_random, -/obj/structure/window/reinforced/spawner/directional/north, -/obj/structure/window/reinforced/spawner/directional/east, -/obj/structure/window/reinforced/spawner/directional/west, -/obj/structure/window/reinforced/spawner/directional/south, -/obj/structure/flora/grass/both/style_2, +/obj/machinery/door/firedoor, /obj/machinery/door/poddoor/shutters/preopen{ dir = 8; id = "rdgene"; name = "Genetics Lab Shutters" }, -/turf/open/misc/asteroid/snow/standard_air, +/obj/machinery/door/airlock/research/glass{ + name = "Genetics Lab" + }, +/obj/effect/mapping_helpers/airlock/access/all/science/genetics, +/turf/open/floor/iron/dark/textured_large, /area/station/science/genetics) "xdx" = ( /obj/structure/window/reinforced/spawner/directional/north, @@ -156158,7 +156285,6 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 8 }, -/obj/structure/railing, /obj/effect/turf_decal/trimline/brown/filled/line, /obj/effect/turf_decal/siding/brown, /obj/effect/turf_decal/trimline/brown/line{ @@ -159982,6 +160108,7 @@ dir = 10 }, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/spawner/random/gizmo, /turf/open/floor/engine, /area/station/science/explab) "xIE" = ( @@ -161349,7 +161476,6 @@ /turf/open/floor/plating, /area/station/maintenance/department/science) "xSw" = ( -/obj/structure/railing/corner/end/flip, /obj/effect/turf_decal/trimline/brown/filled/line{ dir = 5 }, @@ -161359,6 +161485,9 @@ /obj/effect/turf_decal/trimline/brown/corner{ dir = 8 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, /turf/open/floor/iron, /area/station/cargo/miningoffice) "xSA" = ( @@ -194367,7 +194496,7 @@ gym fDY gJT cGO -juB +vNT lhE xeX jzQ @@ -194620,11 +194749,11 @@ gym gym gym gym -gym -gym gJT +rWS +fDY cGO -vNT +tHC xSw lCS xbk @@ -194877,11 +195006,11 @@ gym gym gym gym -gym -gym -fDY -bPw -bPw +rWS +nbS +oqM +nbS +nbS mFl pOD mOI @@ -195133,13 +195262,13 @@ gym gym gym gym -gym -gym -gym +dew gJT -gJT -bPw -bPw +nbS +oqz +nrD +wvQ +sDq kFj kFj kFj @@ -195391,13 +195520,13 @@ gym gym gym gym -gym -gym -gym -gym -ihJ -gJT -kFj +rWS +oqM +sTD +mmF +fIR +hoC +uWr grQ dsJ dec @@ -195647,13 +195776,13 @@ gym gym gym gym -gym -gym -gym -gym -gym -ihJ +dew rnW +nbS +pVC +wLi +uYW +uOS kFj tqY xsP @@ -195905,12 +196034,12 @@ gym gym gym gym -gym -gym -gym -gym -ihJ -gJT +rWS +nbS +nIe +gIP +dgS +nMH kFj ttj qwk @@ -196163,7 +196292,7 @@ gym gym gJT fDY -gJT +ewt oZM oZM oZM @@ -196420,7 +196549,7 @@ gym gJT nnP nnP -nnP +oZM oZM vxf rEU @@ -260672,8 +260801,8 @@ txW txW txW txW -txW -pCa +dtb +dtb dtb dtb aGm diff --git a/_maps/map_files/debug/runtimestation.dmm b/_maps/map_files/debug/runtimestation.dmm index 66baca7acb2..9779a6622ee 100644 --- a/_maps/map_files/debug/runtimestation.dmm +++ b/_maps/map_files/debug/runtimestation.dmm @@ -2808,8 +2808,7 @@ /area/station/engineering/atmos) "ZK" = ( /obj/structure/table, -/obj/item/storage/box/shipping, -/obj/item/boulder_beacon, +/obj/item/storage/box/shipping/debug, /turf/open/floor/iron, /area/station/commons/storage/primary) "ZP" = ( diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index a7879a5a073..5e4af937de0 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -2,6 +2,11 @@ "aa" = ( /turf/open/space/basic, /area/space) +"ad" = ( +/obj/structure/sign/nanotrasen/directional/south, +/obj/effect/turf_decal/tile/green, +/turf/open/floor/iron, +/area/centcom/central_command_areas/ferry) "ak" = ( /obj/item/kirbyplants/organic/plant21, /obj/effect/turf_decal/tile/red/anticorner/contrasted{ @@ -22,18 +27,20 @@ /turf/open/indestructible/dark, /area/centcom/central_command_areas/prison/cells) "ap" = ( -/obj/effect/turf_decal/stripes/line{ +/obj/effect/turf_decal/trimline/dark_red/warning{ dir = 1 }, -/obj/machinery/light/floor, /turf/open/floor/iron, /area/centcom/central_command_areas/supplypod/loading/ert) "ar" = ( +/obj/structure/cable, +/obj/effect/turf_decal/tile/neutral/half/contrasted{ + dir = 8 + }, /obj/structure/chair/office{ dir = 8 }, /obj/effect/landmark/ert_spawn, -/obj/structure/cable, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) "at" = ( @@ -46,21 +53,8 @@ /turf/open/floor/iron, /area/centcom/tdome/observation) "au" = ( -/obj/structure/table/reinforced, -/obj/item/stack/sheet/iron/fifty, -/obj/item/stack/sheet/iron/fifty, -/obj/item/stack/sheet/plasteel{ - amount = 15 - }, -/obj/item/stack/sheet/rglass{ - amount = 50; - pixel_x = 2; - pixel_y = -2 - }, -/obj/item/stack/rods/fifty, -/obj/item/stack/cable_coil, -/obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/stripes/line, +/obj/structure/reagent_dispensers/watertank, /turf/open/floor/iron, /area/centcom/central_command_areas/admin) "av" = ( @@ -72,22 +66,24 @@ /turf/open/floor/iron, /area/centcom/tdome/observation) "aw" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, /obj/machinery/airalarm/directional/south, /obj/machinery/atmospherics/components/unary/portables_connector/visible{ dir = 1 }, /obj/machinery/portable_atmospherics/canister/air, -/turf/open/floor/iron, +/obj/effect/turf_decal/siding/dark{ + dir = 1 + }, +/obj/effect/turf_decal/tile/yellow/half, +/turf/open/floor/iron/textured_edge, /area/centcom/central_command_areas/admin/storage) "az" = ( /obj/machinery/modular_computer/preset/id/centcom{ dir = 1 }, -/turf/open/floor/iron/grimy, +/obj/effect/turf_decal/siding/wood, +/obj/structure/window/reinforced/spawner/directional/south, +/turf/open/floor/carpet/green, /area/centcom/central_command_areas/briefing) "aA" = ( /obj/effect/landmark/thunderdome/one, @@ -105,10 +101,6 @@ /turf/open/floor/iron, /area/centcom/tdome/observation) "aD" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, @@ -117,7 +109,12 @@ }, /obj/structure/cable, /obj/machinery/status_display/evac/directional/south, -/turf/open/floor/iron, +/obj/effect/turf_decal/siding/dark{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow/half, +/turf/open/floor/iron/textured_edge, /area/centcom/central_command_areas/admin/storage) "aG" = ( /obj/structure/noticeboard/directional/east, @@ -128,13 +125,14 @@ /area/centcom/central_command_areas/prison) "aK" = ( /obj/structure/table/reinforced, -/obj/item/stack/package_wrap, /obj/item/crowbar/power, -/obj/item/wrench, -/obj/item/hand_labeler, /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/effect/decal/cleanable/dirt, +/obj/item/weldingtool/experimental{ + pixel_y = 5 + }, /turf/open/floor/iron, /area/centcom/central_command_areas/admin) "aL" = ( @@ -181,10 +179,8 @@ /turf/open/floor/iron, /area/centcom/central_command_areas/evacuation) "aS" = ( -/obj/item/kirbyplants/organic/plant22, /obj/machinery/power/apc/auto_name/directional/south, /obj/structure/cable, -/obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) "aU" = ( @@ -270,12 +266,14 @@ /area/centcom/tdome/observation) "bj" = ( /obj/structure/table/reinforced, -/obj/item/storage/box/zipties, -/obj/item/crowbar/red, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/item/storage/box/zipties{ + pixel_y = 12; + pixel_x = -5 }, -/turf/open/floor/iron, +/obj/item/crowbar/red{ + pixel_y = -7 + }, +/turf/open/floor/iron/textured_large, /area/centcom/central_command_areas/armory) "bk" = ( /obj/machinery/door/firedoor, @@ -321,24 +319,23 @@ /area/centcom/tdome/observation) "bA" = ( /obj/structure/table/reinforced, -/obj/item/storage/medkit/regular{ - pixel_x = -7 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 5 +/obj/item/bodybag/environmental/nanotrasen{ + pixel_x = 7; + pixel_y = 13 }, /obj/item/bodybag/environmental/nanotrasen{ pixel_x = 7; - pixel_y = 12 + pixel_y = 7 }, /obj/item/bodybag/environmental/nanotrasen{ pixel_x = 7; - pixel_y = 6 + pixel_y = 1 }, -/obj/item/bodybag/environmental/nanotrasen{ - pixel_x = 7 +/obj/item/storage/medkit/advanced{ + pixel_y = 7; + pixel_x = -12 }, -/turf/open/floor/iron, +/turf/open/floor/iron/textured_large, /area/centcom/central_command_areas/armory) "bB" = ( /obj/item/storage/box/handcuffs, @@ -368,7 +365,12 @@ /area/centcom/central_command_areas/control) "bH" = ( /obj/structure/cable, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/trimline/dark_red/warning{ + dir = 8 + }, +/obj/effect/turf_decal/caution/stand_clear/red{ + dir = 4 + }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/armory) "bJ" = ( @@ -397,9 +399,22 @@ /turf/open/floor/iron, /area/centcom/central_command_areas/evacuation/ship) "bO" = ( -/obj/item/kirbyplants/organic/plant22, -/obj/effect/turf_decal/tile/neutral/fourcorners, /obj/machinery/light/directional/south, +/obj/effect/turf_decal/siding/dark{ + dir = 1 + }, +/obj/structure/table/wood, +/obj/item/storage/fancy/cigarettes/cigars/cohiba{ + pixel_y = 12; + pixel_x = -2 + }, +/obj/item/reagent_containers/cup/glass/mug/nanotrasen{ + pixel_x = -6 + }, +/obj/item/reagent_containers/cup/glass/mug/nanotrasen{ + pixel_x = 6; + pixel_y = 0 + }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin) "bP" = ( @@ -427,8 +442,7 @@ /area/centcom/central_command_areas/control) "bW" = ( /obj/structure/filingcabinet/white, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/turf/open/floor/iron/dark/textured_large, /area/centcom/central_command_areas/ferry) "bZ" = ( /obj/effect/turf_decal/tile/green, @@ -436,16 +450,8 @@ /turf/open/floor/iron, /area/centcom/tdome/arena) "cb" = ( -/obj/item/storage/briefcase{ - pixel_x = -3; - pixel_y = 3 - }, -/obj/item/storage/briefcase/secure, -/obj/structure/table/wood, -/obj/effect/turf_decal/tile/neutral/anticorner/contrasted{ - dir = 4 - }, -/turf/open/floor/iron/dark, +/obj/structure/filingcabinet/security, +/turf/open/floor/carpet/green, /area/centcom/central_command_areas/briefing) "cd" = ( /obj/structure/sink/directional/east, @@ -499,10 +505,10 @@ "cm" = ( /obj/structure/closet/secure_closet/ert_engi, /obj/machinery/airalarm/directional/north, -/obj/effect/turf_decal/stripes/line{ - dir = 6 +/obj/effect/turf_decal/tile/yellow/half{ + dir = 1 }, -/turf/open/floor/iron, +/turf/open/floor/iron/textured_half, /area/centcom/central_command_areas/armory) "cn" = ( /obj/effect/spawner/structure/window/reinforced, @@ -538,36 +544,49 @@ /turf/open/floor/iron, /area/centcom/central_command_areas/courtroom) "cw" = ( -/obj/structure/table/wood, -/obj/item/folder/red, -/obj/item/lighter, /obj/machinery/firealarm/directional/south, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "cA" = ( /obj/item/storage/box/emps{ - pixel_x = 3; - pixel_y = 3 + pixel_x = 7; + pixel_y = 12 + }, +/obj/item/storage/box/flashbangs{ + pixel_y = 4 + }, +/obj/item/grenade/c4/x4{ + pixel_y = -1; + pixel_x = -8 + }, +/obj/item/grenade/c4/x4{ + pixel_x = -8; + pixel_y = 4 + }, +/obj/item/grenade/c4/x4{ + pixel_x = -8; + pixel_y = 10 }, -/obj/item/storage/box/flashbangs, -/obj/item/grenade/c4/x4, -/obj/item/grenade/c4/x4, -/obj/item/grenade/c4/x4, -/obj/structure/table/reinforced, -/obj/item/clothing/ears/earmuffs, /obj/structure/reagent_dispensers/wall/peppertank/directional/east, -/obj/effect/turf_decal/stripes/line{ +/obj/structure/table/reinforced, +/obj/effect/turf_decal/siding/dark{ dir = 1 }, -/turf/open/floor/iron, +/obj/effect/turf_decal/tile/dark_red/half, +/turf/open/floor/iron/textured_edge, /area/centcom/central_command_areas/admin/storage) "cB" = ( -/obj/item/kirbyplants/organic/plant21, /obj/structure/cable, /obj/machinery/power/apc/auto_name/directional/south, -/turf/open/floor/wood, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) +"cC" = ( +/obj/effect/turf_decal/siding/dark, +/obj/effect/turf_decal/siding/dark{ + dir = 1 + }, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/armory) "cD" = ( /obj/structure/table/wood, /obj/item/folder/red, @@ -577,6 +596,14 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/tdome/administration) +"cG" = ( +/obj/effect/turf_decal/tile/green/opposingcorners, +/obj/effect/turf_decal/siding/dark/corner, +/obj/effect/turf_decal/siding/dark/corner{ + dir = 8 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/ferry) "cI" = ( /obj/machinery/light/directional/north, /obj/effect/turf_decal/tile/red/half/contrasted{ @@ -606,14 +633,23 @@ /turf/open/floor/iron/dark/textured_large, /area/centcom/central_command_areas/evacuation/ship) "cL" = ( -/obj/item/gun/energy/pulse/carbine/loyalpin, -/obj/item/flashlight/seclite, +/obj/item/gun/energy/pulse/carbine/loyalpin{ + pixel_y = 7 + }, +/obj/item/flashlight/seclite{ + pixel_x = 4; + pixel_y = -1 + }, /obj/structure/table/reinforced, /obj/machinery/airalarm/directional/south, -/obj/effect/turf_decal/stripes/line{ +/obj/item/clothing/ears/earmuffs{ + pixel_y = -1 + }, +/obj/effect/turf_decal/siding/dark{ dir = 1 }, -/turf/open/floor/iron, +/obj/effect/turf_decal/tile/dark_red/half, +/turf/open/floor/iron/textured_edge, /area/centcom/central_command_areas/admin/storage) "cO" = ( /obj/structure/fans/tiny, @@ -688,11 +724,16 @@ /turf/open/floor/iron, /area/centcom/central_command_areas/evacuation) "db" = ( -/obj/structure/table/wood, -/obj/item/folder/red, -/obj/item/lighter, /obj/machinery/newscaster/directional/south, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/structure/table/wood, +/obj/item/storage/briefcase/secure{ + pixel_x = -3; + pixel_y = 7 + }, +/obj/item/storage/briefcase{ + pixel_y = 0; + pixel_x = 3 + }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) "dc" = ( @@ -705,16 +746,46 @@ /turf/open/floor/iron, /area/centcom/central_command_areas/evacuation) "dd" = ( -/obj/structure/reagent_dispensers/watertank, /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/structure/table/reinforced, +/obj/item/stack/sheet/rglass{ + amount = 50; + pixel_x = -6; + pixel_y = 6 + }, +/obj/item/stack/sheet/plasteel{ + amount = 15; + pixel_y = 5; + pixel_x = -1 + }, +/obj/item/stack/rods/fifty{ + pixel_y = 4; + pixel_x = -4 + }, +/obj/item/stack/sheet/iron/fifty{ + pixel_y = 7; + pixel_x = 8 + }, +/obj/item/stack/sheet/iron/fifty{ + pixel_y = 7; + pixel_x = 8 + }, +/obj/item/stack/cable_coil{ + pixel_y = -1; + pixel_x = 3 + }, /turf/open/floor/iron, /area/centcom/central_command_areas/admin) "df" = ( /obj/structure/table/wood, -/obj/item/clipboard, -/obj/item/folder/red, +/obj/item/clipboard{ + pixel_x = -6 + }, +/obj/item/folder/documents{ + pixel_x = -6 + }, /obj/item/stamp/denied{ pixel_x = 6; pixel_y = 6 @@ -724,7 +795,7 @@ pixel_y = 3 }, /obj/item/stamp/centcom, -/turf/open/floor/iron/grimy, +/turf/open/floor/carpet/green, /area/centcom/central_command_areas/admin) "dh" = ( /obj/effect/turf_decal/tile/dark_blue/half/contrasted{ @@ -831,7 +902,9 @@ /area/centcom/tdome/observation) "dx" = ( /obj/machinery/light/directional/east, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/tile/neutral/half/contrasted{ + dir = 8 + }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin) "dy" = ( @@ -847,19 +920,27 @@ /turf/open/floor/iron, /area/centcom/central_command_areas/evacuation/ship) "dz" = ( -/obj/item/clipboard, -/obj/structure/table/reinforced, -/obj/item/detective_scanner, +/obj/item/clipboard{ + pixel_x = -6; + pixel_y = 2 + }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ dir = 4 }, /obj/structure/cable, -/obj/item/storage/box/ids{ - pixel_x = 6; - pixel_y = 12 +/obj/item/folder/red{ + pixel_x = -7 }, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/item/paper_bin{ + pixel_y = 4; + pixel_x = 5 + }, +/obj/machinery/door/window/brigdoor/right/directional/west{ + name = "Commander's Desk"; + req_access = list("cent_captain") + }, +/obj/structure/table/reinforced, +/turf/open/floor/iron/grimy, /area/centcom/central_command_areas/admin) "dC" = ( /obj/item/kirbyplants/organic/plant21, @@ -908,6 +989,14 @@ /obj/effect/turf_decal/loading_area, /turf/open/floor/iron, /area/centcom/tdome/observation) +"dR" = ( +/obj/effect/turf_decal/tile/green/half{ + dir = 4 + }, +/turf/open/floor/iron/edge{ + dir = 4 + }, +/area/centcom/central_command_areas/ferry) "dU" = ( /obj/structure/bookcase/random, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -923,18 +1012,19 @@ /turf/open/floor/iron/dark, /area/centcom/tdome/observation) "dW" = ( +/obj/machinery/status_display/evac/directional/east, +/obj/structure/table/wood, /obj/item/radio{ pixel_x = 5; - pixel_y = 5 + pixel_y = 7 }, /obj/item/radio{ pixel_x = -5; - pixel_y = 5 + pixel_y = 7 + }, +/obj/item/radio{ + pixel_y = 2 }, -/obj/item/radio, -/obj/structure/table/wood, -/obj/machinery/status_display/evac/directional/east, -/obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) "ea" = ( @@ -1017,17 +1107,15 @@ /area/centcom/central_command_areas/evacuation/ship) "eA" = ( /obj/machinery/status_display/ai/directional/north, -/obj/item/kirbyplants/organic/plant15{ - pixel_x = -6; - pixel_y = 12 - }, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/effect/turf_decal/siding/wood, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "eB" = ( -/obj/structure/bookcase/random, -/obj/effect/turf_decal/tile/neutral/fourcorners, /obj/structure/sign/nanotrasen/directional/west, +/obj/effect/turf_decal/siding/dark{ + dir = 1 + }, +/obj/structure/bookcase/random, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin) "eD" = ( @@ -1037,20 +1125,29 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, /obj/effect/turf_decal/stripes/line, /obj/effect/mapping_helpers/airlock/access/all/admin/officer, -/turf/open/floor/iron, +/obj/effect/turf_decal/siding/wood, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "eE" = ( -/obj/structure/table/reinforced, -/obj/item/toy/figure/dsquad{ +/obj/structure/table/reinforced/plastitaniumglass, +/obj/effect/turf_decal/tile/green/full, +/obj/item/clothing/mask/gas/sechailer{ pixel_x = -3; - pixel_y = 11 + pixel_y = 2 }, -/obj/item/flashlight/seclite, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/item/flashlight/seclite{ + pixel_x = 1; + pixel_y = -5 + }, +/obj/item/toy/figure/dsquad{ + pixel_y = 5; + pixel_x = 9 + }, +/turf/open/floor/iron/dark/smooth_large, /area/centcom/central_command_areas/briefing) "eF" = ( -/turf/open/floor/iron/grimy, +/obj/effect/turf_decal/siding/wood, +/turf/open/floor/carpet/green, /area/centcom/central_command_areas/briefing) "eH" = ( /obj/structure/flora/bush/sparsegrass/style_random, @@ -1112,10 +1209,15 @@ /turf/open/floor/iron/dark, /area/centcom/central_command_areas/courtroom) "eV" = ( -/obj/structure/table/reinforced, -/obj/item/book/manual/wiki/security_space_law, -/obj/item/taperecorder, -/turf/open/floor/iron/grimy, +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, +/obj/structure/window/reinforced/spawner/directional/east, +/obj/structure/window/reinforced/spawner/directional/south, +/obj/machinery/modular_computer/preset/id{ + dir = 1 + }, +/turf/open/floor/carpet/green, /area/centcom/central_command_areas/briefing) "eX" = ( /obj/effect/turf_decal/siding/wood/corner{ @@ -1126,9 +1228,7 @@ /area/centcom/central_command_areas/evacuation/ship) "fa" = ( /obj/machinery/status_display/evac/directional/south, -/obj/effect/turf_decal/tile/green{ - dir = 8 - }, +/obj/effect/turf_decal/trimline/green/arrow_cw, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "fb" = ( @@ -1176,18 +1276,8 @@ /obj/effect/turf_decal/tile/green/half/contrasted, /turf/open/floor/iron, /area/centcom/tdome/observation) -"fi" = ( -/obj/structure/chair/office{ - dir = 8 - }, -/obj/effect/landmark/ert_spawn, -/obj/structure/cable, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/centcom/central_command_areas/briefing) "fj" = ( /obj/structure/extinguisher_cabinet/directional/east, -/obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/armory) "fk" = ( @@ -1208,9 +1298,14 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/centcom/central_command_areas/evacuation) +"fo" = ( +/obj/effect/turf_decal/trimline/green/arrow_cw{ + dir = 10 + }, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/briefing) "fu" = ( /obj/structure/reagent_dispensers/fueltank, -/obj/item/weldingtool/experimental, /obj/effect/decal/cleanable/blood/oil, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/stripes/line, @@ -1259,6 +1354,7 @@ }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, /obj/effect/mapping_helpers/airlock/access/all/admin/officer, +/obj/effect/turf_decal/siding/wood, /turf/open/floor/iron/white, /area/centcom/central_command_areas/admin) "fI" = ( @@ -1287,9 +1383,9 @@ /turf/open/floor/iron/dark, /area/centcom/central_command_areas/control) "fN" = ( -/obj/structure/closet/crate/bin, -/obj/machinery/light_switch/directional/south, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/siding/dark{ + dir = 1 + }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin) "fP" = ( @@ -1312,6 +1408,13 @@ }, /turf/open/space/basic, /area/space) +"fS" = ( +/obj/item/kirbyplants/organic/plant22, +/obj/effect/turf_decal/tile/green{ + dir = 4 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/ferry) "fT" = ( /obj/structure/lattice, /obj/structure/window/reinforced/spawner/directional/north, @@ -1394,7 +1497,18 @@ /area/centcom/central_command_areas/control) "gm" = ( /obj/structure/table/wood, -/obj/item/storage/dice, +/obj/item/storage/dice{ + pixel_x = -8; + pixel_y = 6 + }, +/obj/item/dice/d20{ + pixel_x = 6; + pixel_y = 6 + }, +/obj/item/dice/d10{ + pixel_x = 1; + pixel_y = 2 + }, /turf/open/floor/iron/grimy, /area/centcom/central_command_areas/admin) "gs" = ( @@ -1423,15 +1537,18 @@ /area/centcom/central_command_areas/evacuation/ship) "gw" = ( /obj/structure/table/reinforced, +/obj/machinery/firealarm/directional/north, /obj/item/grenade/c4{ pixel_x = 6 }, /obj/item/grenade/c4{ pixel_x = -4 }, -/obj/machinery/firealarm/directional/north, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/iron, +/obj/item/grenade/c4{ + pixel_x = 1; + pixel_y = 3 + }, +/turf/open/floor/iron/textured_large, /area/centcom/central_command_areas/armory) "gy" = ( /obj/machinery/shower/directional/east, @@ -1466,6 +1583,12 @@ }, /turf/open/floor/iron, /area/centcom/tdome/observation) +"gF" = ( +/obj/effect/turf_decal/siding/dark{ + dir = 4 + }, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/armory) "gH" = ( /obj/structure/closet/secure_closet/security, /obj/item/storage/belt/security/full, @@ -1478,8 +1601,8 @@ /area/centcom/central_command_areas/control) "gI" = ( /obj/machinery/status_display/evac/directional/north, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/effect/turf_decal/siding/wood, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "gL" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -1499,8 +1622,9 @@ /turf/open/floor/iron/dark, /area/centcom/central_command_areas/courtroom) "gS" = ( -/obj/effect/turf_decal/tile/neutral/fourcorners, /obj/structure/sign/warning/secure_area/directional/east, +/obj/effect/turf_decal/siding/dark, +/obj/machinery/light/directional/east, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/armory) "gU" = ( @@ -1509,13 +1633,21 @@ }, /turf/open/floor/iron, /area/centcom/tdome/observation) +"gW" = ( +/obj/structure/cable, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/briefing) "gX" = ( /obj/structure/table/reinforced, -/obj/item/storage/lockbox/loyalty, -/obj/effect/turf_decal/stripes/line{ - dir = 10 +/obj/item/storage/lockbox/loyalty{ + pixel_y = 8; + pixel_x = -4 }, -/turf/open/floor/iron, +/obj/item/tank/internals/emergency_oxygen/double, +/turf/open/floor/iron/textured_large, /area/centcom/central_command_areas/armory) "gY" = ( /obj/machinery/door/firedoor, @@ -1547,12 +1679,23 @@ /area/centcom/central_command_areas/control) "hd" = ( /obj/structure/table/wood, -/obj/item/paper_bin, -/obj/item/pen/fourcolor, -/turf/open/floor/iron/grimy, +/obj/item/paper_bin{ + pixel_y = 3; + pixel_x = 5 + }, +/obj/item/pen/fourcolor{ + pixel_x = 5; + pixel_y = 3 + }, +/obj/item/phone{ + desc = "Supposedly a direct line to Nanotrasen Central Command. It's not even plugged in."; + pixel_x = -6; + pixel_y = 7 + }, +/turf/open/floor/carpet/green, /area/centcom/central_command_areas/admin) "he" = ( -/obj/effect/turf_decal/tile/neutral/anticorner/contrasted{ +/obj/effect/turf_decal/tile/neutral/half/contrasted{ dir = 4 }, /turf/open/floor/iron/dark, @@ -1585,24 +1728,38 @@ /turf/open/misc/asteroid, /area/centcom/central_command_areas/evacuation) "ho" = ( -/obj/structure/table/wood, -/obj/item/folder/red, -/obj/item/book/manual/wiki/security_space_law, -/obj/item/restraints/handcuffs, -/obj/item/assembly/flash/handheld, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/trimline/dark_red/corner{ + dir = 1 + }, +/obj/item/kirbyplants/organic/plant11, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) +"ht" = ( +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/obj/effect/mapping_helpers/airlock/access/all/admin/general, +/obj/effect/turf_decal/trimline/green/arrow_cw, +/obj/machinery/door/airlock/centcom{ + name = "CentCom Security"; + id_tag = "HallwayLock" + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/ferry) +"hu" = ( +/obj/effect/mapping_helpers/airlock/access/all/admin/general, +/obj/machinery/door/airlock/centcom{ + name = "Administrative Office" + }, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/ferry) "hv" = ( /obj/machinery/barsign/all_access/directional/south, /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/machinery/griddle, /turf/open/floor/iron/dark, /area/centcom/tdome/observation) -"hx" = ( -/obj/machinery/photocopier/gratis/prebuilt, -/turf/open/floor/iron/grimy, -/area/centcom/central_command_areas/briefing) "hz" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, @@ -1632,6 +1789,12 @@ /obj/machinery/light/floor, /turf/open/floor/iron, /area/centcom/tdome/administration) +"hE" = ( +/obj/effect/turf_decal/siding/dark{ + dir = 8 + }, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/armory) "hF" = ( /obj/structure/table/reinforced, /obj/item/folder/red{ @@ -1688,38 +1851,76 @@ /area/centcom/central_command_areas/courtroom) "hT" = ( /obj/machinery/status_display/evac/directional/east, -/turf/open/floor/wood, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) +"hV" = ( +/obj/effect/turf_decal/tile/green/half{ + dir = 1 + }, +/turf/open/floor/iron/edge{ + dir = 1 + }, +/area/centcom/central_command_areas/ferry) "hW" = ( /obj/structure/chair/office, /turf/open/floor/iron/grimy, /area/centcom/central_command_areas/prison) "hY" = ( /obj/structure/table/reinforced, -/obj/item/storage/box/handcuffs, -/obj/item/crowbar/red, -/obj/item/crowbar/power, -/obj/item/storage/belt/security/full, +/obj/item/crowbar/power{ + pixel_y = 16 + }, +/obj/item/storage/belt/security/full{ + pixel_x = 6 + }, +/obj/item/storage/box/handcuffs{ + pixel_y = 4; + pixel_x = -6 + }, /obj/structure/extinguisher_cabinet/directional/east, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/iron, +/obj/effect/turf_decal/siding/dark, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/dark_red/half{ + dir = 1 + }, +/turf/open/floor/iron/textured_edge{ + dir = 1 + }, /area/centcom/central_command_areas/admin/storage) "ia" = ( -/obj/structure/chair/comfy/brown{ +/obj/structure/chair/sofa/corner/brown{ dir = 8 }, -/turf/open/floor/iron/grimy, +/turf/open/floor/carpet/executive, /area/centcom/central_command_areas/admin) +"ib" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/light/floor, +/turf/open/floor/plating, +/area/centcom/central_command_areas/briefing) +"id" = ( +/turf/open/floor/carpet/green, +/area/centcom/central_command_areas/briefing) "ie" = ( /obj/item/soap/nanotrasen, /turf/open/floor/iron/white, /area/centcom/tdome/observation) "ig" = ( /obj/structure/table/reinforced, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/obj/item/taperecorder, -/obj/item/book/manual/wiki/security_space_law, -/turf/open/floor/iron/dark, +/obj/item/taperecorder{ + pixel_x = -6; + pixel_y = 4 + }, +/obj/item/book/manual/wiki/security_space_law{ + pixel_x = 7 + }, +/turf/open/floor/iron/dark/textured_large, /area/centcom/central_command_areas/ferry) "ih" = ( /obj/structure/bookcase/random, @@ -1890,8 +2091,11 @@ }, /area/centcom/central_command_areas/supply) "iH" = ( -/obj/effect/turf_decal/tile/green, /obj/structure/sign/nanotrasen/directional/south, +/obj/effect/turf_decal/tile/green, +/obj/structure/chair{ + dir = 1 + }, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "iK" = ( @@ -2014,6 +2218,12 @@ }, /turf/open/floor/iron, /area/centcom/central_command_areas/supply) +"je" = ( +/obj/effect/turf_decal/trimline/green/arrow_ccw{ + dir = 9 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/ferry) "jf" = ( /obj/machinery/light/directional/east, /obj/effect/turf_decal/tile/brown/half/contrasted{ @@ -2281,6 +2491,20 @@ /obj/machinery/computer, /turf/open/floor/iron, /area/centcom/central_command_areas/prison) +"jZ" = ( +/obj/effect/turf_decal/trimline/dark_red/filled/warning{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/dark_red/filled/warning{ + dir = 8 + }, +/obj/machinery/door/poddoor/shutters{ + id = "CCFerry"; + name = "CC Ferry Hangar" + }, +/obj/machinery/light/floor, +/turf/open/floor/iron, +/area/centcom/central_command_areas/ferry) "ka" = ( /obj/effect/landmark/thunderdome/one, /obj/effect/turf_decal/stripes/line{ @@ -2306,8 +2530,7 @@ /area/centcom/tdome/administration) "kh" = ( /obj/machinery/telecomms/allinone/nuclear, -/obj/structure/sign/poster/contraband/syndicate_pistol/directional/north, -/turf/open/indestructible/dark, +/turf/open/floor/circuit, /area/centcom/central_command_areas/admin) "ki" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -2348,9 +2571,10 @@ /turf/open/floor/iron, /area/centcom/central_command_areas/supply) "ks" = ( -/obj/machinery/modular_computer/preset/id/centcom, /obj/machinery/status_display/ai/directional/north, -/turf/open/floor/iron/grimy, +/obj/structure/table/wood, +/obj/machinery/computer/security/wooden_tv, +/turf/open/floor/carpet/green, /area/centcom/central_command_areas/admin) "ku" = ( /obj/machinery/button/door/indestructible{ @@ -2366,6 +2590,12 @@ }, /turf/open/floor/iron, /area/centcom/tdome/observation) +"kw" = ( +/obj/effect/turf_decal/trimline/dark_red/warning{ + dir = 4 + }, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/briefing) "kx" = ( /obj/structure/filingcabinet/medical, /obj/effect/turf_decal/stripes/line{ @@ -2427,8 +2657,7 @@ /turf/open/floor/iron/grimy, /area/centcom/central_command_areas/courtroom) "kO" = ( -/obj/item/kirbyplants/organic/plant21, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/item/kirbyplants/organic/plant22, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) "kR" = ( @@ -2529,13 +2758,23 @@ /area/centcom/central_command_areas/evacuation/ship) "lj" = ( /obj/structure/table/wood, -/obj/item/paper_bin, -/obj/item/pen/fourcolor, +/obj/item/paper_bin{ + pixel_x = 7 + }, +/obj/item/pen/fourcolor{ + pixel_x = 7 + }, /obj/machinery/wall_healer/directional/north{ use_power = 0 }, /obj/machinery/computer/security/telescreen/entertainment/directional/west, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/item/flashlight/lamp{ + pixel_y = 12; + pixel_x = -7 + }, +/obj/effect/turf_decal/tile/green/half/contrasted{ + dir = 1 + }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin) "ln" = ( @@ -2593,8 +2832,8 @@ /area/centcom/central_command_areas/prison) "lw" = ( /obj/structure/chair/comfy/brown{ - buildstackamount = 0; - dir = 1 + dir = 1; + color = "#a75400" }, /turf/open/floor/iron/grimy, /area/centcom/central_command_areas/courtroom) @@ -2677,9 +2916,8 @@ /turf/open/floor/iron, /area/centcom/central_command_areas/control) "lU" = ( -/obj/structure/closet/crate/bin, -/obj/effect/turf_decal/tile/neutral/fourcorners, /obj/machinery/status_display/ai/directional/south, +/obj/item/kirbyplants/organic/plant22, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) "lV" = ( @@ -2697,6 +2935,15 @@ }, /turf/open/floor/iron/grimy, /area/centcom/central_command_areas/courtroom) +"lX" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/turf/open/floor/iron/grimy, +/area/centcom/central_command_areas/admin) "mc" = ( /obj/effect/light_emitter/podbay, /turf/open/floor/iron, @@ -2757,11 +3004,11 @@ /obj/structure/table/wood, /turf/open/floor/iron/grimy, /area/centcom/central_command_areas/courtroom) -"ms" = ( -/obj/effect/turf_decal/tile/neutral/fourcorners, +"mB" = ( /obj/machinery/light/floor, -/turf/open/floor/iron, -/area/centcom/central_command_areas/supplypod/loading/ert) +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/centcom/central_command_areas/ferry) "mC" = ( /obj/structure/window/reinforced/spawner/directional/east, /obj/machinery/computer/operating, @@ -2871,6 +3118,13 @@ /obj/machinery/status_display/evac/directional/north, /turf/open/floor/iron, /area/centcom/central_command_areas/prison) +"mU" = ( +/obj/effect/turf_decal/siding/dark, +/obj/effect/turf_decal/siding/dark/corner{ + dir = 1 + }, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/armory) "mW" = ( /obj/structure/reagent_dispensers/wall/peppertank/directional/west, /obj/effect/turf_decal/tile/red/half/contrasted{ @@ -2907,8 +3161,11 @@ /turf/open/floor/iron/dark/textured_large, /area/centcom/central_command_areas/evacuation/ship) "ne" = ( -/obj/effect/turf_decal/tile/green, /obj/machinery/status_display/ai/directional/south, +/obj/effect/turf_decal/tile/green, +/obj/structure/chair{ + dir = 1 + }, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "nj" = ( @@ -2918,7 +3175,7 @@ /area/centcom/tdome/observation) "nk" = ( /obj/machinery/light_switch/directional/east, -/turf/open/floor/iron/grimy, +/turf/open/floor/carpet/green, /area/centcom/central_command_areas/admin) "nl" = ( /obj/machinery/computer/security/mining{ @@ -2972,14 +3229,19 @@ /turf/open/floor/iron, /area/centcom/central_command_areas/fore) "nz" = ( -/obj/structure/table/reinforced, -/obj/machinery/fax/admin, -/turf/open/floor/iron/grimy, +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/obj/structure/table/wood, +/obj/machinery/computer/records/medical/laptop{ + dir = 8 + }, +/obj/structure/window/reinforced/spawner/directional/east, +/turf/open/floor/carpet/green, /area/centcom/central_command_areas/briefing) "nA" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "nC" = ( /obj/machinery/door/airlock/centcom{ @@ -3055,6 +3317,11 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/control) +"nR" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/light/floor, +/turf/open/floor/plating, +/area/centcom/central_command_areas/ferry) "nS" = ( /obj/structure/bookcase/random, /obj/machinery/light/directional/north, @@ -3134,11 +3401,11 @@ /turf/open/floor/plating, /area/centcom/central_command_areas/ferry) "oh" = ( -/obj/structure/table/wood, -/obj/item/paper_bin, -/obj/item/pen/fourcolor, /obj/machinery/airalarm/directional/south, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/siding/dark{ + dir = 1 + }, +/obj/structure/bookcase/random, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin) "oi" = ( @@ -3160,13 +3427,9 @@ /turf/open/space/basic, /area/space) "oo" = ( -/obj/structure/table/wood, -/obj/item/taperecorder, -/obj/item/storage/box/handcuffs, -/obj/item/flashlight/seclite, /obj/structure/noticeboard/directional/north, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/machinery/vending/boozeomat, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "op" = ( /obj/structure/sink/directional/west, @@ -3226,7 +3489,9 @@ "oB" = ( /obj/machinery/airalarm/directional/east, /obj/machinery/vending/wardrobe/cent_wardrobe, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/tile/green/half/contrasted{ + dir = 4 + }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin) "oF" = ( @@ -3272,13 +3537,14 @@ /area/centcom/central_command_areas/supply) "oK" = ( /obj/machinery/airalarm/directional/south, -/obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) "oL" = ( /obj/machinery/light/directional/east, -/obj/effect/turf_decal/tile/neutral/fourcorners, /obj/structure/sign/warning/secure_area/directional/east, +/obj/effect/turf_decal/siding/dark{ + dir = 1 + }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/armory) "oM" = ( @@ -3328,17 +3594,18 @@ /area/centcom/central_command_areas/supply) "oV" = ( /obj/structure/table/wood, -/obj/item/storage/briefcase/secure{ - pixel_x = 5; - pixel_y = 5 - }, -/obj/item/storage/lockbox/medal, /obj/machinery/newscaster{ pixel_x = 32 }, -/obj/effect/turf_decal/tile/neutral/fourcorners, /obj/machinery/computer/security/telescreen/research/directional/south, -/turf/open/floor/iron/dark, +/obj/item/storage/lockbox/medal{ + pixel_y = 2 + }, +/obj/item/flashlight/seclite{ + pixel_y = 11; + pixel_x = 2 + }, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "oW" = ( /obj/structure/flora/bush/lavendergrass/style_random, @@ -3450,26 +3717,35 @@ /obj/item/kirbyplants/organic/plant21, /obj/machinery/light/directional/east, /obj/structure/mirror/directional/east, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/tile/green/half/contrasted{ + dir = 4 + }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin) "pB" = ( -/obj/effect/turf_decal/stripes/line{ +/obj/effect/turf_decal/trimline/dark_red/warning{ dir = 9 }, /turf/open/floor/iron, /area/centcom/central_command_areas/supplypod/loading/ert) +"pC" = ( +/obj/effect/turf_decal/tile/green, +/obj/structure/chair{ + dir = 1 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/ferry) "pD" = ( -/obj/effect/turf_decal/stripes/line{ +/obj/effect/turf_decal/trimline/dark_red/warning{ dir = 5 }, /turf/open/floor/iron, /area/centcom/central_command_areas/supplypod/loading/ert) "pE" = ( -/obj/structure/chair/comfy/black{ +/obj/structure/chair/sofa/right/brown{ dir = 8 }, -/turf/open/floor/iron/grimy, +/turf/open/floor/carpet/executive, /area/centcom/central_command_areas/admin) "pH" = ( /obj/structure/flora/tree/palm{ @@ -3515,11 +3791,17 @@ /turf/open/floor/iron, /area/centcom/central_command_areas/supply) "pR" = ( -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/effect/turf_decal/tile/green/opposingcorners, +/obj/effect/turf_decal/siding/dark{ + dir = 8 + }, +/obj/effect/turf_decal/siding/dark{ + dir = 4 + }, +/turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "pT" = ( -/obj/effect/turf_decal/stripes/line{ +/obj/effect/turf_decal/trimline/dark_red/warning{ dir = 8 }, /turf/open/floor/iron, @@ -3538,7 +3820,7 @@ /turf/open/ai_visible, /area/centcom/ai_multicam_room) "pX" = ( -/obj/effect/turf_decal/stripes/line{ +/obj/effect/turf_decal/trimline/dark_red/warning{ dir = 4 }, /turf/open/floor/iron, @@ -3615,7 +3897,10 @@ /turf/open/floor/iron/dark, /area/centcom/tdome/administration) "ql" = ( -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/trimline/dark_red/filled/warning, +/obj/effect/turf_decal/trimline/dark_red/filled/warning{ + dir = 1 + }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin/storage) "qo" = ( @@ -3678,6 +3963,14 @@ name = "plating" }, /area/centcom/central_command_areas/control) +"qx" = ( +/obj/structure/cable, +/obj/effect/turf_decal/siding/dark{ + dir = 1 + }, +/obj/effect/turf_decal/siding/dark, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/armory) "qy" = ( /obj/structure/flora/bush/lavendergrass/style_random, /obj/structure/flora/bush/sparsegrass/style_random, @@ -3723,13 +4016,13 @@ /turf/open/floor/grass, /area/centcom/central_command_areas/evacuation) "qF" = ( -/obj/effect/turf_decal/stripes/line{ +/obj/effect/turf_decal/trimline/dark_red/warning{ dir = 10 }, /turf/open/floor/iron, /area/centcom/central_command_areas/supplypod/loading/ert) "qG" = ( -/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/trimline/dark_red/warning, /turf/open/floor/iron, /area/centcom/central_command_areas/supplypod/loading/ert) "qI" = ( @@ -3795,7 +4088,7 @@ /turf/open/floor/grass, /area/centcom/central_command_areas/evacuation) "rb" = ( -/obj/effect/turf_decal/stripes/line{ +/obj/effect/turf_decal/trimline/dark_red/warning{ dir = 6 }, /turf/open/floor/iron, @@ -3807,6 +4100,13 @@ /obj/machinery/light/directional/east, /turf/open/floor/iron/grimy, /area/centcom/central_command_areas/courtroom) +"rd" = ( +/obj/effect/turf_decal/trimline/green/arrow_ccw{ + dir = 1 + }, +/obj/structure/sign/poster/official/nanotrasen_logo/directional/north, +/turf/open/floor/iron, +/area/centcom/central_command_areas/ferry) "rf" = ( /obj/machinery/computer/records/medical{ dir = 1 @@ -3825,17 +4125,11 @@ /area/centcom/central_command_areas/courtroom) "rm" = ( /obj/machinery/computer/shuttle/labor, -/obj/effect/turf_decal/stripes/line{ - dir = 10 - }, -/turf/open/floor/iron, +/turf/open/floor/iron/dark/textured_large, /area/centcom/central_command_areas/ferry) "rn" = ( /obj/machinery/computer/shuttle/mining, -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/turf/open/floor/iron, +/turf/open/floor/iron/dark/textured_large, /area/centcom/central_command_areas/ferry) "ro" = ( /obj/machinery/newscaster/directional/north, @@ -3849,10 +4143,9 @@ /turf/open/floor/iron, /area/centcom/central_command_areas/evacuation) "rr" = ( -/obj/structure/table/wood, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/obj/item/clipboard, -/obj/item/radio/headset/headset_cent, +/obj/effect/turf_decal/trimline/dark_red/line{ + dir = 8 + }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) "rs" = ( @@ -3905,10 +4198,12 @@ /turf/cordon, /area/misc/start) "rB" = ( -/obj/structure/table/reinforced, -/obj/item/storage/fancy/donut_box, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/structure/table/reinforced/plastitaniumglass, +/obj/effect/turf_decal/tile/green/full, +/obj/item/storage/toolbox/mechanical{ + pixel_y = 2 + }, +/turf/open/floor/iron/dark/smooth_large, /area/centcom/central_command_areas/briefing) "rF" = ( /obj/structure/flora/bush/sparsegrass/style_random, @@ -4052,7 +4347,8 @@ /area/centcom/tdome/observation) "sd" = ( /obj/machinery/door/airlock/centcom{ - name = "Orbital Drop Pod Loading" + name = "Orbital Drop Pod Loading"; + id_tag = "PodLock" }, /obj/effect/mapping_helpers/airlock/access/all/admin/general, /turf/open/floor/iron, @@ -4092,23 +4388,22 @@ /obj/machinery/computer/shuttle/white_ship{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 5 - }, /obj/machinery/status_display/ai/directional/west, -/turf/open/floor/iron, +/turf/open/floor/iron/dark/textured_large, /area/centcom/central_command_areas/ferry) "sr" = ( /obj/structure/chair/office{ dir = 8 }, -/obj/effect/turf_decal/tile/green/anticorner/contrasted{ - dir = 1 +/obj/effect/turf_decal/tile/green/opposingcorners, +/obj/effect/turf_decal/siding/dark{ + dir = 9 }, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "ss" = ( -/obj/effect/turf_decal/tile/green{ +/obj/effect/turf_decal/tile/green/opposingcorners, +/obj/effect/turf_decal/siding/dark{ dir = 1 }, /turf/open/floor/iron, @@ -4117,7 +4412,8 @@ /obj/structure/chair/office{ dir = 1 }, -/obj/effect/turf_decal/tile/green{ +/obj/effect/turf_decal/tile/green/opposingcorners, +/obj/effect/turf_decal/siding/dark{ dir = 1 }, /turf/open/floor/iron, @@ -4130,8 +4426,9 @@ /area/centcom/central_command_areas/ferry) "sv" = ( /obj/structure/noticeboard/directional/east, -/obj/effect/turf_decal/tile/green/anticorner/contrasted{ - dir = 4 +/obj/effect/turf_decal/tile/green/opposingcorners, +/obj/effect/turf_decal/siding/dark{ + dir = 5 }, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) @@ -4169,7 +4466,10 @@ /turf/open/floor/iron, /area/centcom/tdome/observation) "sE" = ( -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/siding/dark, +/obj/effect/turf_decal/siding/dark/corner{ + dir = 4 + }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/armory) "sF" = ( @@ -4177,6 +4477,16 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/evacuation/ship) +"sG" = ( +/obj/structure/cable, +/obj/effect/turf_decal/siding/dark{ + dir = 1 + }, +/obj/effect/turf_decal/siding/dark/corner{ + dir = 8 + }, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/armory) "sH" = ( /obj/machinery/computer/security/telescreen, /obj/structure/table/reinforced, @@ -4291,16 +4601,20 @@ /turf/open/floor/iron/dark, /area/centcom/central_command_areas/supplypod) "tb" = ( -/obj/structure/table/wood, -/obj/item/paper_bin, -/obj/item/pen/fourcolor, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/effect/turf_decal/siding/wood, +/obj/structure/bookcase/random, +/turf/open/floor/carpet/green, /area/centcom/central_command_areas/briefing) "td" = ( /obj/structure/sign/departments/drop, /turf/closed/indestructible/riveted, /area/centcom/central_command_areas/ferry) +"te" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/turf/open/floor/wood/tile, +/area/centcom/central_command_areas/admin) "tg" = ( /obj/structure/chair{ dir = 1 @@ -4309,51 +4623,38 @@ /obj/effect/turf_decal/tile/green/half/contrasted, /turf/open/floor/iron, /area/centcom/central_command_areas/control) -"tl" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, -/turf/open/floor/wood, -/area/centcom/central_command_areas/admin) "tn" = ( -/obj/structure/chair{ - dir = 8 - }, /obj/machinery/computer/security/telescreen/entertainment/directional/south, /obj/structure/sign/warning/secure_area/directional/east, -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, /obj/machinery/light/directional/south, +/obj/structure/chair{ + dir = 1 + }, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "to" = ( /obj/machinery/computer/shuttle/ferry{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, /obj/machinery/status_display/evac/directional/west, -/turf/open/floor/iron, +/turf/open/floor/iron/dark/textured_large, /area/centcom/central_command_areas/ferry) "tp" = ( -/obj/effect/turf_decal/tile/green/anticorner/contrasted{ - dir = 8 +/obj/effect/turf_decal/tile/green/opposingcorners, +/obj/effect/turf_decal/siding/dark{ + dir = 10 }, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "tq" = ( /obj/structure/chair/office, -/obj/effect/turf_decal/tile/green{ - dir = 8 - }, +/obj/effect/turf_decal/tile/green/opposingcorners, +/obj/effect/turf_decal/siding/dark, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "tr" = ( -/obj/effect/turf_decal/tile/green{ - dir = 8 - }, +/obj/effect/turf_decal/tile/green/opposingcorners, +/obj/effect/turf_decal/siding/dark, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "ts" = ( @@ -4361,7 +4662,10 @@ /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "tt" = ( -/obj/effect/turf_decal/tile/green/anticorner/contrasted, +/obj/effect/turf_decal/tile/green/opposingcorners, +/obj/effect/turf_decal/siding/dark{ + dir = 6 + }, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "tu" = ( @@ -4372,24 +4676,14 @@ dir = 8 }, /obj/effect/mapping_helpers/airlock/access/all/admin/general, -/turf/open/floor/iron, +/turf/open/floor/iron/dark, /area/centcom/central_command_areas/ferry) "ty" = ( -/obj/structure/filingcabinet/security, /obj/machinery/status_display/evac/directional/south, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/structure/closet/crate/bin, +/obj/item/trash/cheesie, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) -"tA" = ( -/obj/machinery/door/poddoor/shutters{ - id = "CCFerry"; - name = "CC Ferry Hangar" - }, -/obj/effect/turf_decal/loading_area{ - dir = 4 - }, -/turf/open/floor/iron, -/area/centcom/central_command_areas/ferry) "tF" = ( /obj/machinery/door/airlock/centcom{ name = "Thunderdome Locker Room" @@ -4475,7 +4769,7 @@ /area/centcom/central_command_areas/evacuation) "tW" = ( /obj/structure/sign/poster/contraband/syndicate_recruitment/directional/north, -/turf/open/indestructible/dark, +/turf/open/floor/circuit, /area/centcom/central_command_areas/admin) "ub" = ( /obj/structure/sign/directions/command, @@ -4501,8 +4795,9 @@ /turf/open/floor/iron/dark, /area/centcom/central_command_areas/evacuation) "uh" = ( -/obj/structure/chair/comfy/black{ - dir = 1 +/obj/structure/chair/comfy/brown{ + dir = 1; + color = "#a75400" }, /turf/open/floor/iron/grimy, /area/centcom/central_command_areas/admin) @@ -4539,10 +4834,7 @@ /obj/machinery/computer/communications{ dir = 1 }, -/obj/effect/turf_decal/stripes/line{ - dir = 5 - }, -/turf/open/floor/iron, +/turf/open/floor/iron/dark/textured_large, /area/centcom/central_command_areas/ferry) "up" = ( /obj/structure/table/wood, @@ -4572,6 +4864,12 @@ }, /turf/open/space/basic, /area/space) +"uv" = ( +/obj/effect/turf_decal/siding/wood/corner{ + dir = 4 + }, +/turf/open/floor/wood/tile, +/area/centcom/central_command_areas/admin) "uw" = ( /obj/structure/chair/office, /obj/effect/turf_decal/tile/red/half/contrasted, @@ -4658,18 +4956,26 @@ /turf/open/floor/iron/dark, /area/centcom/central_command_areas/courtroom) "uO" = ( +/obj/effect/mapping_helpers/airlock/access/all/admin/general, +/obj/effect/turf_decal/tile/green/opposingcorners, +/obj/effect/turf_decal/siding/dark/end, /obj/machinery/door/airlock/centcom{ name = "Shuttle Control Office" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/mapping_helpers/airlock/access/all/admin/general, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "uP" = ( -/obj/item/flashlight/lamp, +/obj/item/flashlight/lamp{ + pixel_y = 7; + pixel_x = -7 + }, +/obj/item/storage/box/ids{ + pixel_x = 6; + pixel_y = 3 + }, +/obj/structure/window/reinforced/spawner/directional/west, /obj/structure/table/reinforced, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/turf/open/floor/iron/grimy, /area/centcom/central_command_areas/admin) "uQ" = ( /obj/effect/turf_decal/tile/neutral/opposingcorners, @@ -4785,9 +5091,8 @@ }, /area/centcom/central_command_areas/evacuation) "vm" = ( -/obj/effect/turf_decal/delivery, -/obj/machinery/light/directional/south, -/turf/open/floor/iron, +/obj/effect/turf_decal/tile/green/half, +/turf/open/floor/iron/edge, /area/centcom/central_command_areas/ferry) "vn" = ( /obj/item/kirbyplants/organic/plant21, @@ -4803,8 +5108,8 @@ /obj/machinery/door/window/brigdoor/left/directional/south{ name = "Shower" }, -/obj/item/soap/deluxe, /obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/item/soap/nanotrasen, /turf/open/floor/iron/white, /area/centcom/central_command_areas/admin) "vq" = ( @@ -4832,8 +5137,11 @@ /obj/item/kirbyplants/organic/plant22, /obj/machinery/newscaster/directional/west, /obj/machinery/status_display/evac/directional/north, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/effect/turf_decal/siding/wood, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "vA" = ( /obj/effect/spawner/structure/window/reinforced, @@ -4858,36 +5166,22 @@ /area/centcom/central_command_areas/ferry) "vC" = ( /obj/machinery/light/directional/north, -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/turf/open/floor/iron, -/area/centcom/central_command_areas/ferry) -"vD" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/structure/chair{ + pixel_y = -2 }, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "vE" = ( /obj/machinery/firealarm/directional/north, -/obj/structure/chair{ - dir = 8 - }, /obj/structure/extinguisher_cabinet/directional/east, -/obj/effect/turf_decal/stripes/line{ - dir = 5 +/obj/structure/chair{ + pixel_y = -2 }, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "vF" = ( -/obj/machinery/door/airlock/centcom{ - name = "Administrative Office" - }, -/obj/effect/turf_decal/stripes/line, /obj/structure/cable, -/obj/effect/mapping_helpers/airlock/access/all/admin/general, -/turf/open/floor/iron, +/turf/closed/indestructible/riveted, /area/centcom/central_command_areas/ferry) "vG" = ( /obj/effect/turf_decal/stripes/line{ @@ -4932,6 +5226,10 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/iron, /area/centcom/central_command_areas/control) +"vT" = ( +/obj/effect/turf_decal/trimline/green/line, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/briefing) "vU" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -4992,14 +5290,17 @@ /area/centcom/tdome/observation) "wg" = ( /obj/structure/closet/secure_closet/ert_com, -/obj/effect/turf_decal/stripes/line, /obj/machinery/status_display/ai/directional/east, -/turf/open/floor/iron, +/obj/effect/turf_decal/tile/dark_blue/half{ + dir = 1 + }, +/turf/open/floor/iron/textured_half, /area/centcom/central_command_areas/armory) "wh" = ( /obj/structure/cable, -/obj/effect/turf_decal/tile/green, /obj/structure/sign/warning/secure_area/directional/south, +/obj/machinery/light/directional/south, +/obj/effect/turf_decal/tile/green, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "wj" = ( @@ -5047,31 +5348,26 @@ /turf/open/floor/iron, /area/centcom/tdome/arena) "wq" = ( -/obj/structure/chair/comfy/black{ - dir = 1 - }, /obj/machinery/computer/security/telescreen/entertainment/directional/west, +/obj/structure/chair/comfy/brown{ + dir = 1; + color = "#a75400" + }, /turf/open/floor/iron/grimy, /area/centcom/central_command_areas/admin) -"wr" = ( -/obj/structure/chair{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/iron, -/area/centcom/central_command_areas/ferry) "wt" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/effect/turf_decal/trimline/green/arrow_cw{ + dir = 10 }, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "wv" = ( -/obj/effect/turf_decal/loading_area{ +/obj/effect/turf_decal/trimline/dark_red/filled/warning{ dir = 4 }, +/obj/effect/turf_decal/trimline/dark_red/filled/warning{ + dir = 8 + }, /obj/machinery/door/poddoor/shutters{ id = "CCFerry"; name = "CC Ferry Hangar" @@ -5079,31 +5375,32 @@ /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "ww" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 5 +/obj/effect/turf_decal/trimline/green/arrow_ccw{ + dir = 1 }, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "wx" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 10 +/obj/structure/sign/warning/secure_area/directional/south, +/obj/structure/chair{ + dir = 1 }, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "wy" = ( -/obj/effect/turf_decal/delivery, /obj/structure/cable, -/turf/open/floor/iron, -/area/centcom/central_command_areas/ferry) -"wz" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 6 +/obj/effect/turf_decal/trimline/green/arrow_ccw{ + dir = 1 }, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) +"wz" = ( +/obj/effect/turf_decal/trimline/green/arrow_cw, +/turf/open/floor/iron, +/area/centcom/central_command_areas/ferry) "wB" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 9 +/obj/effect/turf_decal/trimline/green/corner{ + dir = 8 }, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) @@ -5208,9 +5505,6 @@ /turf/open/floor/catwalk_floor, /area/centcom/central_command_areas/evacuation/ship) "xc" = ( -/obj/machinery/door/airlock/external/ruin{ - name = "Ferry Airlock" - }, /obj/effect/turf_decal/stripes/line{ dir = 8 }, @@ -5218,29 +5512,32 @@ dir = 4 }, /obj/effect/mapping_helpers/airlock/access/all/admin/general, +/obj/machinery/door/airlock/external/ruin{ + name = "Ferry Airlock" + }, +/obj/structure/fans/tiny, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "xd" = ( -/obj/structure/fans/tiny, /obj/effect/turf_decal/delivery, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "xe" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 +/obj/effect/turf_decal/trimline/green/arrow_ccw{ + dir = 1 }, -/turf/open/floor/iron, -/area/centcom/central_command_areas/ferry) -"xf" = ( -/obj/effect/turf_decal/bot, +/obj/effect/turf_decal/trimline/green/arrow_cw, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "xg" = ( -/obj/structure/chair{ +/obj/effect/turf_decal/trimline/green/corner{ dir = 8 }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 +/obj/effect/turf_decal/trimline/green/corner{ + dir = 1 + }, +/obj/structure/chair{ + dir = 8 }, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) @@ -5253,18 +5550,6 @@ }, /turf/open/floor/plating, /area/centcom/central_command_areas/ferry) -"xj" = ( -/obj/effect/turf_decal/tile/green/half/contrasted{ - dir = 8 - }, -/turf/open/floor/iron, -/area/centcom/central_command_areas/ferry) -"xk" = ( -/obj/effect/turf_decal/tile/green/half/contrasted{ - dir = 4 - }, -/turf/open/floor/iron, -/area/centcom/central_command_areas/ferry) "xl" = ( /obj/effect/turf_decal/tile/neutral/half/contrasted{ dir = 8 @@ -5305,15 +5590,20 @@ /turf/open/floor/iron, /area/centcom/tdome/arena) "xy" = ( -/obj/effect/turf_decal/stripes/line, -/obj/effect/decal/cleanable/dirt, /obj/structure/reagent_dispensers/fueltank, /obj/item/weldingtool/experimental, /obj/machinery/power/terminal{ dir = 8 }, /obj/structure/cable, -/turf/open/floor/iron, +/obj/effect/turf_decal/siding/dark, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow/half{ + dir = 1 + }, +/turf/open/floor/iron/textured_edge{ + dir = 1 + }, /area/centcom/central_command_areas/admin/storage) "xD" = ( /obj/machinery/computer/security{ @@ -5349,10 +5639,10 @@ /turf/open/floor/iron, /area/centcom/central_command_areas/control) "xR" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 5 - }, /obj/structure/cable, +/obj/effect/turf_decal/trimline/green/arrow_ccw{ + dir = 4 + }, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "xS" = ( @@ -5361,10 +5651,12 @@ name = "CC Shutter 4 Control"; pixel_y = -24 }, -/obj/effect/turf_decal/stripes/line{ - dir = 10 +/obj/effect/turf_decal/tile/green/half{ + dir = 4 + }, +/turf/open/floor/iron/edge{ + dir = 4 }, -/turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "xT" = ( /obj/effect/turf_decal/tile/green{ @@ -5373,9 +5665,8 @@ /turf/open/floor/iron, /area/centcom/central_command_areas/control) "xU" = ( -/obj/structure/filingcabinet/medical, -/obj/effect/turf_decal/tile/neutral/fourcorners, /obj/machinery/light/directional/south, +/obj/structure/bookcase/random, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) "xV" = ( @@ -5436,7 +5727,10 @@ /obj/machinery/atmospherics/components/unary/vent_pump{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/trimline/dark_red/filled/warning, +/obj/effect/turf_decal/trimline/dark_red/filled/warning{ + dir = 1 + }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin/storage) "yj" = ( @@ -5470,15 +5764,17 @@ /turf/open/floor/iron/dark, /area/centcom/central_command_areas/control) "yp" = ( -/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/loading_area/red, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "yr" = ( +/obj/effect/mapping_helpers/airlock/access/all/admin/general, +/obj/effect/turf_decal/trimline/green/arrow_cw{ + dir = 8 + }, /obj/machinery/door/airlock/centcom{ name = "Briefing Room" }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/mapping_helpers/airlock/access/all/admin/general, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "yx" = ( @@ -5537,15 +5833,14 @@ /turf/open/floor/iron/dark, /area/centcom/central_command_areas/evacuation/ship) "yL" = ( -/obj/structure/table/wood, -/obj/item/storage/fancy/donut_box, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/structure/filingcabinet/employment, +/obj/machinery/newscaster/directional/north, +/turf/open/floor/carpet/green, /area/centcom/central_command_areas/briefing) "yO" = ( /obj/machinery/computer/communications, /obj/machinery/status_display/evac/directional/north, -/turf/open/floor/iron/grimy, +/turf/open/floor/carpet/green, /area/centcom/central_command_areas/admin) "yP" = ( /obj/machinery/newscaster{ @@ -5560,29 +5855,46 @@ /turf/open/floor/iron, /area/centcom/central_command_areas/supply) "yR" = ( -/obj/item/clipboard, -/obj/item/folder/red, +/obj/item/clipboard{ + pixel_x = -6; + pixel_y = -4 + }, +/obj/item/folder/blue{ + pixel_x = -6; + pixel_y = -4 + }, /obj/item/stamp/denied{ pixel_x = 6; - pixel_y = 6 + pixel_y = 3 }, /obj/item/stamp/granted{ pixel_x = 3; - pixel_y = 3 + pixel_y = 0 }, -/obj/structure/table/reinforced, -/obj/item/stamp/centcom, -/turf/open/floor/iron/grimy, +/obj/item/stamp/centcom{ + pixel_y = -3 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/obj/structure/table/wood, +/obj/machinery/door/window/brigdoor/right/directional/east{ + name = "Briefing Desk"; + req_access = list("cent_captain") + }, +/turf/open/floor/carpet/green, /area/centcom/central_command_areas/briefing) "yS" = ( /obj/structure/table/reinforced, -/obj/item/storage/box/emps, -/obj/item/gun/energy/ionrifle, -/obj/structure/sign/departments/medbay/alt/directional/south, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/item/gun/energy/ionrifle{ + pixel_y = 9 }, -/turf/open/floor/iron, +/obj/item/storage/box/emps{ + pixel_x = -6; + pixel_y = 4 + }, +/obj/structure/sign/departments/medbay/alt/directional/south, +/turf/open/floor/iron/textured_large, /area/centcom/central_command_areas/armory) "yV" = ( /obj/docking_port/stationary{ @@ -5624,7 +5936,8 @@ /area/centcom/central_command_areas/control) "zc" = ( /obj/structure/chair/comfy/brown{ - dir = 1 + dir = 1; + color = "#a75400" }, /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, @@ -5732,11 +6045,16 @@ /turf/closed/wall/mineral/titanium/nodiagonal, /area/centcom/central_command_areas/evacuation/ship) "zz" = ( -/obj/structure/table/reinforced, -/obj/item/restraints/handcuffs/cable/zipties, -/obj/item/assembly/flash/handheld, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/structure/table/reinforced/plastitaniumglass, +/obj/effect/turf_decal/tile/green/full, +/obj/item/storage/medkit/o2{ + pixel_y = 12; + pixel_x = 1 + }, +/obj/item/storage/medkit/toxin{ + pixel_x = -1 + }, +/turf/open/floor/iron/dark/smooth_large, /area/centcom/central_command_areas/briefing) "zA" = ( /obj/structure/flora/bush/lavendergrass/style_random, @@ -5839,7 +6157,7 @@ "zU" = ( /obj/item/kirbyplants/organic/plant22, /obj/machinery/light_switch/directional/south, -/turf/open/floor/wood, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "zW" = ( /obj/structure/table, @@ -5988,12 +6306,9 @@ /turf/open/floor/iron, /area/centcom/tdome/observation) "AF" = ( -/obj/structure/table/wood, -/obj/item/storage/photo_album, -/obj/item/camera, /obj/structure/reagent_dispensers/wall/peppertank/directional/north, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/effect/turf_decal/siding/wood/corner, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "AG" = ( /obj/structure/table/wood, @@ -6014,17 +6329,11 @@ /area/centcom/central_command_areas/supplypod/loading/one) "AK" = ( /obj/machinery/light_switch/directional/north, -/turf/open/floor/wood, -/area/centcom/central_command_areas/admin) -"AL" = ( -/obj/structure/chair/office{ - dir = 1 +/obj/effect/turf_decal/siding/wood/corner{ + dir = 8 }, -/obj/effect/landmark/ert_spawn, -/obj/structure/cable, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/centcom/central_command_areas/briefing) +/turf/open/floor/wood/tile, +/area/centcom/central_command_areas/admin) "AO" = ( /obj/machinery/computer/communications{ dir = 8 @@ -6117,10 +6426,22 @@ /turf/open/floor/iron, /area/centcom/tdome/administration) "Bl" = ( -/obj/structure/bookcase/random, -/obj/effect/turf_decal/tile/neutral/fourcorners, /obj/machinery/light/small/directional/west, -/turf/open/floor/iron/dark, +/obj/structure/table/wood, +/obj/machinery/chem_dispenser/drinks/fullupgrade{ + dir = 4 + }, +/turf/open/floor/wood/tile, +/area/centcom/central_command_areas/admin) +"Bn" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, +/obj/effect/turf_decal/siding/wood/corner{ + dir = 8 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "Bo" = ( /obj/effect/turf_decal/tile/green{ @@ -6134,13 +6455,13 @@ /turf/open/floor/iron, /area/centcom/tdome/administration) "Br" = ( -/obj/structure/chair/comfy/black{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ dir = 4 }, -/turf/open/floor/iron/grimy, +/obj/structure/chair/sofa/corner/brown{ + dir = 1 + }, +/turf/open/floor/carpet/executive, /area/centcom/central_command_areas/admin) "Bs" = ( /obj/structure/table/reinforced, @@ -6153,19 +6474,18 @@ /turf/open/floor/iron, /area/centcom/tdome/observation) "Bu" = ( -/obj/item/kirbyplants/organic/plant21, /obj/machinery/status_display/evac/directional/west, -/obj/effect/turf_decal/tile/neutral/anticorner/contrasted{ - dir = 4 +/obj/structure/table/wood, +/obj/item/storage/fancy/donut_box{ + pixel_y = 5 }, -/turf/open/floor/iron/dark, +/turf/open/floor/carpet/green, /area/centcom/central_command_areas/briefing) "By" = ( /obj/machinery/light/directional/south, /obj/structure/filingcabinet/chestdrawer, /obj/machinery/status_display/evac/directional/south, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/turf/open/floor/iron/dark/textured_large, /area/centcom/central_command_areas/ferry) "BA" = ( /obj/machinery/door/airlock/centcom{ @@ -6314,11 +6634,19 @@ /area/centcom/central_command_areas/evacuation/ship) "BT" = ( /obj/structure/table/wood, -/obj/item/clipboard, -/obj/item/toy/figure/dsquad, +/obj/item/clipboard{ + pixel_y = 2 + }, +/obj/item/toy/figure/dsquad{ + pixel_y = 8; + pixel_x = -6 + }, /obj/machinery/computer/security/telescreen/entertainment/directional/south, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/item/toy/figure/captain{ + pixel_y = 1; + pixel_x = 1 + }, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "BU" = ( /obj/item/clipboard, @@ -6398,10 +6726,10 @@ /turf/open/floor/iron, /area/centcom/central_command_areas/supplypod/loading/four) "Cp" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, /obj/structure/sign/warning/secure_area/directional/north, +/obj/effect/turf_decal/trimline/green/arrow_ccw{ + dir = 5 + }, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "Cq" = ( @@ -6445,6 +6773,18 @@ }, /turf/open/floor/iron, /area/centcom/tdome/observation) +"CC" = ( +/obj/effect/mapping_helpers/airlock/access/all/admin/general, +/obj/effect/turf_decal/siding/dark{ + dir = 4 + }, +/obj/machinery/door/airlock/centcom{ + name = "Orbital Drop Pod Quick Access"; + id_tag = "QuickAccess" + }, +/obj/effect/mapping_helpers/airlock/locked, +/turf/open/floor/iron, +/area/centcom/central_command_areas/briefing) "CE" = ( /obj/item/clipboard, /obj/item/folder/red, @@ -6518,6 +6858,12 @@ /obj/machinery/light/directional/west, /turf/open/floor/iron, /area/centcom/central_command_areas/control) +"CQ" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/briefing) "CT" = ( /obj/structure/table/reinforced, /obj/structure/railing{ @@ -6544,8 +6890,8 @@ "CU" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, /obj/structure/cable, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/effect/turf_decal/siding/wood, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "CV" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, @@ -6592,7 +6938,11 @@ /area/centcom/central_command_areas/prison/cells) "Dk" = ( /obj/structure/cable, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/siding/dark{ + dir = 1 + }, +/obj/structure/table/wood, +/obj/machinery/coffeemaker/impressa, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin) "Dm" = ( @@ -6731,9 +7081,8 @@ /turf/closed/indestructible/riveted, /area/centcom/central_command_areas/armory) "Eb" = ( -/obj/item/kirbyplants/organic/plant21, /obj/structure/extinguisher_cabinet/directional/south, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/item/kirbyplants/organic/plant12, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) "Ee" = ( @@ -6762,19 +7111,17 @@ /turf/open/floor/iron/dark, /area/centcom/central_command_areas/control) "Em" = ( -/obj/item/paper_bin, -/obj/item/pen/fourcolor, -/obj/structure/table/reinforced, /obj/machinery/newscaster/directional/east, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/structure/window/reinforced/spawner/directional/south, +/obj/machinery/modular_computer/preset/id/centcom{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, +/turf/open/floor/iron/grimy, /area/centcom/central_command_areas/admin) "En" = ( -/obj/structure/chair/comfy/black, /obj/machinery/computer/security/telescreen/entertainment/directional/west, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, +/obj/structure/chair/sofa/right/brown, /turf/open/floor/iron/grimy, /area/centcom/central_command_areas/admin) "Eq" = ( @@ -6795,6 +7142,12 @@ /obj/item/kirbyplants, /turf/open/floor/iron/dark/textured_large, /area/centcom/central_command_areas/evacuation/ship) +"Et" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/turf/open/floor/iron/grimy, +/area/centcom/central_command_areas/admin) "Ev" = ( /obj/structure/window/reinforced/spawner/directional/east, /obj/structure/bodycontainer/morgue{ @@ -6874,13 +7227,15 @@ /turf/open/floor/iron, /area/centcom/tdome/arena) "EJ" = ( -/obj/structure/chair/comfy/brown{ - color = "#596479"; - dir = 1 - }, /obj/machinery/atmospherics/components/unary/vent_pump{ dir = 8 }, +/obj/effect/turf_decal/siding/wood{ + dir = 5 + }, +/obj/structure/chair/office{ + dir = 4 + }, /turf/open/floor/iron/grimy, /area/centcom/central_command_areas/admin) "EK" = ( @@ -6913,6 +7268,14 @@ /obj/machinery/door/firedoor, /turf/open/floor/iron/dark, /area/centcom/tdome/administration) +"ES" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/item/storage/toolbox/mechanical{ + pixel_x = -4; + pixel_y = 10 + }, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/admin) "EV" = ( /obj/structure/table/wood, /obj/machinery/microwave{ @@ -6933,6 +7296,12 @@ }, /turf/open/floor/iron, /area/centcom/central_command_areas/supplypod/loading/three) +"Fc" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/turf/open/floor/wood/tile, +/area/centcom/central_command_areas/admin) "Fe" = ( /obj/structure/sink/directional/west, /obj/structure/mirror/directional/east, @@ -6954,8 +7323,8 @@ /area/centcom/central_command_areas/control) "Fh" = ( /obj/item/kirbyplants/organic/plant21, -/obj/effect/turf_decal/delivery, -/turf/open/floor/iron, +/obj/effect/turf_decal/box, +/turf/open/floor/iron/large, /area/centcom/central_command_areas/ferry) "Fj" = ( /obj/machinery/door/firedoor, @@ -7031,20 +7400,17 @@ }, /turf/open/floor/iron/grimy, /area/centcom/tdome/administration) -"Fz" = ( -/obj/item/kirbyplants/organic/plant22, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/centcom/central_command_areas/briefing) "FB" = ( /obj/structure/table/reinforced, -/obj/item/storage/box/syringes, -/obj/item/gun/syringe/rapidsyringe, -/obj/structure/reagent_dispensers/wall/peppertank/directional/south, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/item/gun/syringe/rapidsyringe{ + pixel_y = 10 }, -/turf/open/floor/iron, +/obj/item/storage/box/syringes{ + pixel_x = 5; + pixel_y = 4 + }, +/obj/structure/reagent_dispensers/wall/peppertank/directional/south, +/turf/open/floor/iron/textured_large, /area/centcom/central_command_areas/armory) "FI" = ( /obj/effect/landmark/thunderdome/two, @@ -7088,10 +7454,23 @@ "FX" = ( /obj/machinery/computer/auxiliary_base/directional/north, /obj/structure/table/reinforced, -/obj/item/clipboard, -/obj/item/radio/headset/headset_cent, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/item/clipboard{ + pixel_x = -10; + pixel_y = 4 + }, +/obj/item/radio/headset/headset_cent{ + pixel_x = -8; + pixel_y = 2 + }, +/obj/item/hand_labeler{ + pixel_x = 4; + pixel_y = 8 + }, +/obj/item/stack/package_wrap{ + pixel_y = -1; + pixel_x = 3 + }, +/turf/open/floor/iron/dark/textured_large, /area/centcom/central_command_areas/ferry) "FZ" = ( /obj/effect/turf_decal/tile/neutral/half/contrasted{ @@ -7104,9 +7483,20 @@ /turf/closed/indestructible/fakeglass, /area/centcom/tdome/observation) "Ge" = ( -/obj/structure/bookcase/random, -/obj/effect/turf_decal/tile/neutral/fourcorners, /obj/structure/sign/nanotrasen/directional/south, +/obj/item/storage/box/drinkingglasses{ + pixel_y = 8; + pixel_x = -6 + }, +/obj/structure/table/wood, +/obj/item/reagent_containers/cup/glass/bottle/whiskey{ + pixel_y = 11; + pixel_x = 8 + }, +/obj/item/reagent_containers/cup/glass/drinkingglass{ + pixel_y = 3; + pixel_x = 4 + }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) "Gf" = ( @@ -7114,7 +7504,10 @@ /obj/machinery/atmospherics/components/unary/vent_pump{ dir = 8 }, -/turf/open/floor/iron/grimy, +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "Gi" = ( /obj/structure/window/reinforced/spawner/directional/north, @@ -7164,11 +7557,16 @@ /area/centcom/central_command_areas/control) "Gs" = ( /obj/machinery/power/smes/magical, -/obj/effect/turf_decal/stripes/line, /obj/effect/decal/cleanable/dirt, /obj/structure/cable, /obj/machinery/light/directional/north, -/turf/open/floor/iron, +/obj/effect/turf_decal/siding/dark, +/obj/effect/turf_decal/tile/yellow/half{ + dir = 1 + }, +/turf/open/floor/iron/textured_edge{ + dir = 1 + }, /area/centcom/central_command_areas/admin/storage) "Gy" = ( /obj/effect/turf_decal/siding/dark{ @@ -7178,24 +7576,41 @@ /area/centcom/tdome/administration) "GB" = ( /obj/machinery/power/apc/auto_name/directional/west, -/obj/effect/turf_decal/stripes/line, -/obj/effect/decal/cleanable/dirt, /obj/structure/table/reinforced, -/obj/item/stack/sheet/iron/fifty, -/obj/item/stack/sheet/iron/fifty, +/obj/item/stack/sheet/iron/fifty{ + pixel_x = -6; + pixel_y = 5 + }, +/obj/item/stack/sheet/iron/fifty{ + pixel_x = -6; + pixel_y = 5 + }, /obj/item/stack/sheet/plasteel{ - amount = 15 + amount = 15; + pixel_y = 7; + pixel_x = -6 }, /obj/item/stack/sheet/rglass{ amount = 50; - pixel_x = 2; - pixel_y = -2 + pixel_x = 6; + pixel_y = 4 + }, +/obj/item/stack/rods/fifty{ + pixel_y = 7 }, -/obj/item/stack/rods/fifty, /obj/item/stack/cable_coil, -/obj/item/screwdriver/power, +/obj/item/screwdriver/power{ + pixel_y = 11 + }, /obj/structure/cable, -/turf/open/floor/iron, +/obj/effect/turf_decal/siding/dark, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow/half{ + dir = 1 + }, +/turf/open/floor/iron/textured_edge{ + dir = 1 + }, /area/centcom/central_command_areas/admin/storage) "GC" = ( /obj/machinery/door/firedoor, @@ -7283,8 +7698,8 @@ /turf/open/indestructible/dark, /area/centcom/central_command_areas/prison/cells) "Hi" = ( -/obj/effect/turf_decal/tile/green, /obj/machinery/light/directional/south, +/obj/effect/turf_decal/tile/green, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "Hj" = ( @@ -7323,6 +7738,13 @@ /obj/effect/mapping_helpers/airlock/access/all/admin/captain, /turf/open/floor/iron, /area/centcom/central_command_areas/prison) +"Hq" = ( +/obj/structure/cable, +/obj/effect/turf_decal/trimline/green/arrow_ccw{ + dir = 6 + }, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/briefing) "Hs" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -7334,14 +7756,24 @@ /turf/closed/indestructible/riveted, /area/centcom/central_command_areas/courtroom) "Hw" = ( -/obj/item/kirbyplants/organic/plant21, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/machinery/light_switch/directional/south, +/obj/effect/turf_decal/siding/dark{ + dir = 1 + }, +/obj/structure/closet/crate/bin, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin) "Hz" = ( -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin) +"HC" = ( +/obj/item/kirbyplants/organic/plant17, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/briefing) "HE" = ( /obj/structure/flora/bush/lavendergrass/style_random, /obj/structure/flora/bush/fullgrass/style_random, @@ -7403,6 +7835,12 @@ /obj/machinery/status_display/evac/directional/south, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/courtroom) +"HN" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/admin) "HR" = ( /obj/structure/bed/medical/emergency, /obj/machinery/iv_drip, @@ -7424,7 +7862,8 @@ /area/centcom/central_command_areas/supply) "HW" = ( /obj/structure/chair/comfy/brown{ - dir = 1 + dir = 1; + color = "#a75400" }, /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/structure/sign/nanotrasen/directional/south, @@ -7513,6 +7952,12 @@ }, /turf/open/floor/iron, /area/centcom/central_command_areas/prison) +"Il" = ( +/obj/effect/turf_decal/trimline/dark_red/warning{ + dir = 8 + }, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/armory) "Im" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/centcom{ @@ -7549,10 +7994,7 @@ /obj/machinery/newscaster{ pixel_y = -32 }, -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/turf/open/floor/iron, +/turf/open/floor/iron/dark/textured_large, /area/centcom/central_command_areas/ferry) "Iv" = ( /obj/effect/turf_decal/siding/wood{ @@ -7576,11 +8018,16 @@ /area/centcom/central_command_areas/prison/cells) "IK" = ( /obj/structure/closet/secure_closet/ert_sec, -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, /obj/machinery/status_display/ai/directional/south, -/turf/open/floor/iron, +/obj/effect/turf_decal/tile/dark_red/half, +/turf/open/floor/iron/textured_half, +/area/centcom/central_command_areas/armory) +"IN" = ( +/obj/structure/cable, +/obj/effect/turf_decal/siding/dark{ + dir = 4 + }, +/turf/open/floor/iron/dark, /area/centcom/central_command_areas/armory) "IO" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -7629,7 +8076,9 @@ dir = 8 }, /obj/machinery/status_display/evac/directional/east, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/tile/green/half/contrasted{ + dir = 4 + }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin) "JE" = ( @@ -7645,6 +8094,10 @@ /obj/effect/turf_decal/tile/neutral/full, /turf/open/floor/iron/dark/textured_large, /area/centcom/central_command_areas/evacuation/ship) +"JG" = ( +/obj/effect/turf_decal/tile/neutral/half/contrasted, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/briefing) "JJ" = ( /obj/structure/table/wood, /obj/item/storage/fancy/donut_box, @@ -7652,7 +8105,9 @@ /turf/open/floor/iron/dark, /area/centcom/tdome/administration) "JO" = ( -/obj/machinery/modular_computer/preset/id/centcom, +/obj/structure/closet/crate/bin, +/obj/item/disk/nuclear/fake/obvious, +/obj/structure/sign/poster/official/do_not_question/directional/east, /turf/open/floor/iron/grimy, /area/centcom/central_command_areas/admin) "JS" = ( @@ -7692,11 +8147,37 @@ /turf/open/floor/iron/dark, /area/centcom/tdome/observation) "JW" = ( -/obj/structure/table/reinforced, -/obj/item/storage/briefcase/secure, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/structure/table/reinforced/plastitaniumglass, +/obj/item/assembly/flash/handheld{ + pixel_x = -6; + pixel_y = 2 + }, +/obj/item/restraints/handcuffs{ + pixel_x = 9; + pixel_y = 5 + }, +/obj/item/assembly/flash/handheld{ + pixel_x = -1; + pixel_y = 1 + }, +/obj/effect/turf_decal/tile/green/full, +/turf/open/floor/iron/dark/smooth_large, /area/centcom/central_command_areas/briefing) +"Kb" = ( +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/obj/effect/mapping_helpers/airlock/access/all/admin/general, +/obj/effect/turf_decal/trimline/green/arrow_ccw{ + dir = 1 + }, +/obj/machinery/door/airlock/centcom{ + name = "CentCom Security"; + id_tag = "HallwayLock" + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/ferry) "Kd" = ( /obj/effect/turf_decal/tile/red/opposingcorners, /obj/effect/turf_decal/tile/yellow/opposingcorners{ @@ -7705,18 +8186,19 @@ /turf/open/floor/iron, /area/centcom/tdome/observation) "Kf" = ( -/obj/machinery/door/airlock/centcom{ - name = "Administrative Storage" - }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, /obj/structure/cable, /obj/effect/mapping_helpers/airlock/access/all/admin/officer, -/turf/open/floor/iron, +/obj/effect/turf_decal/stripes/red/full, +/obj/effect/turf_decal/siding/dark{ + dir = 8 + }, +/obj/machinery/door/airlock/centcom{ + name = "Administrative Storage" + }, +/turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin) "Kg" = ( /obj/item/radio/intercom/directional/north, @@ -7753,16 +8235,15 @@ /area/centcom/central_command_areas/control) "Kv" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/airlock/centcom{ - name = "CentCom Security" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 8 }, /obj/effect/mapping_helpers/airlock/access/all/admin/general, +/obj/effect/turf_decal/trimline/green/arrow_cw, +/obj/machinery/door/airlock/centcom{ + name = "CentCom Security"; + id_tag = "HallwayLock" + }, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "KA" = ( @@ -7866,14 +8347,18 @@ "KW" = ( /obj/machinery/keycard_auth/wall_mounted/directional/south, /obj/structure/table/reinforced, -/obj/machinery/recharger, +/obj/machinery/recharger{ + pixel_x = 5 + }, /obj/machinery/button/door/indestructible{ id = "CCFerry"; name = "Hanger Bay Shutters"; pixel_y = -38 }, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/machinery/recharger{ + pixel_x = -5 + }, +/turf/open/floor/iron/dark/textured_large, /area/centcom/central_command_areas/ferry) "KZ" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -7921,6 +8406,12 @@ /obj/structure/marker_beacon/burgundy, /turf/open/floor/catwalk_floor, /area/centcom/central_command_areas/evacuation/ship) +"Lg" = ( +/obj/effect/turf_decal/tile/neutral/half/contrasted{ + dir = 4 + }, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/admin) "Li" = ( /obj/effect/turf_decal/tile/neutral/opposingcorners, /obj/effect/turf_decal/tile/neutral/opposingcorners, @@ -8175,16 +8666,19 @@ /area/centcom/tdome/arena) "Mo" = ( /obj/structure/bed, -/obj/item/bedsheet/black, -/obj/effect/turf_decal/tile/neutral/fourcorners, /obj/structure/sign/nanotrasen/directional/south, +/obj/item/bedsheet/nanotrasen, +/obj/effect/turf_decal/tile/green/half/contrasted, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin) "Mp" = ( +/obj/machinery/status_display/evac/directional/east, /obj/structure/table/wood, /obj/machinery/recharger, -/obj/machinery/status_display/evac/directional/east, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/item/radio/headset/headset_cent{ + pixel_x = 12; + pixel_y = 4 + }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) "Mr" = ( @@ -8209,7 +8703,10 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ dir = 4 }, -/turf/open/floor/wood, +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "Mu" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -8231,7 +8728,10 @@ dir = 4 }, /obj/structure/cable, -/turf/open/floor/wood, +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "Mz" = ( /obj/effect/spawner/structure/window/reinforced, @@ -8275,12 +8775,6 @@ }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/supplypod) -"MJ" = ( -/obj/structure/chair/office, -/obj/effect/landmark/ert_spawn, -/obj/structure/cable, -/turf/open/floor/iron/dark, -/area/centcom/central_command_areas/briefing) "MK" = ( /obj/effect/turf_decal/tile/neutral{ dir = 4 @@ -8315,7 +8809,13 @@ /area/centcom/tdome/observation) "MU" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, -/turf/open/floor/wood, +/obj/effect/turf_decal/siding/wood/corner{ + dir = 1 + }, +/obj/effect/turf_decal/siding/wood/corner{ + dir = 4 + }, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "MV" = ( /obj/structure/chair{ @@ -8336,6 +8836,13 @@ /obj/structure/sign/nanotrasen/directional/north, /turf/open/floor/iron, /area/centcom/central_command_areas/control) +"Nc" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/turf/open/floor/wood/tile, +/area/centcom/central_command_areas/admin) "Ne" = ( /obj/structure/table/wood, /obj/item/reagent_containers/cup/glass/trophy/gold_cup, @@ -8379,11 +8886,19 @@ /area/centcom/central_command_areas/evacuation/ship) "Nn" = ( /obj/structure/table/reinforced, -/obj/item/storage/lockbox/loyalty, +/obj/item/storage/lockbox/loyalty{ + pixel_y = 8; + pixel_x = -4 + }, /obj/item/gun/ballistic/automatic/ar, /obj/machinery/light/directional/north, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/iron, +/obj/effect/turf_decal/siding/dark, +/obj/effect/turf_decal/tile/dark_red/half{ + dir = 1 + }, +/turf/open/floor/iron/textured_edge{ + dir = 1 + }, /area/centcom/central_command_areas/admin/storage) "Np" = ( /obj/structure/bookcase/random, @@ -8399,15 +8914,27 @@ dir = 4 }, /obj/structure/cable, -/turf/open/floor/wood, +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "Nr" = ( +/obj/item/restraints/handcuffs{ + pixel_x = 1 + }, +/obj/structure/window/reinforced/spawner/directional/south, +/obj/structure/window/reinforced/spawner/directional/west, /obj/structure/table/reinforced, -/obj/item/folder/red, -/obj/item/restraints/handcuffs, -/obj/item/assembly/flash/handheld, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/machinery/recharger{ + pixel_y = 3; + pixel_x = -4 + }, +/obj/item/gun/energy/e_gun/mini{ + pixel_y = 17; + pixel_x = 1 + }, +/turf/open/floor/iron/grimy, /area/centcom/central_command_areas/admin) "Nw" = ( /obj/item/kirbyplants/organic/plant21, @@ -8423,11 +8950,19 @@ /area/centcom/central_command_areas/supply) "Ny" = ( /obj/structure/cable, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) "NC" = ( /obj/structure/cable, +/obj/effect/turf_decal/trimline/dark_red/warning{ + dir = 4 + }, +/obj/effect/turf_decal/caution/stand_clear/red{ + dir = 8 + }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) "NE" = ( @@ -8464,7 +8999,7 @@ "NM" = ( /obj/structure/closet/crate/bin, /obj/machinery/light/directional/south, -/turf/open/floor/wood, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "NN" = ( /obj/machinery/keycard_auth/wall_mounted/directional/south, @@ -8543,11 +9078,17 @@ }, /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/effect/mapping_helpers/airlock/access/all/admin/officer, -/turf/open/floor/iron/dark, +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/turf/open/floor/iron/grimy, /area/centcom/central_command_areas/admin) "Od" = ( /obj/structure/cable, -/turf/open/floor/wood, +/obj/effect/turf_decal/siding/wood/corner{ + dir = 4 + }, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "Of" = ( /obj/item/clipboard, @@ -8574,12 +9115,13 @@ /turf/open/floor/iron, /area/centcom/central_command_areas/evacuation) "Om" = ( -/obj/structure/table/reinforced, -/obj/item/clipboard, -/obj/item/folder/white, -/obj/item/pen/blue, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/structure/table/reinforced/plastitaniumglass, +/obj/item/storage/medkit/regular{ + pixel_y = 4; + pixel_x = -2 + }, +/obj/effect/turf_decal/tile/green/full, +/turf/open/floor/iron/dark/smooth_large, /area/centcom/central_command_areas/briefing) "On" = ( /turf/closed/indestructible/riveted, @@ -8593,7 +9135,10 @@ dir = 1 }, /obj/machinery/meter, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/trimline/dark_red/filled/warning, +/obj/effect/turf_decal/trimline/dark_red/filled/warning{ + dir = 1 + }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin/storage) "Ot" = ( @@ -8615,7 +9160,10 @@ dir = 1 }, /obj/structure/cable, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/trimline/dark_red/filled/warning, +/obj/effect/turf_decal/trimline/dark_red/filled/warning{ + dir = 1 + }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin/storage) "Ox" = ( @@ -8686,6 +9234,9 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/evacuation/ship) +"OG" = ( +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/armory) "OH" = ( /obj/machinery/computer/records/security{ dir = 4 @@ -8698,8 +9249,14 @@ /turf/open/floor/iron/dark/herringbone, /area/centcom/central_command_areas/evacuation/ship) "OK" = ( -/obj/effect/turf_decal/tile/neutral/fourcorners, /obj/structure/sign/warning/secure_area/directional/west, +/obj/effect/turf_decal/trimline/dark_red/corner{ + dir = 8 + }, +/obj/effect/turf_decal/siding/dark{ + dir = 1 + }, +/obj/machinery/light/directional/west, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/armory) "OM" = ( @@ -8736,12 +9293,14 @@ /turf/open/floor/iron, /area/centcom/central_command_areas/supplypod/loading/one) "OQ" = ( +/obj/structure/cable, +/obj/effect/mapping_helpers/airlock/access/all/admin/general, +/obj/effect/turf_decal/trimline/green/arrow_ccw{ + dir = 4 + }, /obj/machinery/door/airlock/centcom{ name = "Briefing Room" }, -/obj/effect/turf_decal/stripes/line, -/obj/structure/cable, -/obj/effect/mapping_helpers/airlock/access/all/admin/general, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "OR" = ( @@ -8774,19 +9333,22 @@ /turf/open/floor/iron/white/textured, /area/centcom/central_command_areas/evacuation/ship) "OX" = ( +/obj/structure/cable, +/obj/effect/turf_decal/tile/neutral/half/contrasted{ + dir = 1 + }, /obj/structure/chair/office{ dir = 1 }, /obj/effect/landmark/ert_spawn, -/obj/structure/cable, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) "OY" = ( -/obj/item/storage/fancy/donut_box, -/obj/structure/table/reinforced, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/structure/window/reinforced/spawner/directional/south, +/obj/machinery/modular_computer/preset/id{ + dir = 1 + }, +/turf/open/floor/iron/grimy, /area/centcom/central_command_areas/admin) "OZ" = ( /obj/structure/flora/bush/lavendergrass/style_random, @@ -8804,6 +9366,7 @@ /area/centcom/tdome/observation) "Pd" = ( /obj/machinery/light/small/directional/east, +/obj/effect/turf_decal/trimline/dark_red/corner, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) "Pe" = ( @@ -8898,17 +9461,23 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/trimline/dark_red/filled/warning, +/obj/effect/turf_decal/trimline/dark_red/filled/warning{ + dir = 1 + }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin/storage) "Pt" = ( /obj/structure/table/reinforced, -/obj/item/storage/toolbox/mechanical, -/obj/item/tank/internals/emergency_oxygen/engi, -/obj/effect/turf_decal/stripes/line{ - dir = 6 +/obj/item/storage/toolbox/mechanical{ + pixel_x = 4; + pixel_y = 10 }, -/turf/open/floor/iron, +/obj/item/storage/toolbox/electrical{ + pixel_x = 4; + pixel_y = 2 + }, +/turf/open/floor/iron/textured_large, /area/centcom/central_command_areas/armory) "Pv" = ( /obj/effect/turf_decal/tile/brown/half/contrasted{ @@ -8966,8 +9535,7 @@ /obj/machinery/firealarm/directional/south, /obj/structure/closet/crate/bin, /obj/structure/extinguisher_cabinet/directional/east, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/turf/open/floor/iron/dark/textured_large, /area/centcom/central_command_areas/ferry) "PJ" = ( /obj/structure/closet/crate/freezer/blood, @@ -8990,43 +9558,42 @@ /turf/open/misc/asteroid, /area/centcom/central_command_areas/evacuation) "PM" = ( +/obj/structure/cable, +/obj/effect/turf_decal/tile/neutral/half/contrasted, /obj/structure/chair/office, /obj/effect/landmark/ert_spawn, -/obj/structure/cable, -/obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) "PR" = ( -/obj/structure/table/wood, -/obj/item/phone{ - desc = "Supposedly a direct line to Nanotrasen Central Command. It's not even plugged in."; - pixel_x = -3; - pixel_y = 3 - }, -/obj/item/cigarette/cigar/cohiba{ - pixel_x = 6 - }, -/obj/item/cigarette/cigar/havana{ - pixel_x = 2 - }, -/obj/item/cigarette/cigar{ - pixel_x = 4.5 - }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ dir = 10 }, -/turf/open/floor/iron/grimy, +/obj/structure/chair/sofa/middle/brown{ + dir = 1 + }, +/turf/open/floor/carpet/executive, /area/centcom/central_command_areas/admin) "PT" = ( /obj/effect/turf_decal/tile/red/half/contrasted, /turf/open/floor/iron, /area/centcom/tdome/observation) "PU" = ( -/obj/structure/table/wood, -/obj/machinery/computer/records/medical/laptop, -/obj/effect/turf_decal/tile/neutral/fourcorners, /obj/machinery/light/directional/north, -/turf/open/floor/iron/dark, +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/obj/structure/table/wood, +/obj/item/phone{ + pixel_x = 5; + pixel_y = 6 + }, +/obj/item/lighter/greyscale{ + pixel_x = -4; + pixel_y = 5 + }, +/obj/item/storage/fancy/cigarettes/cigars, +/obj/structure/window/reinforced/spawner/directional/east, +/turf/open/floor/carpet/green, /area/centcom/central_command_areas/briefing) "PV" = ( /obj/effect/turf_decal/stripes/line{ @@ -9050,14 +9617,9 @@ /turf/open/floor/grass, /area/centcom/central_command_areas/evacuation/ship) "Qb" = ( -/obj/structure/table/wood, -/obj/item/folder/red, -/obj/item/book/manual/wiki/security_space_law, -/obj/item/restraints/handcuffs, -/obj/item/assembly/flash/handheld, /obj/machinery/airalarm/directional/south, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/item/kirbyplants/organic/plant21, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "Qd" = ( /obj/structure/table/wood, @@ -9135,6 +9697,21 @@ }, /turf/open/floor/iron, /area/centcom/tdome/observation) +"Qw" = ( +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/obj/effect/mapping_helpers/airlock/access/all/admin/general, +/obj/effect/turf_decal/trimline/green/arrow_ccw{ + dir = 1 + }, +/obj/machinery/door/airlock/centcom{ + name = "CentCom Security"; + id_tag = "HallwayLock" + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/ferry) "Qx" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/effect/turf_decal/siding/yellow{ @@ -9234,6 +9811,9 @@ /turf/open/floor/iron/dark, /area/centcom/tdome/administration) "QV" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, /turf/open/floor/iron/grimy, /area/centcom/central_command_areas/admin) "QX" = ( @@ -9243,16 +9823,19 @@ /turf/open/floor/iron/dark, /area/centcom/central_command_areas/courtroom) "QY" = ( -/obj/item/storage/box/handcuffs, -/obj/item/ammo_box/speedloader/c357, /obj/item/ammo_box/speedloader/c357, +/obj/item/ammo_box/speedloader/c357{ + pixel_y = 6; + pixel_x = -5 + }, /obj/item/gun/ballistic/revolver/mateba, /obj/structure/table/reinforced, /obj/machinery/firealarm/directional/south, -/obj/effect/turf_decal/stripes/line{ +/obj/effect/turf_decal/siding/dark{ dir = 1 }, -/turf/open/floor/iron, +/obj/effect/turf_decal/tile/dark_red/half, +/turf/open/floor/iron/textured_edge, /area/centcom/central_command_areas/admin/storage) "Ra" = ( /obj/machinery/door/airlock/centcom{ @@ -9277,10 +9860,12 @@ /turf/open/floor/iron, /area/centcom/tdome/administration) "Rd" = ( -/obj/structure/bookcase/random, -/obj/effect/turf_decal/tile/neutral/fourcorners, /obj/structure/sign/nanotrasen/directional/north, -/turf/open/floor/iron/dark, +/obj/structure/table/wood, +/obj/machinery/fax/admin{ + pixel_y = 6 + }, +/turf/open/floor/carpet/green, /area/centcom/central_command_areas/briefing) "Rf" = ( /obj/item/kirbyplants/organic/plant22, @@ -9311,16 +9896,14 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, +/obj/effect/turf_decal/stripes/red/full, /obj/machinery/door/airlock/vault{ req_access = list("cent_captain") }, /obj/machinery/door/poddoor/shutters/indestructible{ id = "XCCadminstore" }, -/turf/open/floor/iron, +/turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin/storage) "Rk" = ( /obj/structure/cable, @@ -9328,10 +9911,10 @@ /turf/open/floor/catwalk_floor, /area/centcom/central_command_areas/evacuation/ship) "Rl" = ( -/obj/structure/chair/comfy/brown{ +/obj/structure/chair/sofa/left/brown{ dir = 4 }, -/turf/open/floor/iron/grimy, +/turf/open/floor/carpet/executive, /area/centcom/central_command_areas/admin) "Rm" = ( /obj/structure/filingcabinet/white, @@ -9343,14 +9926,24 @@ /area/centcom/central_command_areas/supply) "Rn" = ( /obj/structure/table/wood, -/obj/item/clipboard, -/obj/item/folder/blue, -/obj/item/melee/chainofcommand, -/obj/item/stamp/head/captain, +/obj/item/clipboard{ + pixel_y = 1 + }, +/obj/item/folder/blue{ + pixel_y = 1 + }, +/obj/item/melee/chainofcommand{ + pixel_y = 5 + }, +/obj/item/stamp/head/captain{ + pixel_y = 4 + }, /obj/machinery/newscaster{ pixel_y = 32 }, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/tile/green/half/contrasted{ + dir = 1 + }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin) "Ro" = ( @@ -9423,12 +10016,24 @@ /turf/open/floor/iron, /area/centcom/tdome/administration) "RF" = ( -/obj/structure/table/reinforced, -/obj/item/crowbar/red, -/obj/item/tank/internals/emergency_oxygen/engi, -/obj/item/clothing/mask/gas, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/structure/table/reinforced/plastitaniumglass, +/obj/effect/turf_decal/tile/green/full, +/obj/item/tank/internals/emergency_oxygen/engi{ + pixel_x = -7; + pixel_y = 4 + }, +/obj/item/tank/internals/emergency_oxygen/engi{ + pixel_y = 4; + pixel_x = -13 + }, +/obj/machinery/cell_charger{ + pixel_x = 5; + pixel_y = 4 + }, +/obj/item/stock_parts/power_store/cell/hyper{ + pixel_x = 15 + }, +/turf/open/floor/iron/dark/smooth_large, /area/centcom/central_command_areas/briefing) "RG" = ( /obj/structure/chair/comfy/black{ @@ -9440,7 +10045,9 @@ /turf/open/floor/iron/dark, /area/centcom/central_command_areas/courtroom) "RH" = ( -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/tile/neutral/half/contrasted{ + dir = 1 + }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) "RI" = ( @@ -9459,7 +10066,6 @@ "RM" = ( /obj/machinery/power/apc/auto_name/directional/east, /obj/structure/cable, -/obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/armory) "RP" = ( @@ -9482,17 +10088,21 @@ "RT" = ( /obj/machinery/airalarm/directional/east, /obj/structure/filingcabinet/white, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/structure/sign/poster/official/here_for_your_safety/directional/north, +/turf/open/floor/iron/dark/textured_large, /area/centcom/central_command_areas/ferry) "RV" = ( /obj/structure/table/reinforced, -/obj/item/restraints/handcuffs, -/obj/item/radio, -/obj/effect/turf_decal/stripes/line{ - dir = 9 +/obj/item/radio{ + pixel_y = 11; + pixel_x = -7 }, -/turf/open/floor/iron, +/obj/item/radio{ + pixel_y = 10; + pixel_x = 4 + }, +/obj/item/restraints/handcuffs, +/turf/open/floor/iron/textured_large, /area/centcom/central_command_areas/armory) "RW" = ( /obj/structure/table/reinforced, @@ -9528,13 +10138,22 @@ "Sh" = ( /obj/structure/table/reinforced, /obj/item/mod/control/pre_equipped/corporate{ - pixel_y = 5 + pixel_y = 5; + pixel_x = -7 }, /obj/item/clothing/gloves/combat, /obj/item/clothing/shoes/combat/swat, -/obj/item/clothing/mask/gas/sechailer/swat, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/iron, +/obj/item/clothing/mask/gas/sechailer/swat{ + pixel_y = 10; + pixel_x = 10 + }, +/obj/effect/turf_decal/siding/dark, +/obj/effect/turf_decal/tile/dark_red/half{ + dir = 1 + }, +/turf/open/floor/iron/textured_edge{ + dir = 1 + }, /area/centcom/central_command_areas/admin/storage) "Si" = ( /turf/open/floor/iron, @@ -9550,10 +10169,17 @@ /turf/open/floor/iron, /area/centcom/central_command_areas/evacuation) "Sk" = ( -/obj/structure/table/reinforced, -/obj/item/storage/medkit/regular, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/structure/table/reinforced/plastitaniumglass, +/obj/effect/turf_decal/tile/green/full, +/obj/item/restraints/handcuffs/cable/zipties{ + pixel_x = -6; + pixel_y = 6 + }, +/obj/item/storage/box/zipties{ + pixel_y = 8; + pixel_x = 5 + }, +/turf/open/floor/iron/dark/smooth_large, /area/centcom/central_command_areas/briefing) "Sl" = ( /obj/effect/spawner/structure/window/reinforced, @@ -9575,14 +10201,15 @@ /obj/structure/table/reinforced, /obj/item/clipboard, /obj/item/folder/yellow, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/iron, +/turf/open/floor/iron/textured_large, /area/centcom/central_command_areas/armory) "Su" = ( /turf/open/floor/iron, /area/centcom/central_command_areas/supplypod) +"Sv" = ( +/obj/effect/turf_decal/tile/neutral, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/briefing) "Sx" = ( /obj/structure/chair{ dir = 1 @@ -9668,7 +10295,11 @@ "SP" = ( /obj/item/kirbyplants/organic/plant21, /obj/machinery/status_display/evac/directional/north, -/turf/open/floor/wood, +/obj/machinery/light/directional/north, +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "SQ" = ( /obj/structure/filingcabinet/medical, @@ -9676,6 +10307,9 @@ /turf/open/floor/iron/dark, /area/centcom/central_command_areas/control) "SR" = ( +/obj/effect/turf_decal/siding/dark/end{ + dir = 4 + }, /turf/open/floor/circuit/green, /area/centcom/central_command_areas/briefing) "SS" = ( @@ -9685,11 +10319,16 @@ /turf/open/floor/iron, /area/centcom/central_command_areas/supplypod/loading/one) "ST" = ( +/obj/effect/turf_decal/trimline/dark_red/filled/warning{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/dark_red/filled/warning{ + dir = 4 + }, /obj/machinery/door/poddoor/ert{ id = "XCCertstore" }, -/obj/effect/turf_decal/delivery, -/turf/open/floor/iron, +/turf/open/floor/iron/dark, /area/centcom/central_command_areas/armory) "SX" = ( /obj/machinery/computer/shuttle, @@ -9721,14 +10360,11 @@ /turf/open/floor/iron/smooth_edge, /area/centcom/central_command_areas/evacuation/ship) "Tg" = ( -/obj/item/storage/briefcase{ - pixel_x = -3; - pixel_y = 3 - }, -/obj/item/storage/briefcase/secure, /obj/structure/table/wood, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/machinery/chem_dispenser/drinks/beer/fullupgrade{ + dir = 4 + }, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "Th" = ( /obj/structure/filingcabinet/white, @@ -9768,7 +10404,7 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ dir = 4 }, -/turf/open/floor/iron/grimy, +/turf/open/floor/carpet/green, /area/centcom/central_command_areas/admin) "Tp" = ( /obj/structure/table/reinforced, @@ -9834,11 +10470,10 @@ /turf/open/floor/iron/dark, /area/centcom/tdome/observation) "TE" = ( -/obj/structure/chair/comfy/brown{ - color = "#596479"; +/obj/structure/chair/comfy/black{ dir = 4 }, -/turf/open/floor/iron/grimy, +/turf/open/floor/carpet/green, /area/centcom/central_command_areas/briefing) "TG" = ( /obj/item/kirbyplants/organic/plant21, @@ -9847,11 +10482,25 @@ /turf/open/floor/iron/dark, /area/centcom/central_command_areas/evacuation) "TI" = ( -/obj/structure/table/reinforced, -/obj/item/paper_bin, -/obj/item/pen, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/structure/table/reinforced/plastitaniumglass, +/obj/effect/turf_decal/tile/green/full, +/obj/item/paper_bin{ + pixel_x = -7; + pixel_y = 4 + }, +/obj/item/pen{ + pixel_x = -7; + pixel_y = 4 + }, +/obj/item/clipboard{ + pixel_x = 7; + pixel_y = 5 + }, +/obj/item/paper{ + pixel_x = 7; + pixel_y = 5 + }, +/turf/open/floor/iron/dark/smooth_large, /area/centcom/central_command_areas/briefing) "TJ" = ( /turf/cordon, @@ -9870,16 +10519,19 @@ /area/centcom/tdome/arena) "TS" = ( /obj/structure/table/wood, -/obj/item/dice/d20{ - pixel_x = 3; - pixel_y = 3 - }, -/obj/item/dice/d10{ - pixel_x = -3 - }, /obj/machinery/computer/security/telescreen/entertainment/directional/south, /obj/machinery/firealarm/directional/east, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/siding/dark{ + dir = 1 + }, +/obj/item/book/manual/wiki/security_space_law{ + pixel_x = 6; + pixel_y = 1 + }, +/obj/item/book/manual/wiki/tgc{ + pixel_y = 1; + pixel_x = -6 + }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin) "TT" = ( @@ -9915,13 +10567,24 @@ }, /turf/open/floor/iron/white, /area/centcom/central_command_areas/admin) +"TX" = ( +/obj/structure/cable, +/obj/effect/turf_decal/siding/dark{ + dir = 1 + }, +/obj/effect/turf_decal/siding/dark/corner, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/armory) "Ub" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/visible{ dir = 1 }, /obj/machinery/meter, /obj/structure/cable, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/trimline/dark_red/filled/warning, +/obj/effect/turf_decal/trimline/dark_red/filled/warning{ + dir = 1 + }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin/storage) "Ud" = ( @@ -9940,7 +10603,10 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ dir = 8 }, -/turf/open/floor/wood, +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "Ui" = ( /obj/structure/table/wood, @@ -9950,7 +10616,9 @@ pixel_y = 24 }, /obj/machinery/status_display/ai/directional/east, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/tile/green/anticorner/contrasted{ + dir = 4 + }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin) "Ul" = ( @@ -9979,24 +10647,8 @@ /turf/open/floor/iron, /area/centcom/tdome/arena) "Ur" = ( -/obj/structure/closet/secure_closet/personal/cabinet, -/obj/item/clothing/under/rank/civilian/curator/treasure_hunter, -/obj/item/clothing/under/dress/skirt, -/obj/item/clothing/under/shorts/black, -/obj/item/clothing/under/pants/track, -/obj/item/clothing/accessory/armband/deputy, -/obj/item/clothing/accessory/waistcoat, -/obj/item/clothing/shoes/jackboots, -/obj/item/clothing/shoes/laceup, -/obj/item/clothing/neck/large_scarf/red, -/obj/item/clothing/neck/tie/red, -/obj/item/clothing/head/helmet/space/beret, -/obj/item/clothing/suit/jacket/curator, -/obj/item/clothing/suit/space/officer, -/obj/item/clothing/gloves/fingerless, -/obj/item/clothing/gloves/color/black, -/obj/item/clothing/glasses/eyepatch, /obj/machinery/firealarm/directional/west, +/obj/effect/turf_decal/siding/wood, /turf/open/floor/iron/grimy, /area/centcom/central_command_areas/admin) "Us" = ( @@ -10023,7 +10675,7 @@ /turf/open/floor/iron/dark, /area/centcom/central_command_areas/supplypod) "Ux" = ( -/turf/open/indestructible/dark, +/turf/open/floor/circuit, /area/centcom/central_command_areas/admin) "Uz" = ( /obj/effect/turf_decal/stripes/line{ @@ -10051,26 +10703,25 @@ /turf/open/floor/iron/dark, /area/centcom/central_command_areas/supplypod) "UI" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/components/tank/air{ dir = 1 }, /obj/machinery/firealarm/directional/south, /obj/structure/sign/warning/secure_area/directional/east, -/turf/open/floor/iron, +/obj/effect/turf_decal/siding/dark{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow/half, +/turf/open/floor/iron/textured_edge, /area/centcom/central_command_areas/admin/storage) "UK" = ( /obj/structure/closet/secure_closet/ert_med, /obj/machinery/wall_healer/directional/south{ use_power = 0 }, -/obj/effect/turf_decal/stripes/line{ - dir = 5 - }, -/turf/open/floor/iron, +/obj/effect/turf_decal/tile/blue/half, +/turf/open/floor/iron/textured_half, /area/centcom/central_command_areas/armory) "UM" = ( /obj/effect/turf_decal/tile/brown/half/contrasted{ @@ -10092,12 +10743,37 @@ /turf/open/floor/iron, /area/centcom/central_command_areas/control) "UR" = ( -/obj/structure/table/wood, -/obj/item/flashlight/lamp, /obj/machinery/status_display/evac/directional/south, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/structure/closet/secure_closet/personal/cabinet, +/obj/item/clothing/neck/large_scarf/red, +/obj/item/clothing/neck/tie/red, +/obj/item/clothing/suit/space/officer, +/obj/item/clothing/gloves/color/black, +/obj/item/clothing/glasses/eyepatch, +/obj/item/clothing/gloves/fingerless, +/obj/item/clothing/suit/jacket/curator, +/obj/item/clothing/head/helmet/space/beret, +/obj/item/clothing/shoes/jackboots, +/obj/item/clothing/shoes/laceup, +/obj/item/clothing/accessory/armband/deputy, +/obj/item/clothing/accessory/waistcoat, +/obj/item/clothing/under/dress/skirt, +/obj/item/clothing/under/pants/track, +/obj/item/clothing/under/shorts/black, +/obj/item/clothing/under/rank/civilian/curator/treasure_hunter, +/obj/effect/turf_decal/tile/green/half/contrasted, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin) +"US" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/turf/open/floor/wood/tile, +/area/centcom/central_command_areas/admin) "UU" = ( /obj/structure/sign/flag/nanotrasen/directional/east, /obj/effect/turf_decal/siding/dark{ @@ -10158,10 +10834,10 @@ pixel_y = 3 }, /obj/item/gun/energy/e_gun, -/obj/effect/turf_decal/stripes/line{ - dir = 10 +/obj/effect/turf_decal/tile/dark_blue/half{ + dir = 1 }, -/turf/open/floor/iron, +/turf/open/floor/iron/textured_half, /area/centcom/central_command_areas/armory) "Vh" = ( /obj/structure/table/reinforced, @@ -10286,25 +10962,38 @@ /turf/open/floor/iron, /area/centcom/tdome/observation) "VK" = ( -/obj/structure/table/wood, -/obj/item/storage/fancy/donut_box, -/turf/open/floor/iron/grimy, +/obj/structure/table/glass, +/obj/item/storage/briefcase{ + pixel_x = -4; + pixel_y = 8 + }, +/obj/item/stack/spacecash/c1000{ + pixel_x = 1 + }, +/obj/item/stack/spacecash/c100{ + pixel_x = 4; + pixel_y = 2 + }, +/turf/open/floor/carpet/executive, /area/centcom/central_command_areas/admin) "VM" = ( /obj/structure/closet/secure_closet/ert_sec, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /obj/machinery/status_display/evac/directional/east, -/turf/open/floor/iron, +/obj/effect/turf_decal/tile/dark_red/half, +/turf/open/floor/iron/textured_half, /area/centcom/central_command_areas/armory) "VO" = ( +/obj/structure/cable, +/obj/effect/turf_decal/trimline/dark_red/filled/warning{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/dark_red/filled/warning{ + dir = 4 + }, /obj/machinery/door/poddoor/ert{ id = "XCCertstore" }, -/obj/effect/turf_decal/delivery, -/obj/structure/cable, -/turf/open/floor/iron, +/turf/open/floor/iron/dark, /area/centcom/central_command_areas/armory) "VP" = ( /obj/effect/turf_decal/tile/brown/anticorner/contrasted, @@ -10330,22 +11019,17 @@ /area/centcom/central_command_areas/evacuation) "VZ" = ( /obj/structure/closet/secure_closet/ert_med, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/iron, +/obj/effect/turf_decal/tile/blue/half, +/turf/open/floor/iron/textured_half, /area/centcom/central_command_areas/armory) "Wa" = ( -/obj/item/kirbyplants/organic/plant22, /obj/structure/noticeboard/directional/south, -/obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) "Wb" = ( -/obj/effect/turf_decal/tile/green{ - dir = 8 - }, /obj/structure/sign/warning/secure_area/directional/south, +/obj/machinery/light/directional/south, +/obj/effect/turf_decal/trimline/green/arrow_cw, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "Wc" = ( @@ -10363,11 +11047,14 @@ /area/centcom/central_command_areas/evacuation) "Wd" = ( /obj/structure/table/reinforced, -/obj/item/gun/ballistic/automatic/wt550, -/obj/item/flashlight/seclite, +/obj/item/gun/ballistic/automatic/wt550{ + pixel_y = 9 + }, +/obj/item/flashlight/seclite{ + pixel_x = 1 + }, /obj/structure/noticeboard/directional/north, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/iron, +/turf/open/floor/iron/textured_large, /area/centcom/central_command_areas/armory) "Wf" = ( /obj/structure/sink/directional/west, @@ -10376,9 +11063,19 @@ /area/centcom/tdome/observation) "Wl" = ( /obj/structure/table/wood, -/obj/machinery/recharger, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/item/storage/box/drinkingglasses{ + pixel_y = 8; + pixel_x = -6 + }, +/obj/item/reagent_containers/cup/glass/drinkingglass{ + pixel_x = 7; + pixel_y = 4 + }, +/obj/item/reagent_containers/cup/glass/drinkingglass{ + pixel_x = 8; + pixel_y = 12 + }, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "Wn" = ( /obj/effect/spawner/structure/window/reinforced, @@ -10413,6 +11110,7 @@ /turf/open/floor/iron/dark, /area/centcom/tdome/observation) "Wy" = ( +/obj/effect/turf_decal/tile/neutral/half/contrasted, /obj/structure/chair/office, /obj/effect/landmark/ert_spawn, /turf/open/floor/iron/dark, @@ -10439,8 +11137,10 @@ /area/centcom/central_command_areas/evacuation) "WG" = ( /obj/structure/closet/secure_closet/ert_engi, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/iron, +/obj/effect/turf_decal/tile/yellow/half{ + dir = 1 + }, +/turf/open/floor/iron/textured_half, /area/centcom/central_command_areas/armory) "WK" = ( /obj/structure/chair, @@ -10462,33 +11162,45 @@ /turf/closed/indestructible/riveted, /area/centcom/central_command_areas/ferry) "WN" = ( -/obj/structure/table/wood, -/obj/item/storage/box/drinkingglasses, -/obj/item/reagent_containers/cup/glass/bottle/whiskey{ - pixel_y = 5 - }, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/structure/filingcabinet/medical, +/turf/open/floor/carpet/green, /area/centcom/central_command_areas/briefing) "WO" = ( -/obj/structure/table/wood, -/obj/item/phone{ - desc = "Supposedly a direct line to Nanotrasen Central Command. It's not even plugged in."; - pixel_x = -3; - pixel_y = 3 +/obj/machinery/photocopier/gratis/prebuilt, +/obj/machinery/button/door/directional/north{ + pixel_x = 6; + id = "QuickAccess"; + name = "Quick Access Lock Control"; + normaldoorcontrol = 1; + specialfunctions = 4; + req_access = list("cent_general") }, -/obj/item/cigarette/cigar/cohiba{ - pixel_x = 6 +/obj/machinery/button/door/directional/north{ + pixel_x = 6; + id = "HallwayLock"; + name = "Hallway Doors Lock Control"; + normaldoorcontrol = 1; + specialfunctions = 4; + req_access = list("cent_general"); + pixel_y = 36 }, -/obj/item/cigarette/cigar/havana{ - pixel_x = 2 +/obj/machinery/button/door/directional/north{ + pixel_x = -6; + id = "PodLock"; + name = "Pod Loading Lock Control"; + normaldoorcontrol = 1; + specialfunctions = 4; + pixel_y = 24; + req_access = list("cent_general") }, -/obj/item/cigarette/cigar{ - pixel_x = 4.5 +/obj/machinery/button/door/directional/north{ + pixel_x = -6; + id = "CCFerry"; + name = "Ferry Hangar Shutters"; + pixel_y = 36; + req_access = list("cent_general") }, -/obj/machinery/newscaster/directional/north, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/turf/open/floor/carpet/green, /area/centcom/central_command_areas/briefing) "WP" = ( /obj/machinery/computer/station_alert{ @@ -10503,14 +11215,13 @@ /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) "WU" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, +/obj/structure/cable, +/obj/effect/mapping_helpers/airlock/access/all/admin/officer, /obj/machinery/door/airlock/centcom{ name = "Administrative Office" }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, -/obj/effect/turf_decal/stripes/line, -/obj/structure/cable, -/obj/effect/mapping_helpers/airlock/access/all/admin/officer, -/turf/open/floor/iron, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "WX" = ( /obj/machinery/light_switch/directional/west, @@ -10523,8 +11234,7 @@ /obj/item/wrench, /obj/item/clothing/mask/gas, /obj/machinery/status_display/evac/directional/north, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/turf/open/floor/iron/dark/textured_large, /area/centcom/central_command_areas/ferry) "Xa" = ( /obj/structure/table/reinforced, @@ -10601,7 +11311,7 @@ "Xo" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, /obj/structure/cable, -/turf/open/floor/wood, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "Xp" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -10609,7 +11319,10 @@ /turf/open/floor/iron/dark, /area/centcom/central_command_areas/evacuation/ship) "Xq" = ( -/turf/open/floor/wood, +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "Xs" = ( /obj/effect/turf_decal/tile/brown/anticorner/contrasted, @@ -10636,23 +11349,26 @@ /turf/open/floor/iron/grimy, /area/centcom/tdome/administration) "Xy" = ( -/obj/machinery/door/airlock/external/ruin{ - name = "Ferry Airlock" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 8 }, /obj/effect/mapping_helpers/airlock/access/all/admin/general, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/door/airlock/external/ruin{ + name = "Ferry Airlock" + }, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "Xz" = ( /obj/machinery/atmospherics/components/unary/vent_pump{ dir = 4 }, -/turf/open/floor/wood, +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "XC" = ( /obj/machinery/vending/snack, @@ -10694,13 +11410,13 @@ /turf/open/floor/iron/dark, /area/centcom/central_command_areas/supply) "XL" = ( -/obj/structure/chair/comfy/brown{ - dir = 8 - }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ dir = 6 }, -/turf/open/floor/iron/grimy, +/obj/structure/chair/comfy/black{ + dir = 8 + }, +/turf/open/floor/carpet/green, /area/centcom/central_command_areas/admin) "XQ" = ( /obj/machinery/computer/crew{ @@ -10714,13 +11430,28 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/centcom/central_command_areas/supplypod) +"XU" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/decal/cleanable/garbage, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/admin) "Ya" = ( /turf/closed/indestructible/riveted, /area/centcom/central_command_areas/armory) +"Yb" = ( +/obj/structure/cable, +/obj/effect/turf_decal/siding/dark{ + dir = 8 + }, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/armory) "Yc" = ( /obj/structure/fireplace, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/effect/turf_decal/siding/wood, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "Ye" = ( /obj/structure/closet/crate/bin, @@ -10741,9 +11472,9 @@ /turf/open/floor/iron/dark/herringbone, /area/centcom/central_command_areas/evacuation/ship) "Yj" = ( -/obj/structure/chair/comfy/black, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, /obj/structure/cable, +/obj/structure/chair/sofa/left/brown, /turf/open/floor/iron/grimy, /area/centcom/central_command_areas/admin) "Yk" = ( @@ -10767,13 +11498,27 @@ dir = 4 }, /obj/structure/cable, -/turf/open/floor/wood, +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/turf/open/floor/wood/tile, /area/centcom/central_command_areas/admin) "Yr" = ( /obj/structure/table/wood, -/obj/machinery/computer/security/wooden_tv, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, -/turf/open/floor/iron/grimy, +/obj/machinery/recharger{ + pixel_y = 3; + pixel_x = -10 + }, +/obj/item/camera{ + pixel_x = 4; + pixel_y = 9 + }, +/obj/item/storage/photo_album{ + pixel_x = 3; + pixel_y = -5 + }, +/turf/open/floor/carpet/green, /area/centcom/central_command_areas/admin) "Yt" = ( /obj/structure/sign/directions/security{ @@ -10785,12 +11530,16 @@ /turf/open/floor/iron/white/herringbone, /area/centcom/central_command_areas/evacuation/ship) "Yy" = ( -/obj/structure/table/reinforced, -/obj/item/clipboard, -/obj/item/folder/yellow, -/obj/item/pen/blue, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/structure/table/reinforced/plastitaniumglass, +/obj/effect/turf_decal/tile/green/full, +/obj/item/storage/toolbox/emergency{ + pixel_x = 5; + pixel_y = 10 + }, +/obj/item/flashlight/flare{ + pixel_y = 1 + }, +/turf/open/floor/iron/dark/smooth_large, /area/centcom/central_command_areas/briefing) "YA" = ( /obj/machinery/door/airlock/centcom{ @@ -10853,6 +11602,9 @@ pixel_x = 5; pixel_y = 5 }, +/obj/item/toy/cards/deck{ + pixel_y = 8 + }, /turf/open/floor/iron/grimy, /area/centcom/central_command_areas/admin) "YT" = ( @@ -10883,6 +11635,9 @@ "YX" = ( /obj/machinery/light/small/directional/east, /obj/structure/sign/warning/secure_area/directional/east, +/obj/effect/turf_decal/trimline/dark_red/corner{ + dir = 4 + }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) "YY" = ( @@ -10956,12 +11711,13 @@ /turf/open/floor/iron, /area/centcom/tdome/arena) "Zl" = ( -/obj/structure/table/reinforced, -/obj/item/clipboard, -/obj/item/folder/red, -/obj/item/pen/red, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/obj/structure/table/reinforced/plastitaniumglass, +/obj/effect/turf_decal/tile/green/full, +/obj/item/storage/fancy/donut_box{ + pixel_y = 17 + }, +/obj/machinery/recharger, +/turf/open/floor/iron/dark/smooth_large, /area/centcom/central_command_areas/briefing) "Zm" = ( /obj/structure/sink/directional/east, @@ -10971,22 +11727,51 @@ }, /turf/open/floor/iron/white, /area/centcom/tdome/observation) +"Zn" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/obj/structure/table/wood, +/obj/item/paper_bin{ + pixel_x = 5; + pixel_y = 4 + }, +/obj/item/pen/fourcolor{ + pixel_x = 5; + pixel_y = 4 + }, +/obj/item/taperecorder{ + pixel_y = 4; + pixel_x = -6 + }, +/obj/structure/window/reinforced/spawner/directional/east, +/turf/open/floor/carpet/green, +/area/centcom/central_command_areas/briefing) "Zq" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/white/herringbone, /area/centcom/central_command_areas/evacuation/ship) "Zs" = ( /obj/machinery/shuttle_manipulator, +/obj/effect/turf_decal/siding/dark/end{ + dir = 8 + }, /turf/open/floor/circuit/green, /area/centcom/central_command_areas/briefing) "Zv" = ( /obj/machinery/light/directional/west, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/trimline/dark_red/corner{ + dir = 1 + }, +/obj/effect/turf_decal/siding/dark, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/armory) "Zw" = ( /obj/structure/table/wood, -/obj/item/flashlight/lamp, +/obj/item/flashlight/lamp{ + pixel_y = 5; + pixel_x = -5 + }, /obj/machinery/requests_console/directional/north{ department = "Captain's Desk"; name = "CentCom Requests Console" @@ -10994,7 +11779,7 @@ /obj/effect/mapping_helpers/requests_console/announcement, /obj/effect/mapping_helpers/requests_console/information, /obj/effect/mapping_helpers/requests_console/assistance, -/turf/open/floor/iron/grimy, +/turf/open/floor/carpet/green, /area/centcom/central_command_areas/admin) "Zx" = ( /obj/machinery/computer/records/security{ @@ -11045,7 +11830,7 @@ pixel_x = 32 }, /obj/machinery/status_display/ai/directional/south, -/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/tile/green/anticorner/contrasted, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin) "ZG" = ( @@ -11075,16 +11860,23 @@ /turf/open/floor/iron, /area/centcom/tdome/observation) "ZN" = ( -/obj/item/clipboard, -/obj/item/folder/red, -/obj/item/stamp/denied{ - pixel_x = 3; +/obj/item/clipboard{ + pixel_x = -4; pixel_y = 3 }, -/obj/item/stamp/granted, +/obj/item/folder/red{ + pixel_x = -4; + pixel_y = 2 + }, +/obj/item/stamp/denied{ + pixel_x = 9; + pixel_y = 3 + }, +/obj/item/stamp/granted{ + pixel_x = 5 + }, /obj/structure/table/reinforced, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, +/turf/open/floor/iron/dark/textured_large, /area/centcom/central_command_areas/ferry) "ZO" = ( /obj/structure/flora/bush/lavendergrass/style_random, @@ -46252,9 +47044,9 @@ oe YG mD oe -oe +mB td -oe +nR oe mD aa @@ -46498,14 +47290,14 @@ aa aa mD WY -su -ts +ss +tr By mD vC -wr +fw xe -wr +fw wx mD pB @@ -46755,20 +47547,20 @@ aa aa oe bW -su -ts +ss +cG pR uO -vD +hV fw -xf +xe fw yp sd ap pU pU -ms +pU qG oe aa @@ -47017,7 +47809,7 @@ tt PH mD vE -wt +je xg wt tn @@ -47274,16 +48066,16 @@ tu mD mD mD -ds +Qw xh -ds +ht mD gO cn -cn +ib gO -cn -cn +ib +CC gO gO aa @@ -47526,13 +48318,13 @@ Zf Zf On fu -Hz -Hz +ES +Lg Hz aK mD -tA wv +jZ wv mD yL @@ -47783,21 +48575,21 @@ Wl Qb On au -Hz +XU dx -Hz +HN dd mD -Kv +Kb xh Kv mD WO +id +id +id eF -eF -eF -eF -eF +WR db gO aa @@ -48034,9 +48826,9 @@ aa aa On AF -Xq +Fc Xz -Xq +uv cw On On @@ -48050,11 +48842,11 @@ Fh wz mD Rd -eF -hx +id +id TE az -eF +WR Ge gO aa @@ -48293,7 +49085,7 @@ On eA Rl Br -Xq +te cB On vv @@ -48302,16 +49094,16 @@ gm wq eB mD -ss -xj +ww +fw fa mD PU -eF +Zn nz yR eV -eF +WR xU gO aa @@ -48559,16 +49351,16 @@ YQ uh oh mD -ss +ww fw Wb mD kO -WR -RH -WR +Sv he -WR +he +he +CQ ty gO aa @@ -48816,12 +49608,12 @@ Xq Xq bO mD -wx +rd fw wB yr -RH -RH +fo +JG JW eE rB @@ -49061,9 +49853,9 @@ On ry TW fG -nA -MU -MU +Bn +US +US MU NM On @@ -49076,8 +49868,8 @@ vF wy TK vm -mD -RH +oe +vT Wy Sk Zs @@ -49321,25 +50113,25 @@ On Zw df hd -To +Mt BT On uP dz Nr -Xq +te Hw mD Cp -TK +xR xR OQ -Ny +Hq PM Om SR Yy -AL +OX oK gO aa @@ -49578,21 +50370,21 @@ On ks XL Yr -CV +Nc nA eD CV Vp OY -tl +te fN -mD -su +hu +hV fw wh mD -Fz -MJ +WR +PM TI Zl zz @@ -49844,14 +50636,14 @@ Em hT TS mD -su +fS fw bm mD -kO -Ny +HC +gW +ar ar -fi ar Ny Eb @@ -50107,9 +50899,9 @@ iH mD Mp Pd -RH +kw NC -RH +kw YX dW gO @@ -50347,7 +51139,7 @@ iF iF On lj -To +lX WX Ur UR @@ -50605,7 +51397,7 @@ pd On Rn EJ -QV +Et QV Mo YU @@ -50617,13 +51409,13 @@ uZ oe su fw -ts +pC WM WG OK -sE +Il bH -sE +Il Zv VZ RQ @@ -50873,14 +51665,14 @@ YU uY oe su -xf +fw ts mD cm -bH -bH -bH -sE +TX +IN +IN +gF sE UK Ya @@ -51134,11 +51926,11 @@ fw Hi mD Wd -bH +qx RV Sq gX -sE +cC yS Ya aa @@ -51391,11 +52183,11 @@ fw ts mD gw -bH +qx bA bj Pt -sE +cC FB Ya aa @@ -51644,15 +52436,15 @@ YU vb oe su -xk -iH +fw +ad mD Vg -bH -bH -bH -sE -sE +sG +Yb +Yb +hE +mU IK Ya aa @@ -51900,7 +52692,7 @@ cA YU va oe -wB +dR Fh xS ub @@ -51908,7 +52700,7 @@ wg oL fj RM -sE +OG gS VM Yt diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm index 83e6aa28238..c6ce0ecfef4 100644 --- a/_maps/map_files/tramstation/tramstation.dmm +++ b/_maps/map_files/tramstation/tramstation.dmm @@ -1118,22 +1118,6 @@ }, /turf/open/floor/iron, /area/station/security/courtroom) -"adD" = ( -/mob/living/simple_animal/bot/secbot/beepsky/officer, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/trimline/neutral/filled/line, -/obj/machinery/camera/directional/south{ - c_tag = "Maintenance - East Tram Tunnel 4" - }, -/obj/effect/turf_decal/bot_red, -/obj/effect/turf_decal/siding/thinplating{ - dir = 1 - }, -/obj/effect/turf_decal/trimline/white/warning{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/maintenance/tram/right) "adE" = ( /obj/structure/table, /obj/item/assembly/igniter{ @@ -1525,12 +1509,6 @@ }, /turf/open/misc/asteroid/airless, /area/station/asteroid) -"aeX" = ( -/mob/living/simple_animal/bot/secbot/beepsky/armsky, -/obj/effect/turf_decal/stripes/line, -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/security/armory) "aeY" = ( /obj/effect/turf_decal/trimline/white/warning{ dir = 9 @@ -2335,12 +2313,6 @@ /obj/effect/turf_decal/trimline/white/filled/line, /turf/open/floor/iron/dark, /area/station/engineering/storage/tech) -"ajn" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/decal/cleanable/dirt, -/obj/structure/railing, -/turf/open/floor/iron, -/area/station/cargo/miningfoundry) "ajo" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/carpet, @@ -3150,6 +3122,12 @@ /obj/machinery/light/dim/directional/south, /turf/open/floor/wood, /area/station/service/lawoffice) +"asb" = ( +/obj/structure/sign/poster/official/jim_nortons/directional/north, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "asc" = ( /obj/effect/turf_decal/trimline/purple/filled/corner{ dir = 4 @@ -3574,14 +3552,6 @@ /obj/effect/turf_decal/trimline/red/filled/line, /turf/open/floor/iron, /area/station/security/brig) -"avZ" = ( -/obj/effect/turf_decal/trimline/blue/filled/line, -/obj/machinery/firealarm/directional/south, -/obj/structure/table/glass, -/obj/item/stack/medical/mesh, -/obj/item/stack/medical/wrap/gauze, -/turf/open/floor/iron/white, -/area/station/medical/medbay/central) "awc" = ( /obj/effect/turf_decal/trimline/red/filled/corner, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -6552,6 +6522,13 @@ }, /turf/open/misc/asteroid/snow/coldroom, /area/station/service/kitchen/coldroom) +"bjo" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "bjK" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 10 @@ -7505,22 +7482,6 @@ }, /turf/open/floor/iron, /area/station/commons/fitness/recreation) -"bDB" = ( -/obj/structure/table/glass, -/obj/item/storage/box/bodybags{ - pixel_x = -1; - pixel_y = 6 - }, -/obj/item/storage/box/disks{ - pixel_x = 1; - pixel_y = 5 - }, -/obj/item/storage/box/monkeycubes{ - pixel_x = -5 - }, -/obj/effect/turf_decal/tile/dark_green/fourcorners, -/turf/open/floor/iron/white, -/area/station/science/genetics) "bEo" = ( /obj/machinery/atmospherics/pipe/smart/simple/purple/visible{ dir = 9 @@ -7821,6 +7782,12 @@ }, /turf/open/floor/iron/dark, /area/station/service/chapel/office) +"bIT" = ( +/obj/machinery/digital_clock/directional/north, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "bJb" = ( /obj/effect/turf_decal/trimline/brown/filled/line{ dir = 1 @@ -7890,6 +7857,15 @@ }, /turf/open/floor/iron/dark, /area/station/service/bar) +"bKH" = ( +/obj/machinery/door/poddoor/shutters/preopen{ + dir = 8; + id = "genetics_shutters"; + name = "Genetics Shutters" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/station/science/genetics) "bKK" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -7988,20 +7964,6 @@ /obj/machinery/disposal/bin/tagger, /turf/open/floor/iron, /area/station/security/office) -"bLu" = ( -/obj/structure/table/glass, -/obj/effect/turf_decal/tile/blue/fourcorners, -/obj/machinery/light/cold/directional/south, -/obj/item/tgui_book/manual/dsm{ - pixel_x = -6; - pixel_y = 4 - }, -/obj/item/tgui_book/manual/idc{ - pixel_y = 3 - }, -/obj/item/storage/briefcase/secure, -/turf/open/floor/iron/white, -/area/station/command/heads_quarters/cmo) "bLA" = ( /obj/structure/table/wood, /obj/item/folder{ @@ -8597,6 +8559,24 @@ "bVW" = ( /turf/open/floor/iron/dark, /area/station/engineering/gravity_generator) +"bVY" = ( +/obj/structure/table/glass, +/obj/item/stack/medical/mesh, +/obj/item/stack/medical/wrap/gauze, +/obj/effect/turf_decal/stripes/corner{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/blue/filled/line{ + dir = 6 + }, +/obj/machinery/camera/directional/east{ + network = list("ss13","medbay"); + c_tag = "Medical - Treatment South-East" + }, +/obj/machinery/light/directional/east, +/obj/machinery/wall_healer/directional/south, +/turf/open/floor/iron/white, +/area/station/medical/treatment_center) "bWb" = ( /obj/machinery/suit_storage_unit/hos, /obj/machinery/keycard_auth/wall_mounted/directional/east, @@ -9028,24 +9008,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/medbay/central) -"caT" = ( -/obj/structure/table/glass, -/obj/item/stack/medical/mesh, -/obj/item/stack/medical/wrap/gauze, -/obj/effect/turf_decal/stripes/corner{ - dir = 8 - }, -/obj/effect/turf_decal/trimline/blue/filled/line{ - dir = 6 - }, -/obj/machinery/camera/directional/east{ - network = list("ss13","medbay"); - c_tag = "Medical - Treatment South-East" - }, -/obj/machinery/light/directional/east, -/obj/machinery/wall_healer/directional/south, -/turf/open/floor/iron/white, -/area/station/medical/treatment_center) "cbc" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/catwalk_floor, @@ -9118,6 +9080,23 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/hallway/secondary/construction/engineering) +"cbY" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Treatment Center" + }, +/obj/effect/turf_decal/trimline/blue/filled/line{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/blue/filled/line, +/obj/machinery/door/firedoor, +/obj/machinery/duct, +/obj/effect/mapping_helpers/airlock/access/all/medical/general, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/mapping_helpers/airlock/unres/delayed{ + dir = 4 + }, +/turf/open/floor/iron/white, +/area/station/medical/treatment_center) "cch" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/lattice/catwalk, @@ -9863,13 +9842,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/hallway/secondary/service) -"cqj" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/railing/corner/end{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/cargo/miningfoundry) "cqn" = ( /obj/structure/table, /obj/machinery/camera/directional/south{ @@ -11868,25 +11840,6 @@ }, /turf/open/floor/iron, /area/station/science/ordnance/storage) -"cXS" = ( -/obj/machinery/door/airlock/medical/glass{ - name = "Medbay"; - id_tag = "MedbayFoyer" - }, -/obj/effect/turf_decal/trimline/blue/filled/line{ - dir = 4 - }, -/obj/effect/turf_decal/trimline/blue/filled/line{ - dir = 8 - }, -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/access/all/medical/general, -/obj/structure/cable, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/mapping_helpers/airlock/unres/delayed, -/turf/open/floor/iron/white, -/area/station/medical/medbay/lobby) "cXX" = ( /obj/effect/turf_decal/trimline/brown/filled/line{ dir = 1 @@ -12010,12 +11963,6 @@ /obj/machinery/light/small/directional/south, /turf/open/floor/plating, /area/station/engineering/atmos) -"cZQ" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/miningfoundry) "cZT" = ( /obj/structure/alien/weeds, /obj/item/clothing/mask/facehugger/dead, @@ -12208,22 +12155,6 @@ /obj/effect/landmark/transport/nav_beacon/tram/nav/immovable_rod, /turf/open/floor/carpet, /area/station/hallway/secondary/entry) -"dcY" = ( -/obj/machinery/door/airlock/medical/glass{ - name = "Treatment Center" - }, -/obj/effect/turf_decal/trimline/blue/filled/line{ - dir = 4 - }, -/obj/effect/turf_decal/trimline/blue/filled/line{ - dir = 8 - }, -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/access/all/medical/general, -/obj/structure/cable, -/obj/effect/mapping_helpers/airlock/unres/delayed, -/turf/open/floor/iron/white, -/area/station/medical/treatment_center) "ddf" = ( /obj/effect/landmark/start/cook, /turf/open/floor/iron/white/side{ @@ -12243,6 +12174,13 @@ "ddn" = ( /turf/open/floor/iron/dark, /area/station/medical/morgue) +"dds" = ( +/obj/effect/spawner/random/entertainment/slot_machine{ + pixel_y = 2 + }, +/obj/machinery/light/cold/directional/north, +/turf/open/floor/iron/dark, +/area/station/commons/lounge) "ddB" = ( /obj/effect/turf_decal/trimline/neutral/filled/corner{ dir = 1 @@ -12274,14 +12212,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/security/prison/safe) -"ddY" = ( -/obj/structure/sign/poster/official/jim_nortons/directional/north, -/obj/machinery/conveyor{ - dir = 8; - id = "mining" - }, -/turf/open/floor/iron, -/area/station/cargo/miningfoundry) "dec" = ( /obj/structure/lattice/catwalk, /obj/structure/cable, @@ -12525,6 +12455,12 @@ /obj/structure/cable, /turf/open/floor/iron/dark, /area/station/ai/satellite/foyer) +"diN" = ( +/obj/effect/spawner/random/entertainment/slot_machine{ + pixel_y = 2 + }, +/turf/open/floor/iron/dark, +/area/station/commons/lounge) "diW" = ( /obj/machinery/door/airlock/external{ name = "Solar Maintenance" @@ -12899,10 +12835,6 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/iron/dark, /area/station/science/explab) -"dpB" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/station/science/genetics) "dpC" = ( /obj/effect/turf_decal/trimline/purple/filled/line{ dir = 1 @@ -13883,6 +13815,14 @@ }, /turf/open/floor/iron/white, /area/station/science/xenobiology) +"dHd" = ( +/obj/structure/closet/crate, +/obj/item/stack/ducts{ + amount = 5 + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "dHr" = ( /obj/effect/turf_decal/trimline/yellow/filled/corner, /obj/effect/turf_decal/trimline/yellow/filled/corner{ @@ -14507,6 +14447,14 @@ /obj/structure/holosign/barrier/atmos/tram, /turf/open/floor/tram, /area/station/hallway/primary/tram/left) +"dRM" = ( +/obj/effect/turf_decal/trimline/blue/filled/line, +/obj/machinery/firealarm/directional/south, +/obj/structure/table/glass, +/obj/item/stack/medical/mesh, +/obj/item/stack/medical/wrap/gauze, +/turf/open/floor/iron/white, +/area/station/medical/medbay/central) "dRY" = ( /obj/machinery/firealarm/directional/south, /obj/effect/turf_decal/trimline/brown/line, @@ -14644,6 +14592,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/white, /area/station/medical/storage) +"dUh" = ( +/obj/effect/turf_decal/tile/brown/opposingcorners{ + dir = 1 + }, +/obj/effect/decal/cleanable/greenglow/waste, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "dUj" = ( /obj/effect/turf_decal/trimline/red/filled/corner{ dir = 1 @@ -14747,14 +14702,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/medbay/central) -"dWi" = ( -/mob/living/simple_animal/bot/secbot/beepsky, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/landmark/event_spawn, -/turf/open/floor/iron, -/area/station/hallway/primary/tram/center) "dWj" = ( /obj/machinery/camera/emp_proof{ dir = 9; @@ -14809,6 +14756,22 @@ }, /turf/open/floor/iron/dark, /area/station/science/ordnance/testlab) +"dXj" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Treatment Center" + }, +/obj/effect/turf_decal/trimline/blue/filled/line{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/blue/filled/line{ + dir = 8 + }, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/access/all/medical/general, +/obj/structure/cable, +/obj/effect/mapping_helpers/airlock/unres/delayed, +/turf/open/floor/iron/white, +/area/station/medical/treatment_center) "dXm" = ( /obj/effect/turf_decal/trimline/neutral/filled/line{ dir = 9 @@ -14827,6 +14790,22 @@ /obj/structure/sign/flag/terragov/directional/north, /turf/open/floor/iron, /area/station/commons/dorms) +"dXo" = ( +/obj/structure/table/glass, +/obj/item/reagent_containers/chem_pack{ + pixel_x = 10; + pixel_y = 10 + }, +/obj/item/storage/box/rxglasses{ + pixel_x = -4; + pixel_y = 8 + }, +/obj/item/stack/medical/wrap/gauze{ + pixel_x = 8 + }, +/obj/effect/turf_decal/tile/blue/fourcorners, +/turf/open/floor/iron/white, +/area/station/medical/treatment_center) "dXA" = ( /obj/structure/cable, /turf/open/floor/iron/dark, @@ -15126,14 +15105,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, /area/station/science/ordnance) -"edQ" = ( -/obj/effect/spawner/random/entertainment/slot_machine{ - pixel_y = 2 - }, -/obj/machinery/light/cold/directional/south, -/obj/machinery/airalarm/directional/south, -/turf/open/floor/iron/dark, -/area/station/commons/lounge) "eep" = ( /turf/open/floor/plating, /area/station/service/barber) @@ -16468,6 +16439,24 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/entry) +"eEz" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Medbay"; + id_tag = "MedbayFoyer" + }, +/obj/effect/turf_decal/trimline/blue/filled/line{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/blue/filled/line{ + dir = 8 + }, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/access/all/medical/general, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/mapping_helpers/airlock/unres/delayed, +/turf/open/floor/iron/white, +/area/station/medical/medbay/lobby) "eEH" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 1 @@ -20543,6 +20532,14 @@ /obj/structure/ladder, /turf/open/openspace/airless, /area/station/asteroid) +"gfr" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "gfK" = ( /turf/closed/wall/r_wall, /area/station/security/execution/education) @@ -21540,6 +21537,27 @@ /obj/structure/sign/calendar/directional/south, /turf/open/floor/iron, /area/station/commons/fitness) +"gyk" = ( +/obj/structure/window/spawner/directional/north, +/obj/structure/table/glass, +/obj/item/storage/box/monkeycubes{ + pixel_x = -7; + pixel_y = 7 + }, +/obj/item/tgui_book/manual/infuser{ + pixel_x = 5; + pixel_y = 3 + }, +/obj/item/storage/pill_bottle/mutadone{ + pixel_x = 9; + pixel_y = 3 + }, +/obj/effect/turf_decal/tile/dark_green/fourcorners, +/obj/item/storage/box/monkeycubes{ + pixel_x = -5 + }, +/turf/open/floor/iron/white, +/area/station/science/genetics) "gyn" = ( /obj/effect/turf_decal/siding/thinplating/dark, /obj/effect/spawner/random/vending/colavend, @@ -22040,6 +22058,12 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible, /turf/open/floor/iron/dark, /area/station/medical/treatment_center) +"gHr" = ( +/obj/machinery/light/warm/directional/north, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "gHx" = ( /obj/effect/landmark/event_spawn, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -22825,15 +22849,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/engineering/atmos) -"gWx" = ( -/mob/living/simple_animal/bot/secbot/pingsky{ - 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/circuit, -/area/station/ai/satellite/interior) "gWD" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -23228,6 +23243,16 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/commons/fitness/recreation) +"hfd" = ( +/obj/structure/table/glass, +/obj/item/stack/medical/wrap/gauze, +/obj/item/stack/medical/suture, +/obj/effect/turf_decal/trimline/blue/filled/line{ + dir = 9 + }, +/obj/machinery/light/directional/west, +/turf/open/floor/iron/white, +/area/station/medical/treatment_center) "hfe" = ( /obj/effect/turf_decal/trimline/red/filled/corner, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -24288,6 +24313,15 @@ /obj/machinery/vending/cigarette, /turf/open/floor/iron/cafeteria, /area/station/science/breakroom) +"hCz" = ( +/obj/machinery/airalarm/directional/east, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "hCA" = ( /obj/machinery/chem_master/condimaster{ name = "HoochMaster Deluxe"; @@ -24831,6 +24865,17 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/engineering/break_room) +"hMw" = ( +/obj/machinery/bouldertech/refinery{ + dir = 4 + }, +/obj/machinery/conveyor{ + dir = 8; + id = "mining" + }, +/obj/structure/railing, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "hMA" = ( /obj/effect/turf_decal/siding/thinplating{ dir = 6 @@ -25656,24 +25701,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/carpet, /area/station/commons/dorms) -"iaM" = ( -/obj/machinery/door/airlock/medical/glass{ - name = "Medbay"; - id_tag = "MedbayFoyer" - }, -/obj/effect/turf_decal/trimline/blue/filled/line{ - dir = 4 - }, -/obj/effect/turf_decal/trimline/blue/filled/line{ - dir = 8 - }, -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/access/all/medical/general, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/mapping_helpers/airlock/unres/delayed, -/turf/open/floor/iron/white, -/area/station/medical/medbay/lobby) "iaT" = ( /obj/machinery/holopad, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -27896,13 +27923,6 @@ /obj/item/kirbyplants/photosynthetic, /turf/open/floor/iron/dark, /area/station/ai/satellite/interior) -"iTJ" = ( -/obj/effect/spawner/random/entertainment/slot_machine{ - pixel_y = 2 - }, -/obj/machinery/light/cold/directional/north, -/turf/open/floor/iron/dark, -/area/station/commons/lounge) "iTO" = ( /obj/structure/window/spawner/directional/east, /obj/structure/window/spawner/directional/west, @@ -28935,6 +28955,16 @@ /obj/effect/turf_decal/tile/dark_blue/fourcorners, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/captain/private) +"jkr" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "mining" + }, +/obj/structure/railing/corner/end/flip{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "jkt" = ( /turf/open/floor/carpet, /area/station/service/chapel) @@ -29170,6 +29200,12 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/command) +"joA" = ( +/obj/structure/sign/poster/official/midtown_slice/directional/north, +/obj/effect/mapping_helpers/burnt_floor, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "joB" = ( /obj/effect/turf_decal/trimline/neutral/filled/line{ dir = 8 @@ -29413,14 +29449,6 @@ }, /turf/open/floor/iron/cafeteria, /area/station/command/heads_quarters/rd) -"jsx" = ( -/obj/machinery/conveyor{ - dir = 8; - id = "mining" - }, -/obj/machinery/digital_clock/directional/north, -/turf/open/floor/iron, -/area/station/cargo/miningfoundry) "jsy" = ( /obj/effect/turf_decal/siding/thinplating/dark{ dir = 9 @@ -29709,15 +29737,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/wood, /area/station/commons/dorms) -"jwy" = ( -/obj/machinery/airalarm/directional/east, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/railing/corner/end/flip{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/cargo/miningfoundry) "jwz" = ( /obj/effect/landmark/secequipment, /obj/effect/turf_decal/bot, @@ -30235,24 +30254,6 @@ /obj/structure/tank_dispenser/oxygen, /turf/open/floor/iron/dark/herringbone, /area/station/commons/vacant_room) -"jFB" = ( -/obj/effect/turf_decal/trimline/green/filled/line{ - dir = 8 - }, -/obj/structure/table/glass, -/obj/item/book/manual/wiki/infections{ - pixel_y = 7 - }, -/obj/item/reagent_containers/dropper, -/obj/item/reagent_containers/spray/cleaner, -/obj/item/reagent_containers/syringe/antiviral, -/obj/machinery/status_display/ai/directional/west, -/obj/item/tgui_book/manual/idc{ - pixel_y = 9; - pixel_x = 3 - }, -/turf/open/floor/iron/white, -/area/station/medical/virology) "jFC" = ( /obj/machinery/vending/hydroseeds{ slogan_delay = 700 @@ -31724,26 +31725,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron, /area/station/hallway/secondary/exit) -"kdN" = ( -/obj/machinery/door/airlock/medical/glass{ - name = "Treatment Center" - }, -/obj/effect/turf_decal/trimline/blue/filled/line{ - dir = 1 - }, -/obj/effect/turf_decal/trimline/blue/filled/line, -/obj/machinery/door/firedoor, -/obj/machinery/duct, -/obj/effect/mapping_helpers/airlock/access/all/medical/general, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/mapping_helpers/airlock/unres/delayed{ - dir = 8 - }, -/turf/open/floor/iron/white, -/area/station/medical/treatment_center) "kdV" = ( /obj/effect/turf_decal/trimline/neutral/filled/line{ dir = 4 @@ -33002,13 +32983,6 @@ /obj/machinery/light/small/dim/directional/south, /turf/open/floor/iron, /area/station/maintenance/tram/left) -"kxV" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/miningfoundry) "kye" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/cafeteria, @@ -33974,19 +33948,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/security/prison/workout) -"kNk" = ( -/obj/structure/table/reinforced, -/obj/machinery/door/firedoor, -/obj/machinery/door/window/left/directional/south{ - name = "Genetics Lab Desk"; - req_access = list("science") - }, -/obj/structure/desk_bell{ - pixel_x = 7 - }, -/obj/effect/turf_decal/tile/dark_green/fourcorners, -/turf/open/floor/iron/white/side, -/area/station/science/genetics) "kNn" = ( /obj/effect/turf_decal/trimline/neutral/filled/line{ dir = 9 @@ -34870,6 +34831,14 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/catwalk_floor, /area/station/maintenance/solars/port) +"lbW" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/conveyor{ + dir = 8; + id = "mining" + }, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "lbZ" = ( /obj/structure/table, /obj/item/paper_bin{ @@ -35791,6 +35760,24 @@ }, /turf/open/floor/iron/dark, /area/station/command/vault) +"lrA" = ( +/obj/effect/turf_decal/trimline/green/filled/line{ + dir = 8 + }, +/obj/structure/table/glass, +/obj/item/book/manual/wiki/infections{ + pixel_y = 7 + }, +/obj/item/reagent_containers/dropper, +/obj/item/reagent_containers/spray/cleaner, +/obj/item/reagent_containers/syringe/antiviral, +/obj/machinery/status_display/ai/directional/west, +/obj/item/tgui_book/manual/idc{ + pixel_y = 9; + pixel_x = 3 + }, +/turf/open/floor/iron/white, +/area/station/medical/virology) "lrG" = ( /obj/effect/turf_decal/sand/plating, /obj/item/flashlight/flare, @@ -36209,6 +36196,16 @@ }, /turf/open/floor/catwalk_floor, /area/station/hallway/primary/tram/right) +"lyv" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "mining" + }, +/obj/structure/railing/corner/end{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "lyx" = ( /obj/structure/table, /obj/machinery/recharger{ @@ -36394,26 +36391,6 @@ }, /turf/open/floor/iron/white, /area/station/science/ordnance) -"lBM" = ( -/obj/structure/table/glass, -/obj/item/book/manual/wiki/surgery{ - pixel_y = 0; - pixel_x = 3 - }, -/obj/item/book/manual/wiki/medicine{ - pixel_y = 3; - pixel_x = 3 - }, -/obj/item/tgui_book/manual/dsm{ - pixel_y = 6; - pixel_x = 3 - }, -/obj/item/tgui_book/manual/idc{ - pixel_y = 9; - pixel_x = 3 - }, -/turf/open/floor/iron/dark, -/area/station/medical/treatment_center) "lBP" = ( /obj/machinery/holopad, /obj/effect/turf_decal/bot, @@ -38097,13 +38074,6 @@ }, /turf/open/floor/iron, /area/station/security/courtroom) -"meg" = ( -/obj/machinery/light/small/directional/west, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/miningfoundry) "men" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 4 @@ -38168,6 +38138,15 @@ /obj/effect/turf_decal/trimline/blue/filled/line, /turf/open/floor/iron, /area/station/command/bridge) +"mfv" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + dir = 1; + id = "genetics_shutters"; + name = "Genetics Shutters" + }, +/turf/open/floor/plating, +/area/station/science/genetics) "mfB" = ( /obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible{ dir = 1 @@ -38744,13 +38723,6 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/entry) -"mqT" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/station/cargo/miningfoundry) "mrf" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 1 @@ -39252,6 +39224,25 @@ "mBq" = ( /turf/closed/wall/r_wall, /area/station/maintenance/department/crew_quarters/dorms) +"mBQ" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Medbay"; + id_tag = "MedbayFoyer" + }, +/obj/effect/turf_decal/trimline/blue/filled/line{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/blue/filled/line{ + dir = 8 + }, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/access/all/medical/general, +/obj/structure/cable, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/mapping_helpers/airlock/unres/delayed, +/turf/open/floor/iron/white, +/area/station/medical/medbay/lobby) "mBT" = ( /obj/machinery/power/apc/auto_name/directional/east, /obj/structure/cable, @@ -39661,6 +39652,10 @@ dir = 8 }, /area/station/command/bridge) +"mIM" = ( +/obj/effect/decal/cleanable/rubble, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "mIN" = ( /obj/structure/table, /obj/item/radio/intercom/prison, @@ -40122,11 +40117,6 @@ /obj/structure/sign/clock/directional/east, /turf/open/floor/carpet, /area/station/medical/psychology) -"mTg" = ( -/obj/effect/decal/cleanable/rubble, -/obj/structure/closet/crate, -/turf/open/floor/iron, -/area/station/cargo/miningfoundry) "mTh" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/chapel{ @@ -40513,6 +40503,20 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/hallway/secondary/service) +"ncr" = ( +/obj/structure/table/glass, +/obj/effect/turf_decal/tile/blue/fourcorners, +/obj/machinery/light/cold/directional/south, +/obj/item/tgui_book/manual/dsm{ + pixel_x = -6; + pixel_y = 4 + }, +/obj/item/tgui_book/manual/idc{ + pixel_y = 3 + }, +/obj/item/storage/briefcase/secure, +/turf/open/floor/iron/white, +/area/station/command/heads_quarters/cmo) "ncv" = ( /obj/structure/lattice/catwalk, /obj/structure/cable, @@ -41634,6 +41638,17 @@ /obj/machinery/light/floor, /turf/open/floor/iron, /area/station/security/armory) +"nvJ" = ( +/obj/effect/turf_decal/tile/dark_green/fourcorners, +/obj/machinery/button/door/directional/east{ + id = "genetics_shutters"; + name = "Genetics Shutters"; + pixel_y = 0; + req_access = list("genetics"); + pixel_x = 23 + }, +/turf/open/floor/iron/white, +/area/station/science/genetics) "nwd" = ( /obj/effect/turf_decal/trimline/neutral/filled/line{ dir = 4 @@ -41721,10 +41736,6 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/exit) -"nxN" = ( -/obj/item/radio/intercom/directional/west, -/turf/open/floor/iron, -/area/station/cargo/miningfoundry) "nxT" = ( /obj/effect/turf_decal/trimline/yellow/filled/line, /turf/open/floor/iron, @@ -43092,12 +43103,6 @@ }, /turf/open/floor/iron, /area/station/command/teleporter) -"nXb" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/railing, -/turf/open/floor/iron, -/area/station/cargo/miningfoundry) "nXh" = ( /obj/effect/turf_decal/trimline/neutral/warning{ dir = 1 @@ -43682,6 +43687,20 @@ }, /turf/open/floor/engine, /area/station/engineering/supermatter/room) +"oiH" = ( +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/dark_green/fourcorners, +/obj/machinery/door/airlock/research/glass{ + name = "Genetics Lab" + }, +/obj/effect/mapping_helpers/airlock/access/all/science/genetics, +/obj/machinery/door/poddoor/shutters/preopen{ + dir = 1; + id = "genetics_shutters"; + name = "Genetics Shutters" + }, +/turf/open/floor/iron/white/side, +/area/station/science/genetics) "oiI" = ( /obj/machinery/firealarm/directional/south{ pixel_x = -3 @@ -44054,6 +44073,24 @@ }, /turf/open/floor/plating, /area/station/maintenance/disposal) +"oqB" = ( +/obj/structure/table/reinforced, +/obj/machinery/door/firedoor, +/obj/machinery/door/window/left/directional/south{ + name = "Genetics Lab Desk"; + req_access = list("science") + }, +/obj/structure/desk_bell{ + pixel_x = 7 + }, +/obj/effect/turf_decal/tile/dark_green/fourcorners, +/obj/machinery/door/poddoor/shutters/preopen{ + dir = 1; + id = "genetics_shutters"; + name = "Genetics Shutters" + }, +/turf/open/floor/iron/white/side, +/area/station/science/genetics) "oqF" = ( /obj/machinery/light/directional/south, /turf/open/water/no_planet_atmos/deep, @@ -49648,6 +49685,17 @@ /obj/machinery/meter, /turf/open/floor/iron, /area/station/engineering/atmos) +"qtc" = ( +/obj/structure/table, +/obj/effect/turf_decal/trimline/blue/filled/line{ + dir = 5 + }, +/obj/item/stack/medical/wrap/gauze, +/obj/item/stack/medical/mesh, +/obj/item/radio/intercom/directional/east, +/obj/machinery/light/cold/directional/north, +/turf/open/floor/iron/white, +/area/station/medical/medbay/lobby) "qti" = ( /obj/effect/turf_decal/siding/wood{ dir = 9 @@ -49830,6 +49878,14 @@ /obj/machinery/wall_healer/directional/south, /turf/open/floor/iron/white, /area/station/science/xenobiology) +"qwE" = ( +/obj/item/radio/intercom/directional/west, +/obj/effect/mapping_helpers/burnt_floor, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "qwH" = ( /obj/structure/extinguisher_cabinet/directional/south, /turf/open/floor/wood, @@ -49937,14 +49993,6 @@ "qza" = ( /turf/closed/wall, /area/station/command/heads_quarters/qm) -"qzh" = ( -/obj/machinery/bouldertech/refinery/smelter, -/obj/machinery/conveyor{ - dir = 8; - id = "mining" - }, -/turf/open/floor/iron, -/area/station/cargo/miningfoundry) "qzn" = ( /obj/machinery/vending/wardrobe/curator_wardrobe, /turf/open/floor/engine/cult, @@ -50685,14 +50733,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/science/ordnance/testlab) -"qMI" = ( -/obj/machinery/light/warm/directional/north, -/obj/machinery/conveyor{ - dir = 8; - id = "mining" - }, -/turf/open/floor/iron, -/area/station/cargo/miningfoundry) "qMQ" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -51723,6 +51763,14 @@ /obj/effect/landmark/navigate_destination/aiupload, /turf/open/floor/iron/dark, /area/station/ai/upload/chamber) +"reE" = ( +/mob/living/basic/bot/secbot/beepsky, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/landmark/event_spawn, +/turf/open/floor/iron, +/area/station/hallway/primary/tram/center) "reU" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/camera/directional/south{ @@ -51975,22 +52023,6 @@ /obj/effect/turf_decal/tile/red/anticorner/contrasted, /turf/open/floor/iron, /area/station/command/bridge) -"rji" = ( -/obj/structure/table/glass, -/obj/item/reagent_containers/chem_pack{ - pixel_x = 10; - pixel_y = 10 - }, -/obj/item/storage/box/rxglasses{ - pixel_x = -4; - pixel_y = 8 - }, -/obj/item/stack/medical/wrap/gauze{ - pixel_x = 8 - }, -/obj/effect/turf_decal/tile/blue/fourcorners, -/turf/open/floor/iron/white, -/area/station/medical/treatment_center) "rjs" = ( /obj/machinery/medical_kiosk, /obj/effect/turf_decal/trimline/blue/filled/line{ @@ -52018,6 +52050,14 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) +"rjC" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "rjP" = ( /obj/machinery/portable_atmospherics/canister/oxygen, /obj/machinery/light/floor, @@ -52580,6 +52620,26 @@ }, /turf/open/floor/plating, /area/station/maintenance/solars/starboard/fore) +"rub" = ( +/obj/structure/table/glass, +/obj/item/book/manual/wiki/surgery{ + pixel_y = 0; + pixel_x = 3 + }, +/obj/item/book/manual/wiki/medicine{ + pixel_y = 3; + pixel_x = 3 + }, +/obj/item/tgui_book/manual/dsm{ + pixel_y = 6; + pixel_x = 3 + }, +/obj/item/tgui_book/manual/idc{ + pixel_y = 9; + pixel_x = 3 + }, +/turf/open/floor/iron/dark, +/area/station/medical/treatment_center) "run" = ( /turf/closed/wall/r_wall, /area/station/security/medical) @@ -52706,17 +52766,6 @@ /obj/effect/turf_decal/sand/plating, /turf/open/floor/plating/airless, /area/station/asteroid) -"rws" = ( -/obj/structure/table/glass, -/obj/item/storage/box/monkeycubes{ - pixel_x = -5 - }, -/obj/item/reagent_containers/spray/cleaner{ - pixel_x = 9 - }, -/obj/effect/turf_decal/tile/dark_green/fourcorners, -/turf/open/floor/iron/white, -/area/station/science/genetics) "rwF" = ( /obj/structure/railing, /obj/effect/turf_decal/trimline/dark_red/warning{ @@ -53039,6 +53088,12 @@ /obj/effect/turf_decal/tile/brown/fourcorners, /turf/open/floor/iron, /area/station/cargo/warehouse) +"rCu" = ( +/mob/living/basic/bot/secbot/beepsky/armsky, +/obj/effect/turf_decal/stripes/line, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/security/armory) "rCL" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/cable, @@ -54184,12 +54239,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/commons/fitness/recreation) -"rXV" = ( -/obj/effect/spawner/random/entertainment/slot_machine{ - pixel_y = 2 - }, -/turf/open/floor/iron/dark, -/area/station/commons/lounge) "rYd" = ( /obj/structure/bodycontainer/morgue{ dir = 2 @@ -54703,14 +54752,6 @@ dir = 4 }, /area/station/service/theater) -"siF" = ( -/obj/machinery/bouldertech/refinery, -/obj/machinery/conveyor{ - dir = 8; - id = "mining" - }, -/turf/open/floor/iron, -/area/station/cargo/miningfoundry) "siL" = ( /obj/effect/turf_decal/trimline/purple/filled/line{ dir = 1 @@ -55804,12 +55845,6 @@ /obj/machinery/firealarm/directional/east, /turf/open/floor/iron/dark, /area/station/engineering/supermatter/room) -"szr" = ( -/obj/effect/turf_decal/tile/brown/opposingcorners{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/miningfoundry) "szs" = ( /obj/effect/turf_decal/trimline/neutral/filled/line{ dir = 10 @@ -57788,17 +57823,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/grimy, /area/station/security/detectives_office) -"tlw" = ( -/obj/structure/table, -/obj/effect/turf_decal/trimline/blue/filled/line{ - dir = 5 - }, -/obj/item/stack/medical/wrap/gauze, -/obj/item/stack/medical/mesh, -/obj/item/radio/intercom/directional/east, -/obj/machinery/light/cold/directional/north, -/turf/open/floor/iron/white, -/area/station/medical/medbay/lobby) "tlP" = ( /obj/effect/turf_decal/trimline/neutral/filled/corner{ dir = 1 @@ -59264,6 +59288,15 @@ }, /turf/open/floor/wood/parquet, /area/station/service/library) +"tLm" = ( +/mob/living/basic/bot/secbot/pingsky{ + 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/circuit, +/area/station/ai/satellite/interior) "tLs" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -59595,6 +59628,16 @@ /obj/machinery/drone_dispenser, /turf/open/floor/iron/smooth, /area/station/maintenance/department/science) +"tRz" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, +/obj/effect/turf_decal/siding/thinplating_new{ + dir = 4 + }, +/obj/machinery/gizmo/toggle/tucker_tubes, +/turf/open/floor/iron, +/area/station/science/explab) "tRT" = ( /obj/effect/turf_decal/trimline/brown/filled/line{ dir = 1 @@ -59823,15 +59866,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/commons/dorms) -"tVK" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 - }, -/obj/effect/turf_decal/siding/thinplating_new{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/science/explab) "tWb" = ( /obj/machinery/camera/directional/east{ c_tag = "Civilian - Theatre Stage" @@ -59910,6 +59944,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/engineering/atmos) +"tXl" = ( +/obj/machinery/light/small/directional/west, +/obj/structure/railing/corner/end{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "tXn" = ( /obj/effect/spawner/structure/window, /turf/open/floor/plating, @@ -61725,6 +61766,10 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/secondary/entry) +"uAv" = ( +/obj/effect/spawner/random/gizmo, +/turf/open/floor/engine, +/area/station/science/explab) "uAx" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 4 @@ -61751,6 +61796,22 @@ }, /turf/open/floor/plating, /area/station/science/xenobiology) +"uAH" = ( +/mob/living/basic/bot/secbot/beepsky/officer, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/trimline/neutral/filled/line, +/obj/machinery/camera/directional/south{ + c_tag = "Maintenance - East Tram Tunnel 4" + }, +/obj/effect/turf_decal/bot_red, +/obj/effect/turf_decal/siding/thinplating{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/white/warning{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/maintenance/tram/right) "uAK" = ( /obj/effect/turf_decal/trimline/red/filled/corner, /turf/open/floor/iron/dark, @@ -62876,23 +62937,6 @@ /obj/structure/cable, /turf/open/floor/wood, /area/station/commons/vacant_room/office) -"uSX" = ( -/obj/machinery/door/airlock/medical/glass{ - name = "Treatment Center" - }, -/obj/effect/turf_decal/trimline/blue/filled/line{ - dir = 1 - }, -/obj/effect/turf_decal/trimline/blue/filled/line, -/obj/machinery/door/firedoor, -/obj/machinery/duct, -/obj/effect/mapping_helpers/airlock/access/all/medical/general, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/mapping_helpers/airlock/unres/delayed{ - dir = 4 - }, -/turf/open/floor/iron/white, -/area/station/medical/treatment_center) "uTg" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -64973,6 +65017,10 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/cargo/miningdock) +"vCO" = ( +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "vCS" = ( /turf/closed/mineral/random/stationside/asteroid/porus, /area/station/engineering/atmos) @@ -65122,15 +65170,6 @@ }, /turf/open/floor/iron/white, /area/station/science/xenobiology) -"vFe" = ( -/obj/effect/mapping_helpers/burnt_floor, -/obj/structure/sign/poster/official/midtown_slice/directional/north, -/obj/machinery/conveyor{ - dir = 8; - id = "mining" - }, -/turf/open/floor/iron, -/area/station/cargo/miningfoundry) "vFh" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 4 @@ -66007,6 +66046,25 @@ /obj/structure/sign/warning/pods/directional/north, /turf/open/openspace, /area/station/hallway/secondary/entry) +"vVb" = ( +/obj/structure/table/glass, +/obj/item/storage/box/bodybags{ + pixel_x = -1; + pixel_y = 6 + }, +/obj/item/storage/box/disks{ + pixel_x = 1; + pixel_y = 5 + }, +/obj/item/storage/box/monkeycubes{ + pixel_x = -5 + }, +/obj/effect/turf_decal/tile/dark_green/fourcorners, +/obj/item/reagent_containers/spray/cleaner{ + pixel_x = 9 + }, +/turf/open/floor/iron/white, +/area/station/science/genetics) "vVc" = ( /obj/effect/turf_decal/trimline/neutral/filled/line{ dir = 8 @@ -66079,16 +66137,6 @@ }, /turf/open/floor/iron/white, /area/station/science/xenobiology) -"vXx" = ( -/obj/structure/table/glass, -/obj/item/stack/medical/wrap/gauze, -/obj/item/stack/medical/suture, -/obj/effect/turf_decal/trimline/blue/filled/line{ - dir = 9 - }, -/obj/machinery/light/directional/west, -/turf/open/floor/iron/white, -/area/station/medical/treatment_center) "vXL" = ( /obj/effect/turf_decal/trimline/yellow/filled/line, /turf/open/floor/iron, @@ -66353,24 +66401,6 @@ }, /turf/open/floor/iron/checker, /area/station/commons/lounge) -"wcw" = ( -/obj/structure/window/spawner/directional/north, -/obj/structure/table/glass, -/obj/item/storage/box/monkeycubes{ - pixel_x = -7; - pixel_y = 7 - }, -/obj/item/tgui_book/manual/infuser{ - pixel_x = 5; - pixel_y = 3 - }, -/obj/item/storage/pill_bottle/mutadone{ - pixel_x = 9; - pixel_y = 3 - }, -/obj/effect/turf_decal/tile/dark_green/fourcorners, -/turf/open/floor/iron/white, -/area/station/science/genetics) "wcy" = ( /obj/effect/turf_decal/trimline/purple/filled/line{ dir = 10 @@ -67376,6 +67406,14 @@ /obj/item/gun/ballistic/shotgun/doublebarrel, /turf/open/floor/wood, /area/station/service/bar/backroom) +"wwj" = ( +/obj/effect/spawner/random/entertainment/slot_machine{ + pixel_y = 2 + }, +/obj/machinery/light/cold/directional/south, +/obj/machinery/airalarm/directional/south, +/turf/open/floor/iron/dark, +/area/station/commons/lounge) "wwA" = ( /obj/effect/turf_decal/trimline/neutral/filled/line, /obj/structure/closet/wardrobe/mixed, @@ -68647,6 +68685,26 @@ }, /turf/open/floor/iron/dark, /area/station/service/chapel/office) +"wTN" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Treatment Center" + }, +/obj/effect/turf_decal/trimline/blue/filled/line{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/blue/filled/line, +/obj/machinery/door/firedoor, +/obj/machinery/duct, +/obj/effect/mapping_helpers/airlock/access/all/medical/general, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/mapping_helpers/airlock/unres/delayed{ + dir = 8 + }, +/turf/open/floor/iron/white, +/area/station/medical/treatment_center) "wTP" = ( /obj/structure/bodycontainer/morgue/beeper_off, /obj/structure/window/reinforced/spawner/directional/south, @@ -69052,11 +69110,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/white, /area/station/science/xenobiology) -"xcU" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/railing, -/turf/open/floor/iron, -/area/station/cargo/miningfoundry) "xdx" = ( /obj/effect/turf_decal/stripes/line{ dir = 6 @@ -69908,6 +69961,14 @@ /obj/effect/mapping_helpers/airalarm/surgery, /turf/open/floor/iron/white, /area/station/medical/surgery/aft) +"xuH" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/bouldertech/refinery/smelter{ + dir = 4 + }, +/obj/structure/railing, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "xuI" = ( /obj/effect/turf_decal/stripes/corner{ dir = 1 @@ -117816,9 +117877,9 @@ aac aaa aaa xdZ -mTg -meg -nxN +mIM +tXl +qwE omS unl ikc @@ -118073,9 +118134,9 @@ aac aac aaa xdZ -qzh -mqT -cqj +vCO +xuH +bjo mgj unl oNp @@ -118330,10 +118391,10 @@ aac aaa aaa xdZ -vFe -cZQ -ajn -szr +joA +jkr +rjC +dUh unl rbM gJs @@ -118587,9 +118648,9 @@ aac aac aaa xdZ -qMI -cZQ -xcU +gHr +lyv +bjo sfn njK xiZ @@ -118844,9 +118905,9 @@ aac aaa aaa xdZ -siF -cZQ -xcU +vCO +hMw +bjo goY njK flZ @@ -119101,9 +119162,9 @@ aac aaa aaa xdZ -jsx -mqT -xcU +bIT +jkr +bjo eAV qxG unl @@ -119358,9 +119419,9 @@ aac aac aaa xdZ -ddY -kxV -nXb +asb +lbW +gfr wAB nzF jrJ @@ -119615,9 +119676,9 @@ aac aaa aaa xdZ +dHd fdc -cZQ -jwy +hCz sUC pIF rRp @@ -119651,7 +119712,7 @@ hFC hFC hFC hFC -adD +uAH qxm qxm abM @@ -119917,7 +119978,7 @@ sQZ owO owO owO -owO +uAv cJS rKD udg @@ -120178,7 +120239,7 @@ sQZ sQZ wrz hIY -tVK +tRz vIF yeZ hTg @@ -120433,7 +120494,7 @@ aaa aaa aaa sQZ -mtI +sQZ fGK bwU vEl @@ -121012,7 +121073,7 @@ dKU szZ kZw mxm -gWx +tLm byF waj iJY @@ -156099,7 +156160,7 @@ hPs juT lAC pbo -aeX +rCu yjm oby etH @@ -167177,12 +167238,12 @@ abM abM abM omm -iTJ +dds jEL hht nTz rQl -edQ +wwj izU swd izU @@ -167691,12 +167752,12 @@ abM abM abM omm -rXV +diN lsx iEl bra mfN -rXV +diN izU mXI kmb @@ -167742,7 +167803,7 @@ aOF wdj wao cHU -bLu +ncr wdj oGJ oGJ @@ -168500,7 +168561,7 @@ jtr jtr jtr xSZ -uSX +cbY xSZ jtr jtr @@ -168751,10 +168812,10 @@ wyd qNI dyI tDP -avZ +dRM jtr jtr -vXx +hfd kWR dZX lxI @@ -169262,7 +169323,7 @@ lNF wAI wAI enB -cXS +mBQ bbD uck gBz @@ -169769,7 +169830,7 @@ qfF pLs izU yhN -dWi +reE bPh sSt jEK @@ -169780,13 +169841,13 @@ wyd dyI aHP aKq -dcY +dXj aLe oIU aLA whF ecW -rji +dXo lTc lrQ xOn @@ -170048,7 +170109,7 @@ eGn xOn xOn gHp -lBM +rub xSZ tLE aOS @@ -170290,7 +170351,7 @@ foh gxq gxq rjx -iaM +eEz eYP tIX irR @@ -170542,7 +170603,7 @@ ykP lej iOy wyd -tlw +qtc kin juV uAx @@ -170816,7 +170877,7 @@ qDF uwk oXz gNE -caT +bVY jtr jtr jtr @@ -171070,7 +171131,7 @@ jtr jtr rhd xSZ -kdN +wTN xSZ jtr jtr @@ -172880,7 +172941,7 @@ cdi ugt qjF rkd -jFB +lrA ycI fwB ugt @@ -185458,8 +185519,8 @@ xNT xNT xNT xNT -kvt -dpB +xNT +bKH nZO kvt wtw @@ -185710,10 +185771,10 @@ tXz hmd bHb sed -dpB +oqB vpp gel -wcw +gyk llY qab lWJ @@ -185967,7 +186028,7 @@ gAQ eoX geG ruD -kNk +mfv tvQ oIe cNX @@ -186224,7 +186285,7 @@ gAQ eoX fyc vwD -dpB +oiH iqM nzk rle @@ -186998,11 +187059,11 @@ pdn xNT kNM ktg -bDB +vVb xNT kNM ktg -rws +nvJ xNT xNT syv diff --git a/_maps/map_files/wawastation/wawastation.dmm b/_maps/map_files/wawastation/wawastation.dmm index 381cd52bdbc..ee82f831ce9 100644 --- a/_maps/map_files/wawastation/wawastation.dmm +++ b/_maps/map_files/wawastation/wawastation.dmm @@ -159,18 +159,6 @@ /obj/item/holosign_creator/atmos, /turf/open/floor/iron/dark, /area/station/science/ordnance) -"acY" = ( -/obj/structure/cable, -/obj/structure/railing/corner{ - dir = 1 - }, -/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/white, -/area/station/science/research) "adc" = ( /obj/machinery/power/emitter/welded{ dir = 1 @@ -598,20 +586,6 @@ /obj/machinery/telecomms/server/presets/engineering, /turf/open/floor/circuit/green/telecomms/mainframe, /area/station/tcommsat/server) -"aki" = ( -/obj/machinery/computer/dna_console{ - dir = 1 - }, -/obj/structure/railing, -/obj/machinery/door/firedoor/border_only, -/obj/effect/turf_decal/siding/purple{ - dir = 1 - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/open/floor/iron/white/textured, -/area/station/science/genetics) "akl" = ( /obj/machinery/duct, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -759,18 +733,6 @@ }, /turf/open/floor/wood, /area/station/service/theater) -"amn" = ( -/obj/machinery/disposal/bin, -/obj/machinery/button/door/directional/east{ - id = "geneshut"; - name = "Genetics Shutters" - }, -/obj/structure/disposalpipe/trunk{ - dir = 8 - }, -/obj/machinery/firealarm/directional/south, -/turf/open/floor/iron/white/textured, -/area/station/science/genetics) "amJ" = ( /obj/machinery/iv_drip, /obj/effect/turf_decal/tile/blue/fourcorners, @@ -804,17 +766,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) -"and" = ( -/obj/effect/turf_decal/tile/neutral/fourcorners, -/obj/effect/turf_decal/siding/purple{ - dir = 5 - }, -/obj/machinery/camera/autoname/directional/east, -/mob/living/simple_animal/bot/secbot/pingsky, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/white, -/area/station/ai/upload/foyer) "anf" = ( /obj/machinery/light/small/directional/south, /obj/effect/decal/cleanable/dirt, @@ -1029,13 +980,6 @@ /obj/item/lighter, /turf/open/floor/carpet/red, /area/station/command/heads_quarters/qm) -"aqM" = ( -/obj/effect/turf_decal/tile/purple/opposingcorners, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/turf/open/floor/iron/white, -/area/station/science/auxlab/firing_range) "aqR" = ( /obj/structure/chair/stool/directional/east, /obj/effect/landmark/start/assistant, @@ -1639,6 +1583,13 @@ }, /turf/open/floor/iron/white, /area/station/medical/medbay/central) +"aAS" = ( +/obj/effect/turf_decal/siding/purple, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/iron/white/textured_large, +/area/station/science/genetics) "aBb" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 1 @@ -1734,6 +1685,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/security/brig) +"aCF" = ( +/obj/machinery/dna_scannernew, +/obj/machinery/power/apc/auto_name/directional/west, +/obj/machinery/door/firedoor/border_only, +/obj/structure/cable, +/turf/open/floor/iron/white/textured, +/area/station/science/genetics) "aCL" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, @@ -1837,6 +1795,12 @@ }, /turf/open/floor/circuit, /area/station/cargo/bitrunning/den) +"aEE" = ( +/obj/effect/turf_decal/siding/purple{ + dir = 1 + }, +/turf/open/floor/iron/white/textured_large, +/area/station/science/genetics) "aEL" = ( /obj/machinery/airalarm/directional/east, /obj/structure/table/reinforced, @@ -2272,13 +2236,6 @@ }, /turf/open/floor/circuit/green, /area/station/ai/satellite/chamber) -"aLe" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/door/firedoor/border_only, -/turf/open/floor/iron/white/textured, -/area/station/science/genetics) "aLz" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/command{ @@ -2897,6 +2854,16 @@ }, /turf/open/floor/engine, /area/station/science/xenobiology) +"aWs" = ( +/obj/structure/railing{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating, +/area/station/cargo/miningoffice) "aWD" = ( /turf/closed/wall/r_wall, /area/station/engineering/main) @@ -3115,10 +3082,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/engineering/atmos) -"bbe" = ( -/obj/machinery/airalarm/directional/west, -/turf/open/floor/engine, -/area/station/science/auxlab/firing_range) "bbf" = ( /obj/structure/table/reinforced, /obj/machinery/door/poddoor/shutters/preopen{ @@ -3657,12 +3620,6 @@ /obj/effect/turf_decal/sand/plating, /turf/open/floor/plating, /area/station/maintenance/department/medical) -"bme" = ( -/obj/structure/sign/warning/directional/east, -/turf/closed/mineral/random/stationside/asteroid/porus{ - mineralChance = 20 - }, -/area/station/asteroid) "bmf" = ( /obj/effect/turf_decal/siding/white{ dir = 1 @@ -3716,6 +3673,11 @@ /obj/machinery/vending/wardrobe/law_wardrobe, /turf/open/floor/wood, /area/station/service/lawoffice) +"bmG" = ( +/turf/closed/mineral/random/stationside/asteroid/porus{ + mineral_chance = 20 + }, +/area/station/asteroid) "bmL" = ( /obj/effect/spawner/random/engineering/tracking_beacon, /turf/open/floor/carpet, @@ -4486,11 +4448,6 @@ /obj/structure/lattice, /turf/open/openspace, /area/station/command/meeting_room) -"bBo" = ( -/turf/closed/mineral/random/stationside/asteroid/porus{ - mineralChance = 20 - }, -/area/station/cargo/miningoffice) "bBr" = ( /obj/effect/spawner/structure/window/reinforced/plasma, /turf/open/floor/plating, @@ -4587,16 +4544,6 @@ /obj/effect/mapping_helpers/airlock/red_alert_access, /turf/open/floor/iron/dark, /area/station/security/lockers) -"bDy" = ( -/obj/structure/chair/sofa/bench{ - dir = 4 - }, -/obj/effect/turf_decal/tile/purple/half/contrasted{ - dir = 8 - }, -/obj/machinery/camera/autoname/directional/west, -/turf/open/floor/iron/white, -/area/station/science/lobby) "bDA" = ( /obj/effect/turf_decal/siding/wood{ dir = 1 @@ -5055,6 +5002,19 @@ /obj/structure/broken_flooring/corner, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) +"bMI" = ( +/obj/effect/landmark/start/geneticist, +/obj/structure/chair/office{ + dir = 1 + }, +/obj/effect/turf_decal/siding/purple/corner{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/iron/white/textured, +/area/station/science/genetics) "bMP" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -5449,16 +5409,6 @@ dir = 8 }, /area/station/science/xenobiology) -"bUu" = ( -/obj/structure/table, -/obj/machinery/cell_charger, -/obj/item/stock_parts/power_store/cell, -/obj/effect/turf_decal/tile/purple/half/contrasted{ - dir = 1 - }, -/obj/machinery/airalarm/directional/north, -/turf/open/floor/iron/white, -/area/station/science/lobby) "bUx" = ( /obj/effect/landmark/event_spawn, /obj/effect/decal/cleanable/dirt, @@ -5503,13 +5453,6 @@ /obj/machinery/camera/autoname/directional/west, /turf/open/floor/iron/dark, /area/station/engineering/circuit_workshop) -"bUU" = ( -/obj/structure/railing, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/decal/cleanable/blood/tracks, -/obj/machinery/door/firedoor/border_only, -/turf/open/floor/catwalk_floor/iron_white, -/area/station/science/lobby) "bUZ" = ( /obj/machinery/light/small/directional/west, /obj/structure/flora/tree/palm/style_random, @@ -5624,6 +5567,14 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/catwalk_floor/iron_white, /area/station/science/xenobiology) +"bXx" = ( +/obj/machinery/camera/autoname/directional/south, +/obj/machinery/airalarm/directional/south, +/obj/effect/spawner/random/entertainment/slot_machine{ + pixel_y = 2 + }, +/turf/open/floor/wood, +/area/station/commons/lounge) "bXD" = ( /obj/structure/filingcabinet/security, /obj/effect/decal/cleanable/dirt/dust, @@ -5742,12 +5693,6 @@ }, /turf/open/floor/wood, /area/station/service/lawoffice) -"bZI" = ( -/obj/effect/turf_decal/bot, -/mob/living/simple_animal/bot/secbot/beepsky/armsky, -/obj/effect/landmark/event_spawn, -/turf/open/floor/iron/dark/textured_large, -/area/station/security/armory) "caq" = ( /obj/effect/spawner/surgery_tray/full/deployed, /obj/effect/turf_decal/tile/blue/fourcorners, @@ -5816,15 +5761,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/catwalk_floor/iron_dark, /area/station/ai/satellite/interior) -"cbn" = ( -/obj/machinery/conveyor{ - dir = 4; - id = "brm" - }, -/obj/effect/turf_decal/sand/plating, -/obj/machinery/light/small/directional/north, -/turf/open/floor/plating, -/area/station/cargo/miningoffice) "cbr" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 4 @@ -5935,11 +5871,6 @@ "cdk" = ( /turf/open/floor/iron/kitchen, /area/station/service/kitchen) -"cdl" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/duct, -/turf/open/floor/plating, -/area/station/science/cytology) "cdo" = ( /obj/machinery/elevator_control_panel/directional/south{ linked_elevator_id = "aisat"; @@ -6401,14 +6332,6 @@ /obj/machinery/duct, /turf/open/floor/iron/freezer, /area/station/commons/toilet/restrooms) -"cmM" = ( -/obj/machinery/power/apc/auto_name/directional/south, -/obj/structure/cable, -/obj/effect/spawner/random/entertainment/slot_machine{ - pixel_y = 2 - }, -/turf/open/floor/wood, -/area/station/commons/lounge) "cmZ" = ( /obj/structure/disposalpipe/segment{ dir = 5 @@ -6715,6 +6638,16 @@ "csW" = ( /turf/open/floor/carpet/executive, /area/station/command/heads_quarters/captain/private) +"csX" = ( +/obj/effect/landmark/start/geneticist, +/obj/structure/chair/office{ + dir = 1 + }, +/obj/structure/cable, +/obj/effect/turf_decal/siding/purple, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/white/textured_large, +/area/station/science/genetics) "cts" = ( /turf/closed/wall/rock/porous, /area/station/medical/chemistry/minisat) @@ -6747,11 +6680,27 @@ /obj/effect/mapping_helpers/airlock/access/all/science/general, /turf/open/floor/iron/white, /area/station/science/research) +"ctI" = ( +/obj/effect/mapping_helpers/airlock/access/all/science/general, +/obj/machinery/door/airlock/science/glass, +/obj/effect/mapping_helpers/airlock/autoname, +/obj/structure/cable, +/obj/effect/turf_decal/tile/purple/opposingcorners, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron/white, +/area/station/science/auxlab/firing_range) "ctL" = ( /obj/structure/window/reinforced/spawner/directional/west, /obj/structure/cable, /turf/open/floor/glass/reinforced, /area/station/security/prison) +"ctP" = ( +/obj/effect/spawner/random/entertainment/slot_machine, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/grimy, +/area/station/maintenance/central/lesser) "cuj" = ( /obj/item/trash/shrimp_chips, /turf/open/floor/plating, @@ -7045,14 +6994,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/catwalk_floor/iron_white, /area/station/science/xenobiology) -"cAr" = ( -/obj/structure/cable, -/obj/machinery/button/door/directional/north{ - id = "chimpcon1"; - name = "anti-chimp protection control" - }, -/turf/open/floor/iron/white/smooth_edge, -/area/station/science/research) "cAv" = ( /obj/machinery/door/airlock/maintenance_hatch, /obj/effect/mapping_helpers/airlock/access/all/supply/general, @@ -7130,10 +7071,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/security/prison/garden) -"cCb" = ( -/obj/structure/lattice/catwalk, -/turf/open/openspace, -/area/station/science/genetics) "cCj" = ( /obj/machinery/shower/directional/north, /obj/effect/turf_decal/trimline/yellow/filled/line{ @@ -7199,6 +7136,11 @@ /obj/item/radio/intercom/directional/north, /turf/open/floor/iron/white, /area/station/hallway/secondary/entry) +"cDz" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/door/firedoor/border_only, +/turf/open/floor/catwalk_floor/iron_white, +/area/station/science/lobby) "cDD" = ( /turf/closed/wall, /area/station/medical/psychology) @@ -7915,20 +7857,6 @@ /obj/structure/cable, /turf/open/floor/iron/dark, /area/station/command/bridge) -"cQR" = ( -/obj/machinery/door/airlock/medical/glass{ - name = "Treatment Centre" - }, -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/access/any/medical/general, -/obj/structure/disposalpipe/segment{ - dir = 8 - }, -/obj/effect/mapping_helpers/airlock/unres/delayed{ - dir = 8 - }, -/turf/open/floor/iron/white, -/area/station/medical/treatment_center) "cQT" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/half{ @@ -7990,21 +7918,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/aft/upper) -"cRV" = ( -/obj/structure/table/glass, -/obj/item/assembly/flash/handheld, -/obj/item/assembly/signaler, -/obj/item/electronics/airlock{ - pixel_x = -14 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 8 - }, -/obj/structure/disposalpipe/segment{ - dir = 10 - }, -/turf/open/floor/iron/white, -/area/station/science/lobby) "cSa" = ( /obj/machinery/power/smes/full, /obj/machinery/power/apc/auto_name/directional/west, @@ -8726,6 +8639,10 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/commons/fitness/recreation) +"dcZ" = ( +/obj/effect/spawner/random/gizmo, +/turf/open/floor/engine, +/area/station/science/explab) "dda" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/door/airlock/maintenance, @@ -8741,6 +8658,18 @@ }, /turf/open/floor/plating, /area/station/commons/vacant_room/commissary) +"ddy" = ( +/obj/machinery/light/directional/south, +/obj/structure/table/glass, +/obj/item/stack/sheet/glass, +/obj/item/assembly/timer, +/obj/effect/turf_decal/tile/purple/half/contrasted, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/item/stack/cable_coil, +/turf/open/floor/iron/white, +/area/station/science/lobby) "ddF" = ( /obj/machinery/power/apc/auto_name/directional/north, /obj/structure/cable, @@ -9330,19 +9259,6 @@ /obj/machinery/light/cold/directional/west, /turf/open/floor/iron/white, /area/station/medical/exam_room) -"dnW" = ( -/obj/structure/table, -/obj/item/paper_bin{ - pixel_x = -2; - pixel_y = 6 - }, -/obj/item/pen, -/obj/effect/turf_decal/tile/purple/half/contrasted{ - dir = 1 - }, -/obj/machinery/firealarm/directional/north, -/turf/open/floor/iron/white, -/area/station/science/lobby) "dog" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -9864,12 +9780,6 @@ "dwI" = ( /turf/open/openspace, /area/station/maintenance/department/medical/central) -"dwV" = ( -/obj/structure/lattice/catwalk, -/obj/structure/railing, -/obj/effect/spawner/random/structure/chair_flipped, -/turf/open/openspace, -/area/station/science/genetics) "dxx" = ( /obj/structure/extinguisher_cabinet/directional/south, /obj/item/kirbyplants/potty, @@ -9879,6 +9789,12 @@ /obj/machinery/telecomms/receiver/preset_left, /turf/open/floor/circuit/green/telecomms/mainframe, /area/station/tcommsat/server) +"dxC" = ( +/obj/structure/railing{ + dir = 8 + }, +/turf/open/floor/catwalk_floor/iron_white, +/area/station/science/lobby) "dxD" = ( /obj/effect/turf_decal/sand/plating, /obj/effect/decal/cleanable/rubble, @@ -10323,13 +10239,6 @@ /obj/effect/spawner/random/maintenance, /turf/open/floor/plating, /area/station/maintenance/port/greater) -"dDI" = ( -/obj/structure/lattice/catwalk, -/obj/structure/railing{ - dir = 10 - }, -/turf/open/openspace, -/area/station/science/genetics) "dDK" = ( /obj/structure/cable/multilayer/multiz, /turf/open/floor/plating, @@ -10347,14 +10256,6 @@ "dEG" = ( /turf/open/floor/grass, /area/station/security/prison/garden) -"dES" = ( -/obj/machinery/dna_scannernew, -/obj/machinery/firealarm/directional/north, -/obj/effect/turf_decal/siding/purple, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/white/textured, -/area/station/science/genetics) "dFb" = ( /obj/effect/turf_decal/siding/wood{ dir = 4 @@ -10419,12 +10320,6 @@ /obj/structure/cable, /turf/open/floor/carpet/executive, /area/station/command/heads_quarters/captain/private) -"dGk" = ( -/obj/structure/sign/warning/directional/south, -/turf/closed/mineral/random/stationside/asteroid/porus{ - mineralChance = 20 - }, -/area/station/asteroid) "dGq" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 8 @@ -10683,6 +10578,12 @@ /obj/effect/decal/cleanable/blood/old, /turf/open/floor/engine/xenobio, /area/station/science/xenobiology) +"dKd" = ( +/obj/structure/sign/warning/directional/south, +/turf/closed/mineral/random/stationside/asteroid/porus{ + mineral_chance = 20 + }, +/area/station/asteroid) "dKo" = ( /obj/machinery/door/airlock/research/glass{ name = "Secure Pen" @@ -10718,6 +10619,14 @@ /obj/structure/sign/warning/vacuum/external/directional/east, /turf/open/floor/plating, /area/station/maintenance/disposal) +"dKU" = ( +/obj/machinery/light/directional/north, +/obj/structure/table, +/obj/effect/turf_decal/tile/purple/opposingcorners, +/obj/item/storage/toolbox/mechanical, +/obj/machinery/airalarm/directional/north, +/turf/open/floor/iron/white, +/area/station/science/auxlab/firing_range) "dLf" = ( /obj/machinery/camera/directional/west{ c_tag = "Atmospherics Tank - Plasma" @@ -10861,14 +10770,6 @@ }, /turf/open/floor/iron/dark/small, /area/station/science/cytology) -"dOl" = ( -/obj/machinery/atmospherics/pipe/multiz/scrubbers/visible/layer2{ - name = "chimpanzee filth exhaust" - }, -/obj/machinery/light/directional/north, -/obj/machinery/firealarm/directional/east, -/turf/open/floor/iron/white, -/area/station/science/research) "dOv" = ( /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -11761,6 +11662,16 @@ /obj/effect/mapping_helpers/mail_sorting/medbay/cmo_office, /turf/open/floor/iron/white, /area/station/medical/medbay/central) +"ecn" = ( +/obj/structure/cable, +/obj/structure/railing/corner{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/disposalpipe/segment, +/turf/open/floor/iron/white, +/area/station/science/research) "ecy" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 1 @@ -11895,6 +11806,14 @@ /obj/effect/spawner/structure/window/reinforced/plasma, /turf/open/floor/engine/vacuum, /area/station/science/ordnance/burnchamber) +"efP" = ( +/obj/effect/turf_decal/siding/purple/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment, +/turf/open/floor/iron/white/textured, +/area/station/science/genetics) "efQ" = ( /obj/structure/cable, /obj/effect/decal/cleanable/dirt, @@ -12045,11 +11964,6 @@ /obj/machinery/light_switch/directional/south, /turf/open/floor/iron, /area/station/security) -"eio" = ( -/turf/closed/mineral/random/stationside/asteroid/porus{ - mineralChance = 20 - }, -/area/station/maintenance/department/cargo) "eip" = ( /obj/structure/cable, /obj/machinery/door/airlock/external{ @@ -12214,6 +12128,17 @@ /obj/item/radio/intercom/directional/south, /turf/open/floor/iron, /area/station/hallway/primary/central) +"ekO" = ( +/obj/machinery/bouldertech/refinery{ + dir = 8 + }, +/obj/machinery/conveyor{ + dir = 4; + id = "brm" + }, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating, +/area/station/cargo/miningoffice) "ekR" = ( /obj/machinery/computer/rdservercontrol{ dir = 4 @@ -12299,6 +12224,11 @@ /obj/machinery/door/firedoor, /turf/open/floor/iron, /area/station/hallway/primary/starboard) +"emQ" = ( +/obj/structure/cable, +/obj/effect/turf_decal/siding/purple/corner, +/turf/open/floor/iron/white/textured, +/area/station/science/genetics) "eng" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -12696,18 +12626,6 @@ "etW" = ( /turf/closed/wall/mineral/plastitanium/nodiagonal, /area/station/maintenance/department/science) -"eua" = ( -/obj/structure/cable, -/obj/structure/railing/corner{ - dir = 4 - }, -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/white, -/area/station/science/research) "euj" = ( /obj/machinery/airalarm/directional/west, /turf/open/floor/plating, @@ -13347,17 +13265,17 @@ /obj/machinery/door/firedoor, /turf/open/floor/iron, /area/station/service/hydroponics/garden) +"eFs" = ( +/obj/machinery/computer/dna_console, +/obj/machinery/light_switch/directional/north, +/turf/open/floor/iron/white/textured, +/area/station/science/genetics) "eFu" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/firealarm/directional/east, /obj/item/kirbyplants/random, /turf/open/floor/iron, /area/station/cargo/miningoffice) -"eFx" = ( -/mob/living/carbon/human/species/monkey, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/grass, -/area/station/science/genetics) "eFy" = ( /obj/machinery/power/apc/auto_name/directional/south, /obj/effect/turf_decal/tile/red/half/contrasted, @@ -13512,6 +13430,13 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/port/lesser) +"eIL" = ( +/obj/structure/cable, +/obj/effect/turf_decal/siding/purple{ + dir = 4 + }, +/turf/open/floor/iron/white/textured, +/area/station/science/genetics) "eIM" = ( /obj/effect/turf_decal/siding/dark, /obj/machinery/door/firedoor/border_only, @@ -14252,6 +14177,11 @@ /obj/structure/cable, /turf/open/space/basic, /area/station/solars/starboard/fore) +"eYp" = ( +/turf/closed/mineral/random/stationside/asteroid/porus{ + mineral_chance = 20 + }, +/area/station/maintenance/department/cargo) "eYt" = ( /obj/structure/chair{ dir = 8 @@ -15207,14 +15137,6 @@ }, /turf/open/floor/iron, /area/station/service/hydroponics) -"frt" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/door/poddoor/shutters/preopen{ - dir = 1; - id = "geneshut" - }, -/turf/open/floor/plating, -/area/station/science/genetics) "frv" = ( /obj/structure/filingcabinet/chestdrawer, /turf/open/floor/iron/dark, @@ -15374,6 +15296,12 @@ /obj/machinery/firealarm/directional/south, /turf/open/floor/iron/dark, /area/station/security/lockers) +"ftQ" = ( +/obj/effect/turf_decal/siding/purple, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/iron/white/textured_large, +/area/station/science/genetics) "ftR" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 4 @@ -15396,13 +15324,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/central/greater) -"fuo" = ( -/obj/effect/landmark/start/geneticist, -/obj/structure/chair/office{ - dir = 1 - }, -/turf/open/floor/glass/reinforced, -/area/station/science/genetics) "fus" = ( /obj/machinery/holopad, /obj/structure/cable, @@ -15769,14 +15690,6 @@ }, /turf/open/floor/wood, /area/station/service/library) -"fAU" = ( -/obj/machinery/power/apc/auto_name/directional/east, -/obj/structure/cable, -/obj/item/radio/intercom/directional/north, -/obj/item/kirbyplants/random, -/obj/effect/turf_decal/tile/purple/opposingcorners, -/turf/open/floor/iron/white, -/area/station/science/auxlab/firing_range) "fAV" = ( /obj/item/kirbyplants/random/dead, /turf/open/misc/asteroid, @@ -16051,23 +15964,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/hallway/primary/central) -"fFq" = ( -/obj/effect/turf_decal/tile/purple/opposingcorners, -/obj/structure/table, -/obj/item/gun/energy/laser/practice{ - pixel_x = 2; - pixel_y = 5 - }, -/obj/item/gun/energy/laser/practice{ - pixel_x = 2; - pixel_y = 1 - }, -/obj/item/gun/energy/laser/practice{ - pixel_x = 2; - pixel_y = -2 - }, -/turf/open/floor/iron/white, -/area/station/science/auxlab/firing_range) "fFt" = ( /obj/machinery/photocopier/prebuilt, /obj/item/newspaper, @@ -16081,10 +15977,6 @@ /obj/structure/cable, /turf/open/floor/iron/white, /area/station/medical/treatment_center) -"fFE" = ( -/obj/effect/decal/cleanable/rubble, -/turf/open/misc/asteroid, -/area/station/cargo/miningoffice) "fFT" = ( /obj/structure/reagent_dispensers/fueltank, /obj/effect/decal/cleanable/dirt, @@ -16619,6 +16511,19 @@ /obj/machinery/wall_healer/directional/west, /turf/open/floor/iron, /area/station/hallway/primary/central) +"fPs" = ( +/obj/effect/turf_decal/tile/blue/half/contrasted{ + dir = 1 + }, +/obj/structure/table, +/obj/item/stack/medical/wrap/gauze, +/obj/item/stack/medical/suture, +/obj/item/stack/medical/mesh, +/obj/machinery/power/apc/auto_name/directional/north, +/obj/structure/cable, +/obj/effect/spawner/random/medical/minor_healing, +/turf/open/floor/iron/white, +/area/station/medical/medbay/lobby) "fPv" = ( /obj/machinery/light_switch/directional/east, /turf/open/floor/glass/reinforced/plasma, @@ -16933,15 +16838,6 @@ /obj/effect/mapping_helpers/mail_sorting/service/bar, /turf/open/floor/iron, /area/station/commons/lounge) -"fTN" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 9 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/white, -/area/station/science/research) "fTX" = ( /turf/closed/wall/r_wall, /area/station/engineering/atmos) @@ -17036,6 +16932,21 @@ }, /turf/open/floor/carpet, /area/station/commons/dorms) +"fVF" = ( +/obj/machinery/door/airlock/medical{ + id_tag = "r1"; + name = "Room A" + }, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/access/any/medical/general, +/obj/effect/turf_decal/tile/blue/fourcorners, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/effect/mapping_helpers/airlock/unres/delayed{ + dir = 4 + }, +/turf/open/floor/iron/white, +/area/station/medical/patients_rooms/room_a) "fVI" = ( /obj/machinery/door/airlock/maintenance_hatch, /obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance, @@ -17080,6 +16991,11 @@ /obj/structure/cable, /turf/open/floor/iron/checker, /area/station/engineering/atmos/mix) +"fWn" = ( +/turf/closed/mineral/random/stationside/asteroid/porus{ + mineral_chance = 20 + }, +/area/station/cargo/miningoffice) "fWp" = ( /obj/effect/turf_decal/siding/white{ dir = 10 @@ -17342,6 +17258,11 @@ }, /turf/open/floor/iron/chapel, /area/station/service/chapel) +"gaM" = ( +/obj/machinery/duct, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/station/science/cytology) "gaN" = ( /obj/effect/landmark/event_spawn, /turf/open/floor/iron, @@ -17637,21 +17558,6 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/department/cargo) -"ggZ" = ( -/obj/machinery/door/airlock/medical{ - name = "Surgery" - }, -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/access/any/medical/surgery, -/obj/effect/turf_decal/tile/blue/fourcorners, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/mapping_helpers/airlock/unres/delayed{ - dir = 8 - }, -/turf/open/floor/iron/white/smooth_large, -/area/station/medical/surgery) "gho" = ( /obj/structure/table/wood, /obj/item/food/grown/harebell{ @@ -17860,6 +17766,11 @@ }, /turf/open/space/basic, /area/space/nearstation) +"gkg" = ( +/obj/effect/decal/cleanable/rubble, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating, +/area/station/cargo/miningoffice) "gkt" = ( /obj/effect/turf_decal/tile/red/half/contrasted{ dir = 1 @@ -18066,6 +17977,12 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/cargo/sorting) +"gpp" = ( +/obj/effect/spawner/structure/window/hollow/reinforced/end{ + dir = 4 + }, +/turf/open/floor/plating, +/area/station/science/genetics) "gpy" = ( /obj/structure/chair/pew/right{ dir = 4 @@ -18182,12 +18099,6 @@ /obj/machinery/camera/autoname/directional/west, /turf/open/floor/iron/dark, /area/station/service/bar) -"grl" = ( -/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/white, -/area/station/science/lobby) "grm" = ( /obj/machinery/door/poddoor/shutters/window{ dir = 4; @@ -18560,6 +18471,10 @@ }, /turf/open/floor/iron/dark, /area/station/medical/treatment_center) +"gwQ" = ( +/obj/structure/stairs/east, +/turf/open/floor/iron/white/smooth_large, +/area/station/science/lobby) "gwS" = ( /obj/structure/cable, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ @@ -18737,11 +18652,6 @@ /obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) -"gzr" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/item/food/grown/banana, -/turf/open/floor/grass, -/area/station/science/genetics) "gzt" = ( /obj/effect/turf_decal/tile/yellow/diagonal_centre, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ @@ -19054,16 +18964,6 @@ /obj/machinery/light_switch/directional/north, /turf/open/floor/iron, /area/station/cargo/miningoffice) -"gFg" = ( -/obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/siding/purple{ - dir = 8 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 1 - }, -/turf/open/floor/iron/white/textured_large, -/area/station/science/genetics) "gFB" = ( /obj/structure/cable, /obj/machinery/door/airlock/atmos/glass{ @@ -19343,6 +19243,10 @@ /mob/living/basic/butterfly, /turf/open/misc/grass, /area/station/ai/satellite/foyer) +"gJn" = ( +/obj/machinery/rnd/experimentor, +/turf/open/floor/engine, +/area/station/science/explab) "gJA" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -19388,9 +19292,6 @@ }, /turf/open/floor/plating, /area/station/service/chapel/funeral) -"gKt" = ( -/turf/closed/wall, -/area/station/science/auxlab/firing_range) "gKu" = ( /obj/machinery/atmospherics/pipe/smart/simple/purple/visible, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -19628,30 +19529,6 @@ dir = 1 }, /area/station/science/research) -"gOB" = ( -/obj/structure/table, -/obj/item/storage/box/monkeycubes{ - pixel_x = 4 - }, -/obj/item/storage/box/monkeycubes{ - pixel_x = 6; - pixel_y = 9 - }, -/obj/item/storage/pill_bottle/mutadone{ - pixel_x = -9 - }, -/obj/machinery/airalarm/directional/north, -/obj/effect/turf_decal/siding/purple/corner{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/item/flesh_shears{ - pixel_x = -5; - pixel_y = 10 - }, -/turf/open/floor/iron/white/textured, -/area/station/science/genetics) "gOY" = ( /turf/closed/wall/r_wall, /area/station/science/ordnance) @@ -19797,10 +19674,6 @@ /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/iron/white, /area/station/medical/chemistry/minisat) -"gSY" = ( -/obj/item/target/syndicate, -/turf/open/floor/engine, -/area/station/science/explab) "gTe" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible, /obj/effect/turf_decal/stripes{ @@ -20156,9 +20029,6 @@ "gYW" = ( /turf/closed/wall, /area/station/maintenance/central/greater) -"gYY" = ( -/turf/closed/wall, -/area/station/science/genetics) "gZc" = ( /obj/machinery/camera/directional/south{ c_tag = "Atmospherics Tank - Air" @@ -20343,6 +20213,11 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/iron/white, /area/station/medical/treatment_center) +"hbp" = ( +/obj/effect/turf_decal/tile/purple/opposingcorners, +/obj/structure/cable, +/turf/open/floor/iron/white, +/area/station/science/auxlab/firing_range) "hbq" = ( /obj/item/extinguisher, /obj/effect/decal/cleanable/dirt, @@ -20351,13 +20226,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/department/engine) -"hbr" = ( -/obj/effect/turf_decal/siding/white{ - dir = 6 - }, -/obj/effect/decal/cleanable/blood/tracks, -/turf/open/floor/iron/white/small, -/area/station/science/lobby) "hbw" = ( /obj/effect/spawner/structure/window, /turf/open/floor/plating, @@ -20870,17 +20738,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/wood, /area/station/service/library) -"hle" = ( -/obj/machinery/light/directional/south, -/obj/structure/table/glass, -/obj/item/stack/sheet/glass, -/obj/item/assembly/timer, -/obj/effect/turf_decal/tile/purple/half/contrasted, -/obj/structure/disposalpipe/segment{ - dir = 8 - }, -/turf/open/floor/iron/white, -/area/station/science/lobby) "hlh" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/disposalpipe/segment{ @@ -21492,6 +21349,10 @@ /obj/machinery/camera/autoname/directional/south, /turf/open/floor/iron, /area/station/maintenance/disposal/incinerator) +"huG" = ( +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating, +/area/station/cargo/miningoffice) "huK" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/wood/parquet, @@ -21785,6 +21646,11 @@ dir = 1 }, /area/station/service/chapel) +"hBd" = ( +/turf/closed/mineral/random/stationside/asteroid/porus{ + mineral_chance = 20 + }, +/area/station/maintenance/disposal/incinerator) "hBi" = ( /obj/structure/reagent_dispensers/watertank, /obj/effect/turf_decal/tile/yellow/half/contrasted{ @@ -22346,6 +22212,18 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/command/bridge) +"hLJ" = ( +/obj/effect/turf_decal/siding/purple{ + dir = 8 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/turf/open/floor/iron/white/textured, +/area/station/science/genetics) "hLP" = ( /obj/machinery/camera/autoname/directional/east{ network = list("ss13","rd","xeno") @@ -22445,6 +22323,22 @@ /obj/effect/mapping_helpers/airlock/access/all/command/general, /turf/open/floor/iron/dark/side, /area/station/command/bridge) +"hOh" = ( +/obj/structure/table/glass, +/obj/item/folder/white{ + pixel_x = 4; + pixel_y = -3 + }, +/obj/item/book/manual/wiki/infections, +/obj/effect/turf_decal/tile/green/half/contrasted{ + dir = 8 + }, +/obj/item/tgui_book/manual/idc{ + pixel_y = 2; + pixel_x = 3 + }, +/turf/open/floor/iron/white, +/area/station/medical/virology) "hOn" = ( /obj/structure/closet/emcloset, /obj/structure/sign/poster/official/random/directional/east, @@ -22455,6 +22349,14 @@ /obj/item/kitchen/rollingpin, /turf/open/floor/iron/kitchen, /area/station/service/kitchen) +"hOJ" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + dir = 8; + id = "geneshut" + }, +/turf/open/floor/plating, +/area/station/science/genetics) "hOR" = ( /obj/structure/stairs/east, /turf/open/floor/iron/stairs, @@ -23024,6 +22926,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/wood/tile, /area/station/service/bar) +"hWM" = ( +/obj/effect/landmark/start/geneticist, +/obj/structure/chair/office, +/obj/structure/cable, +/obj/effect/turf_decal/siding/purple/corner{ + dir = 4 + }, +/turf/open/floor/iron/white/textured, +/area/station/science/genetics) "hWW" = ( /obj/structure/cable, /obj/effect/landmark/start/atmospheric_technician, @@ -23154,11 +23065,6 @@ }, /turf/open/floor/iron/dark, /area/station/engineering/circuit_workshop) -"hZJ" = ( -/obj/effect/spawner/random/entertainment/slot_machine, -/obj/effect/decal/cleanable/dirt/dust, -/turf/open/floor/iron/grimy, -/area/station/maintenance/central/lesser) "hZM" = ( /obj/machinery/light/cold/directional/west, /turf/open/floor/iron/dark, @@ -23195,6 +23101,11 @@ /obj/structure/sign/poster/contraband/random/directional/south, /turf/open/floor/iron, /area/station/maintenance/department/medical/central) +"iaA" = ( +/turf/closed/mineral/random/stationside/asteroid/porus{ + mineral_chance = 20 + }, +/area/station/hallway/secondary/entry) "iaI" = ( /obj/structure/railing{ dir = 10 @@ -23399,15 +23310,6 @@ /obj/item/grown/bananapeel, /turf/open/floor/plating, /area/station/maintenance/department/engine) -"iee" = ( -/obj/machinery/bouldertech/refinery/smelter, -/obj/machinery/conveyor{ - dir = 6; - id = "brm" - }, -/obj/effect/turf_decal/sand/plating, -/turf/open/floor/plating, -/area/station/cargo/miningoffice) "ief" = ( /obj/machinery/airalarm/directional/west, /obj/machinery/portable_atmospherics/canister/oxygen, @@ -23642,6 +23544,13 @@ /obj/structure/cable/layer1, /turf/open/floor/iron, /area/station/engineering/main) +"iiA" = ( +/obj/effect/turf_decal/siding/purple{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/white/textured_large, +/area/station/science/genetics) "iiB" = ( /obj/structure/lattice, /obj/structure/cable, @@ -23736,6 +23645,12 @@ /obj/effect/turf_decal/tile/red/diagonal_edge, /turf/open/floor/iron/dark, /area/station/security/warden) +"ilc" = ( +/obj/effect/turf_decal/siding/white, +/obj/item/ammo_casing/c357/spent, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/white/small, +/area/station/science/lobby) "ili" = ( /obj/structure/transit_tube/curved/flipped{ dir = 1 @@ -23748,11 +23663,6 @@ /obj/effect/spawner/random/structure/closet_empty/crate/with_loot, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) -"ilp" = ( -/turf/closed/mineral/random/stationside/asteroid/porus{ - mineralChance = 20 - }, -/area/station/maintenance/department/science) "ilq" = ( /obj/structure/transport/linear/public, /obj/machinery/holopad, @@ -23762,13 +23672,6 @@ /obj/machinery/smartfridge/organ, /turf/open/floor/plating, /area/station/medical/morgue) -"ilO" = ( -/obj/effect/decal/cleanable/rubble, -/obj/structure/railing{ - dir = 1 - }, -/turf/open/misc/asteroid, -/area/station/cargo/miningoffice) "ilQ" = ( /obj/structure/railing, /obj/machinery/door/firedoor/border_only, @@ -23874,6 +23777,14 @@ dir = 8 }, /area/station/medical/pharmacy) +"inD" = ( +/obj/effect/turf_decal/tile/purple/half/contrasted{ + dir = 1 + }, +/obj/machinery/power/apc/auto_name/directional/north, +/obj/structure/cable, +/turf/open/floor/iron/white, +/area/station/science/lobby) "ioa" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden, @@ -24052,25 +23963,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/hallway/primary/central) -"irf" = ( -/obj/structure/ladder, -/obj/structure/window/reinforced/spawner/directional/east{ - pixel_x = 3 - }, -/obj/machinery/door/window/brigdoor/left/directional/south{ - name = "Monkey Pen"; - pixel_y = -3; - req_one_access = list("genetics") - }, -/obj/machinery/camera/autoname/directional/west{ - network = list("ss13","rd") - }, -/obj/effect/turf_decal/siding/purple/corner, -/obj/structure/sign/poster/random/directional/north, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/white/textured, -/area/station/science/genetics) "irx" = ( /obj/structure/chair/sofa/bench/right{ dir = 4 @@ -24211,19 +24103,6 @@ }, /turf/open/space/basic, /area/space/nearstation) -"itV" = ( -/obj/structure/railing/corner{ - dir = 8 - }, -/obj/effect/turf_decal/siding/purple/corner{ - dir = 1 - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/door/firedoor/border_only, -/turf/open/floor/iron/white/textured, -/area/station/science/genetics) "iua" = ( /obj/machinery/door/airlock/external, /obj/effect/mapping_helpers/airlock/cyclelink_helper, @@ -24541,17 +24420,6 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/wood/tile, /area/station/service/bar) -"izV" = ( -/obj/effect/mapping_helpers/airlock/access/all/science/general, -/obj/machinery/door/airlock/science/glass, -/obj/effect/mapping_helpers/airlock/autoname, -/obj/structure/cable, -/obj/machinery/door/firedoor, -/obj/effect/turf_decal/tile/purple/opposingcorners, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/white, -/area/station/science/auxlab/firing_range) "iAE" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -25127,15 +24995,6 @@ }, /turf/open/floor/iron/dark, /area/station/ai/satellite/foyer) -"iJS" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/white, -/area/station/science/research) "iJT" = ( /obj/structure/cable, /obj/machinery/power/apc/auto_name/directional/south, @@ -25636,6 +25495,17 @@ /obj/effect/spawner/random/structure/grille, /turf/open/space/basic, /area/space/nearstation) +"iUH" = ( +/obj/machinery/disposal/bin, +/obj/machinery/button/door/directional/east{ + id = "geneshut"; + name = "Genetics Shutters" + }, +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, +/turf/open/floor/iron/white/textured, +/area/station/science/genetics) "iUP" = ( /obj/structure/railing/corner{ dir = 1 @@ -25732,6 +25602,21 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/cargo/miningoffice) +"iWx" = ( +/obj/machinery/door/airlock/medical{ + name = "Surgery" + }, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/access/any/medical/surgery, +/obj/effect/turf_decal/tile/blue/fourcorners, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/mapping_helpers/airlock/unres/delayed{ + dir = 8 + }, +/turf/open/floor/iron/white/smooth_large, +/area/station/medical/surgery) "iWO" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -25770,9 +25655,6 @@ /obj/effect/turf_decal/sand/plating, /turf/open/floor/plating, /area/station/maintenance/department/science) -"iXv" = ( -/turf/open/floor/glass/reinforced, -/area/station/science/genetics) "iXx" = ( /obj/structure/railing/corner{ dir = 8 @@ -25869,6 +25751,11 @@ /obj/structure/lattice, /turf/open/openspace, /area/station/hallway/primary/central) +"iZR" = ( +/turf/closed/mineral/random/stationside/asteroid/porus{ + mineral_chance = 20 + }, +/area/station/maintenance/department/science) "iZW" = ( /obj/effect/turf_decal/siding/purple{ dir = 1 @@ -26345,12 +26232,6 @@ /obj/docking_port/stationary/syndicate, /turf/open/space/openspace, /area/space) -"jjp" = ( -/obj/item/reagent_containers/cup/bottle/fake_gbs, -/turf/closed/mineral/random/stationside/asteroid/porus{ - mineralChance = 20 - }, -/area/station/asteroid) "jjF" = ( /obj/effect/turf_decal/siding/wood{ dir = 9 @@ -26651,10 +26532,12 @@ }, /turf/open/floor/wood/tile, /area/station/service/bar) -"jnw" = ( -/obj/machinery/light/small/directional/south, -/turf/open/floor/engine, -/area/station/science/auxlab/firing_range) +"jnA" = ( +/obj/effect/spawner/structure/window/hollow/reinforced/middle{ + dir = 4 + }, +/turf/open/floor/plating, +/area/station/science/genetics) "jnE" = ( /obj/structure/table, /obj/item/binoculars, @@ -26826,19 +26709,6 @@ /obj/item/food/sandwich/philly_cheesesteak, /turf/open/floor/carpet/red, /area/station/command/heads_quarters/hos) -"jqf" = ( -/obj/structure/railing{ - dir = 5 - }, -/obj/machinery/door/firedoor/border_only{ - dir = 4 - }, -/obj/machinery/door/firedoor/border_only{ - dir = 1 - }, -/obj/effect/landmark/firealarm_sanity, -/turf/open/floor/catwalk_floor/iron_white, -/area/station/science/lobby) "jqj" = ( /obj/effect/turf_decal/tile/neutral{ dir = 4 @@ -27106,6 +26976,12 @@ }, /turf/open/floor/iron/textured_large, /area/station/medical/treatment_center) +"jvx" = ( +/obj/structure/sign/warning/directional/north, +/turf/closed/mineral/random/stationside/asteroid/porus{ + mineral_chance = 20 + }, +/area/station/asteroid) "jvA" = ( /obj/machinery/atmospherics/pipe/smart/simple/green/visible{ dir = 10 @@ -27492,6 +27368,18 @@ }, /turf/open/floor/plating, /area/station/maintenance/department/science) +"jBR" = ( +/obj/structure/window/reinforced/spawner/directional/east{ + pixel_x = 3 + }, +/obj/machinery/camera/autoname/directional/west{ + network = list("ss13","rd") + }, +/obj/structure/sign/poster/random/directional/north, +/obj/machinery/dna_infuser, +/obj/item/tgui_book/manual/infuser, +/turf/open/floor/iron/white/textured, +/area/station/science/genetics) "jBX" = ( /obj/effect/turf_decal/stripes{ dir = 8 @@ -27500,14 +27388,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible, /turf/open/floor/engine, /area/station/engineering/supermatter/room) -"jCg" = ( -/obj/machinery/computer/dna_console, -/obj/machinery/light_switch/directional/north, -/obj/effect/turf_decal/siding/purple, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/white/textured, -/area/station/science/genetics) "jCm" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/layer2{ dir = 8 @@ -27539,6 +27419,15 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central) +"jCy" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/iron/white, +/area/station/science/research) "jCD" = ( /turf/closed/wall, /area/station/security/detectives_office/private_investigators_office) @@ -27569,18 +27458,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/catwalk_floor/iron_white, /area/station/hallway/secondary/entry) -"jCT" = ( -/obj/structure/cable, -/obj/effect/turf_decal/siding/purple{ - dir = 4 - }, -/obj/structure/disposalpipe/segment{ - dir = 10 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/white/textured, -/area/station/science/genetics) "jCU" = ( /obj/structure/closet/crate/freezer, /obj/item/reagent_containers/blood/random, @@ -28145,6 +28022,15 @@ /obj/effect/turf_decal/siding/wood, /turf/open/floor/wood/parquet, /area/station/service/theater) +"jLN" = ( +/obj/structure/lattice/catwalk, +/obj/structure/railing{ + dir = 5; + pixel_y = 0; + pixel_x = 4 + }, +/turf/open/openspace, +/area/station/science/lobby) "jLV" = ( /obj/effect/decal/cleanable/dirt/dust, /obj/effect/decal/cleanable/blood/old{ @@ -28780,9 +28666,6 @@ dir = 1 }, /area/station/engineering/atmos/pumproom) -"jXb" = ( -/turf/open/floor/iron/white/textured_large, -/area/station/science/genetics) "jXC" = ( /obj/machinery/light/dim/directional/west, /obj/effect/turf_decal/tile/dark_blue/half/contrasted{ @@ -29991,12 +29874,6 @@ /obj/structure/broken_flooring/pile, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) -"kpe" = ( -/obj/structure/closet/l3closet/janitor, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/camera/autoname/directional/north, -/turf/open/floor/iron, -/area/station/service/janitor) "kpj" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -30170,10 +30047,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/cargo/warehouse/upper) -"krg" = ( -/obj/structure/training_machine, -/turf/open/floor/engine, -/area/station/science/explab) "kri" = ( /obj/effect/turf_decal/siding/purple{ dir = 1 @@ -30368,24 +30241,10 @@ /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/iron, /area/station/service/cafeteria) -"kuX" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "geneshut" - }, -/turf/open/floor/plating, -/area/station/science/genetics) "kvd" = ( /obj/structure/lattice/catwalk, /turf/open/openspace/xenobio, /area/station/science/xenobiology) -"kvj" = ( -/obj/machinery/light/directional/north, -/obj/structure/table, -/obj/effect/turf_decal/tile/purple/opposingcorners, -/obj/item/storage/toolbox/mechanical, -/turf/open/floor/iron/white, -/area/station/science/auxlab/firing_range) "kvk" = ( /obj/structure/table, /obj/machinery/fax{ @@ -30808,6 +30667,11 @@ dir = 1 }, /area/station/medical/pharmacy) +"kCo" = ( +/obj/structure/window/reinforced/spawner/directional/west, +/obj/item/target/syndicate, +/turf/open/floor/engine, +/area/station/science/auxlab/firing_range) "kCr" = ( /obj/structure/rack, /obj/effect/spawner/random/maintenance, @@ -31747,6 +31611,23 @@ dir = 5 }, /area/station/command/corporate_dock) +"kTs" = ( +/obj/machinery/door/airlock/medical{ + name = "Primary Surgical Theatre" + }, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/blue/fourcorners, +/obj/effect/mapping_helpers/airlock/access/all/medical/surgery, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/mapping_helpers/airlock/unres/delayed{ + dir = 8 + }, +/turf/open/floor/iron/white, +/area/station/medical/surgery/theatre) "kTx" = ( /obj/effect/landmark/atmospheric_sanity/ignore_area, /turf/closed/wall/r_wall, @@ -32338,6 +32219,12 @@ }, /turf/open/floor/plating, /area/station/hallway/secondary/entry) +"ldy" = ( +/obj/item/reagent_containers/cup/bottle/fake_gbs, +/turf/closed/mineral/random/stationside/asteroid/porus{ + mineral_chance = 20 + }, +/area/station/asteroid) "ldT" = ( /obj/machinery/portable_atmospherics/pump, /turf/open/floor/plating, @@ -32450,19 +32337,6 @@ /obj/effect/spawner/random/decoration/material, /turf/open/floor/catwalk_floor/iron_dark, /area/station/maintenance/aft/upper) -"lfF" = ( -/obj/effect/turf_decal/tile/blue/half/contrasted{ - dir = 1 - }, -/obj/structure/table, -/obj/item/stack/medical/wrap/gauze, -/obj/item/stack/medical/suture, -/obj/item/stack/medical/mesh, -/obj/machinery/power/apc/auto_name/directional/north, -/obj/structure/cable, -/obj/effect/spawner/random/medical/minor_healing, -/turf/open/floor/iron/white, -/area/station/medical/medbay/lobby) "lfG" = ( /obj/machinery/atmospherics/pipe/smart/simple/green/visible{ dir = 8 @@ -32512,13 +32386,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/security/brig) -"lgK" = ( -/obj/structure/lattice/catwalk, -/obj/structure/railing{ - dir = 8 - }, -/turf/open/openspace, -/area/station/science/genetics) "lgL" = ( /mob/living/carbon/human/species/monkey/angry, /turf/open/misc/asteroid, @@ -32829,6 +32696,21 @@ }, /turf/open/floor/iron/white, /area/station/medical/patients_rooms/room_b) +"lnX" = ( +/obj/structure/cable, +/obj/structure/railing{ + dir = 4 + }, +/obj/machinery/door/firedoor/border_only{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/open/floor/iron/white, +/area/station/science/research) "lnZ" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/structure/table, @@ -32984,6 +32866,12 @@ /obj/structure/extinguisher_cabinet/directional/east, /turf/open/floor/iron/dark, /area/station/engineering/atmospherics_engine) +"lqd" = ( +/obj/effect/spawner/structure/window/hollow/reinforced/end{ + dir = 8 + }, +/turf/open/floor/plating, +/area/station/science/genetics) "lqf" = ( /obj/effect/decal/cleanable/dirt/dust, /obj/effect/spawner/random/maintenance, @@ -33151,12 +33039,6 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) -"ltY" = ( -/obj/effect/spawner/random/entertainment/slot_machine, -/obj/effect/decal/cleanable/dirt/dust, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron/grimy, -/area/station/maintenance/central/lesser) "luq" = ( /obj/effect/turf_decal/stripes{ dir = 4 @@ -33206,6 +33088,11 @@ /obj/machinery/camera/autoname/directional/south, /turf/open/floor/iron/cafeteria, /area/station/commons/locker) +"luS" = ( +/obj/effect/turf_decal/sand/plating, +/obj/machinery/light/small/directional/north, +/turf/open/floor/plating, +/area/station/cargo/miningoffice) "luW" = ( /obj/machinery/door/airlock/grunge{ name = "Chapel" @@ -33791,11 +33678,6 @@ /obj/machinery/airalarm/directional/west, /turf/open/floor/iron/white, /area/station/security/medical) -"lDQ" = ( -/turf/closed/mineral/random/stationside/asteroid/porus{ - mineralChance = 20 - }, -/area/station/hallway/secondary/entry) "lDZ" = ( /obj/machinery/door/airlock/maintenance, /obj/effect/mapping_helpers/airlock/unres/delayed, @@ -33953,6 +33835,11 @@ }, /turf/open/floor/plating, /area/station/maintenance/department/medical) +"lGl" = ( +/obj/machinery/dna_scannernew, +/obj/machinery/firealarm/directional/north, +/turf/open/floor/iron/white/textured, +/area/station/science/genetics) "lGt" = ( /obj/machinery/atmospherics/pipe/smart/manifold/green/visible, /turf/open/floor/iron, @@ -34131,10 +34018,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/exam_room) -"lKk" = ( -/obj/machinery/light/small/dim/directional/west, -/turf/open/misc/asteroid, -/area/station/maintenance/department/science) "lKp" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -34853,10 +34736,6 @@ /mob/living/basic/slime, /turf/open/floor/engine, /area/station/science/xenobiology) -"lXz" = ( -/obj/machinery/atmospherics/pipe/multiz/scrubbers/visible/layer2, -/turf/open/floor/grass, -/area/station/science/genetics) "lXE" = ( /obj/effect/turf_decal/tile/yellow{ dir = 4 @@ -35040,6 +34919,11 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron/white, /area/station/medical/treatment_center) +"lZW" = ( +/turf/closed/mineral/random/stationside/asteroid/porus{ + mineral_chance = 20 + }, +/area/station/maintenance/department/medical) "mam" = ( /obj/structure/closet/secure_closet/personal, /obj/machinery/power/apc/auto_name/directional/east, @@ -35727,6 +35611,12 @@ /mob/living/carbon/human/species/monkey, /turf/open/floor/grass, /area/station/science/genetics) +"mmX" = ( +/obj/effect/turf_decal/bot, +/mob/living/basic/bot/secbot/beepsky/armsky, +/obj/effect/landmark/event_spawn, +/turf/open/floor/iron/dark/textured_large, +/area/station/security/armory) "mna" = ( /obj/structure/tank_dispenser, /obj/machinery/firealarm/directional/west, @@ -35940,14 +35830,6 @@ /obj/structure/sign/departments/chemistry/directional/west, /turf/open/floor/iron/white, /area/station/medical/chemistry) -"mqm" = ( -/obj/machinery/camera/autoname/directional/south, -/obj/machinery/airalarm/directional/south, -/obj/effect/spawner/random/entertainment/slot_machine{ - pixel_y = 2 - }, -/turf/open/floor/wood, -/area/station/commons/lounge) "mqz" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/power/apc/auto_name/directional/east, @@ -35968,22 +35850,6 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos) -"mqG" = ( -/obj/structure/table/reinforced/rglass, -/obj/effect/turf_decal/tile/blue/fourcorners, -/obj/item/book/manual/wiki/medicine, -/obj/item/tgui_book/manual/dsm{ - pixel_y = 3; - pixel_x = 3 - }, -/obj/item/tgui_book/manual/idc{ - pixel_y = 7 - }, -/obj/item/clothing/neck/stethoscope{ - pixel_y = 4 - }, -/turf/open/floor/iron/white, -/area/station/medical/treatment_center) "mqH" = ( /obj/structure/cable, /obj/effect/turf_decal/trimline/yellow/filled/line{ @@ -36217,6 +36083,20 @@ }, /turf/open/openspace, /area/station/engineering/main) +"muE" = ( +/obj/structure/table/glass, +/obj/item/radio/intercom/directional/south, +/obj/item/tgui_book/manual/dsm{ + pixel_x = -6; + pixel_y = 4 + }, +/obj/item/tgui_book/manual/idc{ + pixel_y = 2; + pixel_x = 3 + }, +/obj/item/food/sandwich/cheese, +/turf/open/floor/iron/dark/textured, +/area/station/command/heads_quarters/cmo) "muL" = ( /obj/machinery/door/airlock/maintenance, /obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance, @@ -36416,10 +36296,6 @@ "mxq" = ( /turf/closed/wall, /area/station/maintenance/disposal) -"mxs" = ( -/obj/item/radio/intercom/directional/north, -/turf/open/floor/grass, -/area/station/science/genetics) "mxt" = ( /obj/structure/lattice/catwalk, /turf/open/space/openspace, @@ -36871,6 +36747,12 @@ "mGG" = ( /turf/closed/wall, /area/station/security/breakroom) +"mGL" = ( +/obj/effect/turf_decal/siding/white, +/obj/item/ammo_casing/c357/spent, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, +/turf/open/floor/iron/white/small, +/area/station/science/lobby) "mGM" = ( /obj/effect/turf_decal/sand/plating, /obj/structure/reagent_dispensers/fueltank, @@ -37114,6 +36996,12 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/wood/tile, /area/station/service/bar) +"mKg" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 1 + }, +/turf/open/floor/glass/reinforced, +/area/station/science/genetics) "mKo" = ( /obj/structure/railing{ dir = 5 @@ -37510,6 +37398,13 @@ /obj/item/clothing/head/fedora, /turf/open/floor/wood, /area/station/commons/lounge) +"mSn" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating, +/area/station/cargo/miningoffice) "mSr" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -37638,6 +37533,22 @@ }, /turf/open/floor/iron/white, /area/station/maintenance/department/medical) +"mUB" = ( +/obj/structure/table/reinforced/rglass, +/obj/effect/turf_decal/tile/blue/fourcorners, +/obj/item/book/manual/wiki/medicine, +/obj/item/tgui_book/manual/dsm{ + pixel_y = 3; + pixel_x = 3 + }, +/obj/item/tgui_book/manual/idc{ + pixel_y = 7 + }, +/obj/item/clothing/neck/stethoscope{ + pixel_y = 4 + }, +/turf/open/floor/iron/white, +/area/station/medical/treatment_center) "mUF" = ( /obj/effect/turf_decal/tile/yellow{ dir = 8 @@ -37869,13 +37780,6 @@ /obj/machinery/telecomms/server/presets/service, /turf/open/floor/circuit/green/telecomms/mainframe, /area/station/tcommsat/server) -"mYN" = ( -/obj/structure/cable, -/obj/effect/turf_decal/tile/purple/opposingcorners, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/white, -/area/station/science/auxlab/firing_range) "mYU" = ( /obj/machinery/requests_console/directional/west{ department = "Hydroponics"; @@ -38461,15 +38365,6 @@ dir = 10 }, /area/station/maintenance/radshelter/medical) -"nhf" = ( -/obj/machinery/computer/records/medical/laptop{ - dir = 8; - pixel_y = 1 - }, -/obj/structure/table, -/obj/machinery/light/dim/directional/east, -/turf/open/floor/iron/white/textured, -/area/station/science/genetics) "nhk" = ( /obj/effect/mapping_helpers/broken_floor, /obj/machinery/space_heater, @@ -38533,12 +38428,6 @@ /obj/machinery/computer/cargo, /turf/open/floor/iron, /area/station/cargo/storage) -"nje" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 1 - }, -/turf/open/floor/iron/white/textured_large, -/area/station/science/genetics) "njr" = ( /obj/structure/closet/crate/freezer, /obj/item/food/breadslice/plain, @@ -38699,10 +38588,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/white/smooth_large, /area/station/science/research) -"nmj" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/white, -/area/station/science/research) "nmq" = ( /obj/effect/turf_decal/tile/yellow{ dir = 8 @@ -39073,15 +38958,6 @@ /obj/machinery/light/small/directional/east, /turf/open/floor/carpet, /area/station/commons/dorms) -"nuu" = ( -/obj/machinery/bouldertech/refinery, -/obj/machinery/conveyor{ - dir = 4; - id = "brm" - }, -/obj/effect/turf_decal/sand/plating, -/turf/open/floor/plating, -/area/station/cargo/miningoffice) "nuC" = ( /obj/effect/turf_decal/tile/brown/anticorner/contrasted, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -39090,12 +38966,6 @@ }, /turf/open/floor/iron, /area/station/cargo/sorting) -"nuH" = ( -/obj/structure/sign/warning/directional/west, -/turf/closed/mineral/random/stationside/asteroid/porus{ - mineralChance = 20 - }, -/area/station/asteroid) "nuM" = ( /obj/machinery/door/airlock/public/glass{ name = "Courtroom" @@ -39217,15 +39087,6 @@ /obj/machinery/light/directional/west, /turf/open/floor/engine, /area/station/engineering/supermatter/room) -"nxd" = ( -/obj/structure/rack, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/turf_decal/sand/plating, -/obj/item/storage/box/bandages, -/turf/open/floor/plating, -/area/station/cargo/miningoffice) "nxv" = ( /obj/effect/turf_decal/tile/yellow{ dir = 4 @@ -39321,6 +39182,11 @@ "nzk" = ( /turf/closed/wall/r_wall, /area/station/maintenance/central/greater) +"nzw" = ( +/obj/effect/spawner/random/entertainment/slot_machine, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating, +/area/station/maintenance/central/greater) "nzC" = ( /obj/effect/decal/cleanable/dirt/dust, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -39527,6 +39393,17 @@ /obj/structure/window/reinforced/spawner/directional/north, /turf/open/space/openspace, /area/space/nearstation) +"nCU" = ( +/obj/structure/chair/sofa/bench{ + dir = 4 + }, +/obj/effect/turf_decal/tile/purple/half/contrasted{ + dir = 8 + }, +/obj/machinery/camera/autoname/directional/west, +/obj/machinery/airalarm/directional/west, +/turf/open/floor/iron/white, +/area/station/science/lobby) "nDC" = ( /obj/machinery/holopad, /turf/open/floor/circuit/green/telecomms/mainframe, @@ -39738,22 +39615,6 @@ /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/plating, /area/station/maintenance/department/bridge) -"nIu" = ( -/obj/machinery/door/airlock/research, -/obj/effect/turf_decal/siding/purple{ - dir = 4 - }, -/obj/structure/cable, -/obj/effect/mapping_helpers/airlock/access/all/science/genetics, -/obj/machinery/door/firedoor, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/mapping_helpers/airlock/autoname, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/white/textured, -/area/station/science/genetics) "nID" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/cable, @@ -39983,6 +39844,18 @@ /obj/structure/extinguisher_cabinet/directional/north, /turf/open/floor/iron, /area/station/engineering/gravity_generator) +"nLt" = ( +/obj/structure/table, +/obj/item/paper_bin{ + pixel_x = -1; + pixel_y = 5 + }, +/obj/item/pen{ + pixel_x = 0; + pixel_y = 4 + }, +/turf/open/floor/glass/reinforced, +/area/station/science/genetics) "nLz" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -40004,13 +39877,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/security/lockers) -"nLJ" = ( -/obj/effect/spawner/random/entertainment/slot_machine, -/obj/effect/decal/cleanable/dirt/dust, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/light/small/directional/west, -/turf/open/floor/iron/grimy, -/area/station/maintenance/central/lesser) "nLT" = ( /obj/machinery/light/small/directional/north, /obj/structure/flora/rock/pile/style_random, @@ -40178,6 +40044,12 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron/dark, /area/station/medical/paramedic) +"nOH" = ( +/obj/effect/turf_decal/tile/purple/opposingcorners, +/obj/structure/cable, +/obj/machinery/power/apc/auto_name/directional/south, +/turf/open/floor/iron/white, +/area/station/science/auxlab/firing_range) "nOZ" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 4 @@ -40249,6 +40121,12 @@ }, /turf/open/floor/carpet/royalblue, /area/station/service/library) +"nQS" = ( +/obj/structure/sign/warning/directional/west, +/turf/closed/mineral/random/stationside/asteroid/porus{ + mineral_chance = 20 + }, +/area/station/asteroid) "nQT" = ( /obj/item/flashlight/flare{ icon_state = "flare-on"; @@ -40918,12 +40796,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/central/greater) -"oft" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 1 - }, -/turf/open/floor/grass, -/area/station/science/genetics) "ofx" = ( /obj/structure/chair/stool/directional/north, /obj/effect/landmark/start/atmospheric_technician, @@ -40979,6 +40851,21 @@ /obj/structure/railing/corner, /turf/open/floor/iron/dark/textured_large, /area/station/science/xenobiology) +"ogZ" = ( +/obj/machinery/door/airlock/medical{ + id_tag = "r2"; + name = "Room B" + }, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/blue/fourcorners, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/effect/mapping_helpers/airlock/access/any/medical/general, +/obj/effect/mapping_helpers/airlock/unres/delayed{ + dir = 4 + }, +/turf/open/floor/iron/white, +/area/station/medical/patients_rooms/room_b) "ohe" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 9 @@ -41026,6 +40913,17 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/dark, /area/station/engineering/atmospherics_engine) +"ohI" = ( +/obj/machinery/door/airlock/medical{ + name = "Treatment Centre" + }, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/access/any/medical/general, +/obj/structure/cable, +/obj/structure/disposalpipe/segment, +/obj/effect/mapping_helpers/airlock/unres/delayed, +/turf/open/floor/iron/white, +/area/station/medical/exam_room) "ohZ" = ( /obj/structure/cable, /obj/effect/decal/cleanable/dirt/dust, @@ -41049,6 +40947,10 @@ /obj/item/storage/box/bandages, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) +"oiH" = ( +/obj/structure/lattice/catwalk, +/turf/open/openspace, +/area/station/science/lobby) "ojc" = ( /obj/machinery/atmospherics/components/unary/outlet_injector/monitored/plasma_input, /turf/open/floor/engine/plasma, @@ -41087,19 +40989,6 @@ /obj/effect/turf_decal/tile/blue/fourcorners, /turf/open/floor/catwalk_floor/iron_white, /area/station/medical/treatment_center) -"oka" = ( -/obj/effect/turf_decal/siding/purple{ - dir = 1 - }, -/obj/machinery/door/window/left/directional/north{ - name = "Waiting Room Desk"; - req_access = list("medical") - }, -/obj/machinery/camera/autoname/directional/west{ - network = list("ss13","rd") - }, -/turf/open/floor/engine, -/area/station/science/auxlab/firing_range) "okd" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -41197,6 +41086,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/hallway/primary/central) +"olC" = ( +/obj/effect/spawner/random/entertainment/slot_machine, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/small/directional/west, +/turf/open/floor/iron/grimy, +/area/station/maintenance/central/lesser) "olE" = ( /turf/open/floor/iron/white/smooth_corner, /area/station/science/xenobiology) @@ -41873,13 +41769,6 @@ /obj/effect/spawner/random/maintenance, /turf/open/floor/plating, /area/station/maintenance/department/bridge) -"oAs" = ( -/obj/structure/lattice/catwalk, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 8 - }, -/turf/open/openspace, -/area/station/science/lobby) "oAt" = ( /obj/effect/turf_decal/tile/yellow{ dir = 8 @@ -41909,6 +41798,9 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/dark, /area/station/engineering/atmospherics_engine) +"oAL" = ( +/turf/open/floor/catwalk_floor/iron_white, +/area/station/science/lobby) "oAO" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold/scrubbers/visible, @@ -41938,10 +41830,6 @@ }, /turf/open/floor/iron/white/herringbone, /area/station/science/breakroom) -"oAX" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/grass, -/area/station/science/genetics) "oAY" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -42659,6 +42547,12 @@ "oMn" = ( /turf/open/floor/iron/grimy, /area/station/maintenance/central/greater) +"oMq" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 1 + }, +/turf/open/floor/glass/reinforced, +/area/station/science/genetics) "oMr" = ( /obj/machinery/door/airlock/public/glass, /obj/structure/cable, @@ -42685,19 +42579,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron/white/smooth_large, /area/station/science/explab) -"oMK" = ( -/obj/machinery/door/airlock/medical{ - name = "Primary Surgical Theatre" - }, -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/access/all/medical/surgery, -/obj/effect/turf_decal/tile/blue/fourcorners, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/mapping_helpers/airlock/unres/delayed{ - dir = 8 - }, -/turf/open/floor/iron/white, -/area/station/medical/surgery/theatre) "oNo" = ( /obj/machinery/camera/autoname/directional/west, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -43284,21 +43165,6 @@ }, /turf/open/floor/iron, /area/station/engineering/main) -"oXa" = ( -/obj/structure/cable, -/obj/structure/railing{ - dir = 1 - }, -/obj/machinery/door/firedoor/border_only{ - dir = 1 - }, -/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/white, -/area/station/science/research) "oXc" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 8 @@ -44541,6 +44407,23 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/department/cargo) +"pts" = ( +/obj/structure/table/reinforced/rglass, +/obj/effect/turf_decal/tile/blue/fourcorners, +/obj/item/reagent_containers/cup/bottle/epinephrine{ + pixel_x = 6; + pixel_y = 9 + }, +/obj/item/storage/box/rxglasses{ + pixel_x = -4; + pixel_y = 8 + }, +/obj/item/stack/medical/wrap/gauze{ + pixel_x = 8 + }, +/obj/item/reagent_containers/syringe, +/turf/open/floor/iron/white, +/area/station/medical/treatment_center) "ptP" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -44695,6 +44578,10 @@ /obj/machinery/status_display/ai/directional/east, /turf/open/floor/carpet/royalblue, /area/station/command/heads_quarters/captain/private) +"pvu" = ( +/obj/structure/training_machine, +/turf/open/floor/engine, +/area/station/science/auxlab/firing_range) "pvy" = ( /obj/structure/window/spawner/directional/north, /turf/open/floor/iron/dark, @@ -45873,6 +45760,13 @@ /obj/machinery/light/small/directional/south, /turf/open/floor/plating, /area/station/maintenance/central/lesser) +"pPW" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 1 + }, +/obj/machinery/camera/autoname/directional/south, +/turf/open/floor/grass, +/area/station/science/genetics) "pPY" = ( /obj/machinery/chem_heater/withbuffer, /obj/effect/turf_decal/bot_red, @@ -45919,12 +45813,6 @@ /obj/machinery/door/firedoor, /turf/open/floor/iron, /area/station/security/checkpoint/engineering) -"pQz" = ( -/obj/effect/turf_decal/siding/purple{ - dir = 8 - }, -/turf/open/floor/iron/white/textured_large, -/area/station/science/genetics) "pQE" = ( /obj/structure/dresser, /obj/machinery/airalarm/directional/east, @@ -46559,6 +46447,22 @@ }, /turf/open/floor/iron/white, /area/station/medical/patients_rooms/room_b) +"qaK" = ( +/obj/structure/table/glass, +/obj/item/assembly/flash/handheld, +/obj/item/assembly/signaler, +/obj/item/electronics/airlock{ + pixel_x = -14 + }, +/obj/effect/turf_decal/tile/purple{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/obj/item/assembly/igniter, +/turf/open/floor/iron/white, +/area/station/science/lobby) "qaO" = ( /obj/effect/turf_decal/tile/neutral, /obj/structure/disposalpipe/segment{ @@ -46663,6 +46567,10 @@ /obj/structure/flora/rock/pile/style_random, /turf/open/misc/asteroid, /area/station/maintenance/department/medical) +"qcX" = ( +/obj/machinery/gizmo/toggle/tucker_tubes, +/turf/open/floor/iron/white, +/area/station/science/explab) "qdc" = ( /obj/effect/turf_decal/siding/wood{ dir = 4 @@ -46800,10 +46708,6 @@ /obj/effect/landmark/firealarm_sanity, /turf/open/openspace, /area/station/science/research) -"qfu" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/white/textured_large, -/area/station/science/genetics) "qfB" = ( /turf/closed/wall, /area/station/medical/pharmacy) @@ -47349,11 +47253,6 @@ /obj/machinery/airalarm/directional/east, /turf/open/floor/plating, /area/station/maintenance/central/lesser) -"qoN" = ( -/turf/closed/mineral/random/stationside/asteroid/porus{ - mineralChance = 20 - }, -/area/station/maintenance/department/medical) "qoO" = ( /obj/structure/window/spawner/directional/south, /turf/open/floor/iron/dark, @@ -47508,6 +47407,20 @@ /obj/item/radio/intercom/directional/west, /turf/open/floor/iron, /area/station/construction/mining/aux_base) +"qro" = ( +/obj/structure/table/glass, +/obj/structure/reagent_dispensers/wall/virusfood/directional/west, +/obj/machinery/reagentgrinder{ + pixel_y = 8 + }, +/obj/effect/turf_decal/tile/green/half/contrasted{ + dir = 8 + }, +/obj/item/stack/sheet/mineral/plasma{ + amount = 3 + }, +/turf/open/floor/iron/white, +/area/station/medical/virology) "qrs" = ( /obj/machinery/door/firedoor/border_only{ dir = 8 @@ -47902,6 +47815,19 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/hallway/secondary/exit/departure_lounge) +"qzm" = ( +/obj/machinery/door/airlock/medical{ + name = "Primary Surgical Theatre" + }, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/access/all/medical/surgery, +/obj/effect/turf_decal/tile/blue/fourcorners, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/mapping_helpers/airlock/unres/delayed{ + dir = 8 + }, +/turf/open/floor/iron/white, +/area/station/medical/surgery/theatre) "qzr" = ( /obj/effect/turf_decal/tile/yellow{ dir = 1 @@ -48229,11 +48155,6 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/iron, /area/station/security) -"qFa" = ( -/obj/effect/turf_decal/siding/white, -/obj/item/ammo_casing/c357/spent, -/turf/open/floor/iron/white/small, -/area/station/science/lobby) "qFj" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/turf_decal/caution/stand_clear, @@ -48562,6 +48483,14 @@ /obj/structure/cable, /turf/open/floor/iron/dark, /area/station/security/lockers) +"qLx" = ( +/obj/machinery/door/poddoor/shutters/preopen{ + dir = 1; + id = "geneshut" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/station/science/genetics) "qMd" = ( /obj/effect/turf_decal/tile/dark_red/opposingcorners, /obj/effect/landmark/start/bartender, @@ -48623,6 +48552,12 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central) +"qNw" = ( +/obj/machinery/computer/dna_console{ + dir = 1 + }, +/turf/open/floor/iron/white/textured, +/area/station/science/genetics) "qNz" = ( /obj/structure/railing{ dir = 1 @@ -48770,12 +48705,6 @@ /obj/structure/lattice, /turf/open/space/openspace, /area/space/nearstation) -"qQr" = ( -/mob/living/carbon/human/species/monkey, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/flora/coconuts, -/turf/open/floor/grass, -/area/station/science/genetics) "qQK" = ( /obj/machinery/light/small/directional/east, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -48878,6 +48807,13 @@ /obj/effect/turf_decal/siding/purple, /turf/open/floor/iron/white, /area/station/science/ordnance/testlab) +"qSv" = ( +/obj/machinery/door/poddoor/shutters/preopen{ + id = "geneshut" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/station/science/genetics) "qSG" = ( /obj/effect/turf_decal/tile/brown/half/contrasted, /obj/structure/cable, @@ -49010,26 +48946,6 @@ }, /turf/open/floor/iron, /area/station/engineering/main) -"qVD" = ( -/obj/structure/railing, -/obj/structure/table, -/obj/item/storage/box/disks{ - pixel_x = 6; - pixel_y = 3 - }, -/obj/item/storage/box/bodybags{ - pixel_x = -4; - pixel_y = 9 - }, -/obj/machinery/door/firedoor/border_only, -/obj/effect/turf_decal/siding/purple{ - dir = 1 - }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/open/floor/iron/white/textured, -/area/station/science/genetics) "qVF" = ( /turf/open/floor/plating/reinforced/airless, /area/station/tcommsat/server) @@ -49220,6 +49136,17 @@ /obj/structure/cable, /turf/open/floor/iron/white, /area/station/hallway/secondary/entry) +"qYf" = ( +/obj/effect/decal/cleanable/rubble, +/obj/structure/railing{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating, +/area/station/cargo/miningoffice) "qYm" = ( /obj/effect/turf_decal/tile/yellow{ dir = 4 @@ -49477,18 +49404,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/commons/vacant_room/commissary) -"rcx" = ( -/obj/structure/cable, -/obj/structure/railing{ - dir = 4 - }, -/obj/machinery/door/firedoor/border_only{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/white, -/area/station/science/research) "rcy" = ( /obj/machinery/light/small/broken/directional/north, /obj/structure/table, @@ -49711,6 +49626,15 @@ }, /turf/open/floor/iron, /area/station/cargo/sorting) +"rfU" = ( +/obj/structure/cable, +/obj/structure/railing/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/white, +/area/station/science/research) "rgp" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, @@ -49858,16 +49782,6 @@ /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/iron, /area/station/maintenance/department/medical/central) -"rin" = ( -/obj/effect/landmark/start/geneticist, -/obj/structure/chair/office, -/obj/structure/cable, -/obj/effect/turf_decal/siding/purple{ - dir = 4 - }, -/obj/structure/disposalpipe/segment, -/turf/open/floor/iron/white/textured, -/area/station/science/genetics) "riv" = ( /obj/effect/decal/cleanable/dirt/dust, /obj/machinery/light/small/dim/directional/north, @@ -49967,11 +49881,6 @@ /obj/structure/grille, /turf/open/space/openspace, /area/space/nearstation) -"rjr" = ( -/obj/structure/cable, -/obj/effect/turf_decal/tile/purple/opposingcorners, -/turf/open/floor/iron/white, -/area/station/science/auxlab/firing_range) "rjs" = ( /obj/structure/window/reinforced/spawner/directional/east, /obj/structure/table/reinforced, @@ -50350,6 +50259,11 @@ }, /turf/open/floor/wood, /area/station/command/heads_quarters/hos) +"rpO" = ( +/obj/machinery/light/directional/north, +/obj/machinery/firealarm/directional/east, +/turf/open/floor/iron/white, +/area/station/science/research) "rpP" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -50940,6 +50854,24 @@ }, /turf/open/floor/iron/white/herringbone, /area/station/maintenance/department/medical/central) +"ryW" = ( +/obj/effect/turf_decal/tile/purple/opposingcorners, +/obj/structure/table, +/obj/item/gun/energy/laser/practice{ + pixel_x = 2; + pixel_y = 5 + }, +/obj/item/gun/energy/laser/practice{ + pixel_x = 2; + pixel_y = 1 + }, +/obj/item/gun/energy/laser/practice{ + pixel_x = 2; + pixel_y = -2 + }, +/obj/machinery/camera/autoname/directional/south, +/turf/open/floor/iron/white, +/area/station/science/auxlab/firing_range) "rzb" = ( /obj/effect/turf_decal/siding/wood, /obj/machinery/camera/autoname/directional/south, @@ -50953,6 +50885,13 @@ }, /turf/open/floor/plating/elevatorshaft, /area/station/cargo/storage) +"rzn" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/mob/living/basic/bot/secbot/beepsky/officer, +/turf/open/floor/iron, +/area/station/hallway/primary/central) "rzB" = ( /turf/open/floor/iron/white/smooth_half{ dir = 8 @@ -51285,6 +51224,12 @@ /obj/effect/mapping_helpers/airlock/access/all/engineering/external, /turf/open/floor/plating, /area/station/maintenance/department/cargo) +"rEX" = ( +/obj/item/radio/intercom/directional/north, +/obj/item/kirbyplants/random, +/obj/effect/turf_decal/tile/purple/opposingcorners, +/turf/open/floor/iron/white, +/area/station/science/auxlab/firing_range) "rFb" = ( /obj/effect/turf_decal/trimline/green/filled/line{ dir = 9 @@ -51308,6 +51253,16 @@ /obj/effect/landmark/start/prisoner, /turf/open/floor/iron/freezer, /area/station/security/prison/shower) +"rFG" = ( +/obj/machinery/door/firedoor/border_only{ + dir = 4 + }, +/obj/machinery/door/firedoor/border_only{ + dir = 1 + }, +/obj/effect/landmark/firealarm_sanity, +/turf/open/floor/catwalk_floor/iron_white, +/area/station/science/lobby) "rFK" = ( /obj/effect/turf_decal/sand/plating, /obj/effect/decal/cleanable/rubble, @@ -51320,13 +51275,6 @@ /obj/effect/landmark/start/chemist, /turf/open/floor/iron/white, /area/station/medical/chemistry) -"rFV" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/mob/living/simple_animal/bot/secbot/beepsky/officer, -/turf/open/floor/iron, -/area/station/hallway/primary/central) "rFX" = ( /obj/effect/turf_decal/siding/dark_blue/corner{ dir = 4 @@ -51485,22 +51433,6 @@ }, /turf/open/floor/iron/dark, /area/station/engineering/lobby) -"rIX" = ( -/obj/structure/table/glass, -/obj/item/folder/white{ - pixel_x = 4; - pixel_y = -3 - }, -/obj/item/book/manual/wiki/infections, -/obj/effect/turf_decal/tile/green/half/contrasted{ - dir = 8 - }, -/obj/item/tgui_book/manual/idc{ - pixel_y = 2; - pixel_x = 3 - }, -/turf/open/floor/iron/white, -/area/station/medical/virology) "rJb" = ( /obj/machinery/power/smes/engineering, /obj/structure/cable, @@ -51595,23 +51527,6 @@ /obj/machinery/firealarm/directional/west, /turf/open/floor/iron/white, /area/station/medical/treatment_center) -"rKQ" = ( -/obj/machinery/door/airlock/medical{ - name = "Primary Surgical Theatre" - }, -/obj/machinery/door/firedoor, -/obj/effect/turf_decal/tile/blue/fourcorners, -/obj/effect/mapping_helpers/airlock/access/all/medical/surgery, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/mapping_helpers/airlock/unres/delayed{ - dir = 8 - }, -/turf/open/floor/iron/white, -/area/station/medical/surgery/theatre) "rKW" = ( /obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/bot_red, @@ -51812,11 +51727,6 @@ /obj/item/radio/intercom/directional/south, /turf/open/floor/iron/showroomfloor, /area/station/cargo/storage) -"rPy" = ( -/turf/closed/mineral/random/stationside/asteroid/porus{ - mineralChance = 20 - }, -/area/station/maintenance/port/greater) "rPA" = ( /obj/effect/turf_decal/tile/brown/anticorner/contrasted{ dir = 1 @@ -52504,6 +52414,11 @@ dir = 8 }, /area/station/medical/storage) +"rYC" = ( +/obj/item/food/grown/banana, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/grass, +/area/station/science/genetics) "rYJ" = ( /obj/structure/closet/emcloset/anchored, /turf/open/floor/plating, @@ -52768,6 +52683,20 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/glass/reinforced, /area/station/ai/upload/foyer) +"sck" = ( +/obj/machinery/door/airlock/research, +/obj/effect/turf_decal/siding/purple{ + dir = 4 + }, +/obj/effect/mapping_helpers/airlock/access/all/science/genetics, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/autoname, +/obj/machinery/door/poddoor/shutters/preopen{ + dir = 8; + id = "geneshut" + }, +/turf/open/floor/iron/white/textured, +/area/station/science/genetics) "sco" = ( /obj/structure/reagent_dispensers/water_cooler, /obj/effect/turf_decal/siding/wood{ @@ -53462,6 +53391,20 @@ }, /turf/open/floor/wood/tile, /area/station/security/courtroom) +"snE" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Treatment Centre" + }, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/access/any/medical/general, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/mapping_helpers/airlock/unres/delayed{ + dir = 8 + }, +/turf/open/floor/iron/white, +/area/station/medical/treatment_center) "snF" = ( /obj/effect/turf_decal/tile/red/half/contrasted, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ @@ -53923,20 +53866,6 @@ /obj/machinery/light/small/directional/west, /turf/open/floor/iron/dark, /area/station/service/cafeteria) -"suK" = ( -/obj/effect/turf_decal/siding/purple{ - dir = 1 - }, -/obj/machinery/door/window/right/directional/north, -/turf/open/floor/engine, -/area/station/science/auxlab/firing_range) -"suO" = ( -/obj/structure/window/reinforced/spawner/directional/north, -/obj/effect/turf_decal/siding/purple{ - dir = 1 - }, -/turf/open/floor/engine, -/area/station/science/auxlab/firing_range) "suV" = ( /obj/effect/turf_decal/stripes/line, /obj/effect/decal/cleanable/dirt/dust, @@ -54745,20 +54674,6 @@ /obj/machinery/door/firedoor, /turf/open/floor/iron/dark, /area/station/hallway/secondary/exit/departure_lounge) -"sIY" = ( -/obj/machinery/dna_scannernew, -/obj/structure/railing, -/obj/machinery/power/apc/auto_name/directional/west, -/obj/machinery/door/firedoor/border_only, -/obj/structure/cable, -/obj/effect/turf_decal/siding/purple/corner{ - dir = 4 - }, -/obj/structure/disposalpipe/segment{ - dir = 5 - }, -/turf/open/floor/iron/white/textured, -/area/station/science/genetics) "sJo" = ( /obj/structure/table/glass, /obj/effect/spawner/random/food_or_drink/donkpockets, @@ -54918,9 +54833,6 @@ /obj/machinery/airalarm/directional/north, /turf/open/floor/plating, /area/station/maintenance/department/bridge) -"sMl" = ( -/turf/open/floor/iron/white/textured, -/area/station/science/genetics) "sMs" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/layer_manifold/yellow/visible{ @@ -55032,13 +54944,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible, /turf/open/floor/engine, /area/station/engineering/supermatter) -"sOJ" = ( -/obj/structure/flora/coconuts, -/obj/machinery/camera/autoname/directional/north{ - network = list("ss13","rd") - }, -/turf/open/floor/grass, -/area/station/science/genetics) "sPi" = ( /obj/structure/closet/firecloset, /obj/effect/landmark/start/hangover, @@ -55075,6 +54980,18 @@ dir = 4 }, /area/station/engineering/atmos) +"sPM" = ( +/obj/structure/table, +/obj/item/storage/box/disks{ + pixel_x = 6; + pixel_y = 3 + }, +/obj/item/storage/box/bodybags{ + pixel_x = -4; + pixel_y = 9 + }, +/turf/open/floor/iron/white/textured, +/area/station/science/genetics) "sPV" = ( /obj/machinery/atmospherics/components/binary/passive_gate{ on = 1; @@ -55318,6 +55235,22 @@ /obj/effect/landmark/firealarm_sanity, /turf/open/openspace, /area/station/security/warden) +"sTW" = ( +/obj/structure/rack, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/sand/plating, +/obj/item/stack/ducts{ + pixel_y = 3 + }, +/obj/item/stack/ducts, +/obj/item/stack/ducts{ + pixel_y = 7 + }, +/obj/item/storage/box/bandages, +/turf/open/floor/plating, +/area/station/cargo/miningoffice) "sUc" = ( /obj/item/bodypart/arm/left, /turf/open/floor/plating/airless, @@ -55357,6 +55290,11 @@ /obj/item/radio/intercom/directional/west, /turf/open/openspace, /area/station/security/warden) +"sUW" = ( +/obj/effect/turf_decal/sand/plating, +/obj/machinery/light/small/directional/north, +/turf/open/misc/asteroid, +/area/station/cargo/miningoffice) "sUY" = ( /obj/structure/chair/stool/directional/east, /obj/effect/turf_decal/sand/plating, @@ -55483,12 +55421,6 @@ }, /turf/open/floor/iron, /area/station/command/bridge) -"sXG" = ( -/obj/effect/turf_decal/tile/purple/opposingcorners, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/white, -/area/station/science/auxlab/firing_range) "sXI" = ( /obj/structure/lattice, /obj/structure/grille/broken, @@ -56022,6 +55954,19 @@ /obj/effect/mapping_helpers/mail_sorting/engineering/atmospherics, /turf/open/floor/iron, /area/station/engineering/atmos) +"thx" = ( +/obj/item/radio/intercom/directional/east, +/obj/effect/turf_decal/tile/purple/half/contrasted{ + dir = 4 + }, +/obj/structure/table, +/obj/item/paper_bin{ + pixel_x = -2; + pixel_y = 6 + }, +/obj/item/pen, +/turf/open/floor/iron/white, +/area/station/science/lobby) "thH" = ( /obj/effect/turf_decal/tile/red/anticorner/contrasted{ dir = 4 @@ -56224,6 +56169,12 @@ }, /turf/open/floor/iron, /area/station/service/hydroponics) +"tkW" = ( +/obj/structure/sign/warning/directional/east, +/turf/closed/mineral/random/stationside/asteroid/porus{ + mineral_chance = 20 + }, +/area/station/asteroid) "tla" = ( /obj/machinery/power/apc/auto_name/directional/east, /obj/structure/cable, @@ -56668,14 +56619,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/exam_room) -"tsy" = ( -/obj/effect/turf_decal/siding/purple{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/white/textured, -/area/station/science/genetics) "tsz" = ( /obj/machinery/door/airlock/external{ name = "Escape Pod Two"; @@ -56891,11 +56834,6 @@ /obj/structure/cable, /turf/open/floor/engine, /area/station/engineering/supermatter) -"twm" = ( -/obj/effect/turf_decal/tile/purple/opposingcorners, -/obj/effect/landmark/event_spawn, -/turf/open/floor/iron/white, -/area/station/science/auxlab/firing_range) "tww" = ( /obj/structure/cable, /turf/open/floor/catwalk_floor/iron_dark, @@ -57045,11 +56983,6 @@ }, /turf/open/floor/carpet/executive, /area/station/command/meeting_room) -"tAa" = ( -/turf/closed/mineral/random/stationside/asteroid/porus{ - mineralChance = 20 - }, -/area/station/maintenance/central/greater) "tAf" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -57978,13 +57911,6 @@ }, /turf/open/floor/glass/reinforced/plasma, /area/station/command/heads_quarters/rd) -"tOO" = ( -/obj/effect/landmark/start/geneticist, -/obj/structure/chair/office{ - dir = 1 - }, -/turf/open/floor/iron/white/textured, -/area/station/science/genetics) "tOV" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -58139,6 +58065,14 @@ }, /turf/open/floor/iron/dark, /area/station/security/armory) +"tSk" = ( +/obj/effect/turf_decal/siding/white{ + dir = 6 + }, +/obj/effect/decal/cleanable/blood/tracks, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/white/small, +/area/station/science/lobby) "tSn" = ( /obj/structure/chair/office/light{ dir = 4 @@ -58265,6 +58199,13 @@ /obj/effect/turf_decal/tile/bar/opposingcorners, /turf/open/floor/iron, /area/station/commons/lounge) +"tUQ" = ( +/obj/machinery/door/airlock/research, +/obj/effect/mapping_helpers/airlock/autoname, +/obj/effect/mapping_helpers/airlock/access/all/science/genetics, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/white/textured, +/area/station/science/genetics) "tUR" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 8 @@ -58286,14 +58227,6 @@ }, /turf/open/floor/iron/dark, /area/station/engineering/circuit_workshop) -"tVF" = ( -/obj/effect/spawner/structure/window/hollow/reinforced/middle, -/obj/structure/cable, -/obj/machinery/door/poddoor/shutters/window/preopen{ - id = "chimpcon1" - }, -/turf/open/floor/plating, -/area/station/science/genetics) "tVH" = ( /obj/machinery/door/airlock/security/glass, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ @@ -58409,12 +58342,6 @@ /obj/machinery/camera/autoname/directional/south, /turf/open/floor/iron, /area/station/maintenance/disposal/incinerator) -"tXg" = ( -/obj/structure/sign/warning/directional/north, -/turf/closed/mineral/random/stationside/asteroid/porus{ - mineralChance = 20 - }, -/area/station/asteroid) "tXi" = ( /obj/machinery/duct, /obj/machinery/light_switch/directional/west, @@ -58543,6 +58470,10 @@ }, /turf/open/floor/iron/white, /area/station/medical/surgery/theatre) +"tZQ" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/white/textured, +/area/station/science/genetics) "tZW" = ( /obj/machinery/camera/autoname/directional/south, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -58851,6 +58782,11 @@ /obj/machinery/exodrone_launcher, /turf/open/floor/iron/dark, /area/station/cargo/drone_bay) +"ufq" = ( +/obj/structure/cable/layer3, +/mob/living/basic/bot/secbot/pingsky, +/turf/open/floor/iron/dark, +/area/station/ai/satellite/foyer) "ufr" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -59170,6 +59106,11 @@ /obj/item/stack/rods/two, /turf/open/floor/engine, /area/station/science/auxlab/firing_range) +"ukI" = ( +/obj/effect/landmark/event_spawn, +/obj/machinery/computer/records/medical, +/turf/open/floor/glass/reinforced, +/area/station/science/genetics) "ukK" = ( /obj/effect/turf_decal/tile/dark_red/opposingcorners, /obj/structure/cable, @@ -59309,6 +59250,10 @@ /obj/structure/window/reinforced/spawner/directional/east, /turf/open/floor/engine, /area/station/science/xenobiology) +"umJ" = ( +/obj/effect/spawner/structure/window/hollow/reinforced/middle, +/turf/open/floor/plating, +/area/station/science/genetics) "umK" = ( /obj/effect/spawner/random/structure/crate_abandoned, /turf/open/floor/plating, @@ -59800,17 +59745,6 @@ }, /turf/open/floor/engine, /area/station/command/corporate_dock) -"uvf" = ( -/obj/machinery/door/airlock/medical{ - name = "Treatment Centre" - }, -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/access/any/medical/general, -/obj/structure/cable, -/obj/structure/disposalpipe/segment, -/obj/effect/mapping_helpers/airlock/unres/delayed, -/turf/open/floor/iron/white, -/area/station/medical/exam_room) "uvl" = ( /obj/machinery/door/airlock/virology/glass{ name = "Biohazard Gear" @@ -60015,20 +59949,6 @@ "uyL" = ( /turf/open/floor/iron, /area/station/cargo/storage) -"uyW" = ( -/obj/machinery/door/airlock/medical/glass{ - id_tag = "triage"; - name = "Triage" - }, -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/access/any/medical/general, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/mapping_helpers/airlock/unres/delayed{ - dir = 8 - }, -/turf/open/floor/iron/white, -/area/station/medical/exam_room) "uyZ" = ( /obj/effect/turf_decal/tile/yellow{ dir = 8 @@ -60078,20 +59998,6 @@ "uzQ" = ( /turf/open/floor/iron/white/textured_large, /area/station/commons/fitness/recreation) -"uzT" = ( -/obj/structure/table/glass, -/obj/structure/reagent_dispensers/wall/virusfood/directional/west, -/obj/machinery/reagentgrinder{ - pixel_y = 8 - }, -/obj/effect/turf_decal/tile/green/half/contrasted{ - dir = 8 - }, -/obj/item/stack/sheet/mineral/plasma{ - amount = 3 - }, -/turf/open/floor/iron/white, -/area/station/medical/virology) "uzV" = ( /obj/effect/turf_decal/stripes, /obj/effect/mapping_helpers/broken_floor, @@ -60232,6 +60138,14 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/science/ordnance) +"uCi" = ( +/obj/structure/closet/l3closet/janitor, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/camera/autoname/directional/north, +/obj/item/restraints/legcuffs/beartrap, +/obj/item/restraints/legcuffs/beartrap, +/turf/open/floor/iron, +/area/station/service/janitor) "uCj" = ( /obj/effect/turf_decal/tile/blue/opposingcorners, /obj/effect/turf_decal/tile/red/opposingcorners{ @@ -60495,11 +60409,6 @@ }, /turf/open/floor/iron, /area/station/cargo/lobby) -"uFt" = ( -/obj/machinery/dna_infuser, -/obj/item/tgui_book/manual/infuser, -/turf/open/floor/iron/white/textured, -/area/station/science/genetics) "uFC" = ( /turf/closed/wall/r_wall, /area/station/engineering/supermatter/room) @@ -60745,17 +60654,6 @@ /obj/effect/mapping_helpers/airlock/access/all/engineering/external, /turf/open/floor/plating, /area/station/maintenance/department/bridge) -"uLz" = ( -/obj/structure/table, -/obj/item/stack/cable_coil, -/obj/item/assembly/igniter, -/obj/machinery/power/apc/auto_name/directional/north, -/obj/effect/turf_decal/tile/purple/half/contrasted{ - dir = 1 - }, -/obj/structure/cable, -/turf/open/floor/iron/white, -/area/station/science/lobby) "uLP" = ( /obj/effect/turf_decal/trimline/yellow/filled/warning{ dir = 6 @@ -61615,6 +61513,18 @@ /obj/structure/closet/wardrobe/white/medical, /turf/open/floor/iron/white, /area/station/medical/exam_room) +"vdu" = ( +/obj/structure/cable, +/obj/structure/railing{ + dir = 1 + }, +/obj/machinery/door/firedoor/border_only{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron/white, +/area/station/science/research) "vdD" = ( /obj/effect/turf_decal/siding/purple{ dir = 1 @@ -61774,6 +61684,16 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron, /area/station/security/brig/entrance) +"vgm" = ( +/obj/structure/table, +/obj/machinery/cell_charger, +/obj/item/stock_parts/power_store/cell, +/obj/effect/turf_decal/tile/purple/half/contrasted{ + dir = 1 + }, +/obj/machinery/firealarm/directional/north, +/turf/open/floor/iron/white, +/area/station/science/lobby) "vgq" = ( /obj/structure/railing{ dir = 6 @@ -62094,6 +62014,25 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) +"vlW" = ( +/obj/structure/table, +/obj/item/storage/box/monkeycubes{ + pixel_x = 4 + }, +/obj/item/storage/box/monkeycubes{ + pixel_x = 6; + pixel_y = 9 + }, +/obj/item/storage/pill_bottle/mutadone{ + pixel_x = -9 + }, +/obj/machinery/airalarm/directional/north, +/obj/item/flesh_shears{ + pixel_x = -5; + pixel_y = 10 + }, +/turf/open/floor/iron/white/textured, +/area/station/science/genetics) "vmf" = ( /obj/structure/closet/wardrobe/orange, /obj/effect/turf_decal/tile/red/anticorner/contrasted{ @@ -62565,10 +62504,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/department/medical) -"vwd" = ( -/obj/machinery/newscaster/directional/south, -/turf/open/floor/engine, -/area/station/science/auxlab/firing_range) "vwf" = ( /obj/structure/girder, /obj/effect/decal/cleanable/dirt/dust, @@ -62595,21 +62530,6 @@ }, /turf/open/openspace, /area/station/engineering/main) -"vwx" = ( -/obj/machinery/door/airlock/medical{ - id_tag = "r1"; - name = "Room A" - }, -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/access/any/medical/general, -/obj/effect/turf_decal/tile/blue/fourcorners, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/obj/effect/mapping_helpers/airlock/unres/delayed{ - dir = 4 - }, -/turf/open/floor/iron/white, -/area/station/medical/patients_rooms/room_a) "vwD" = ( /obj/effect/landmark/start/clown, /obj/structure/chair/stool/bar/directional/west, @@ -62650,6 +62570,14 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/hallway/primary/central) +"vxl" = ( +/obj/machinery/power/apc/auto_name/directional/south, +/obj/structure/cable, +/obj/effect/spawner/random/entertainment/slot_machine{ + pixel_y = 2 + }, +/turf/open/floor/wood, +/area/station/commons/lounge) "vxn" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 8 @@ -62682,11 +62610,6 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/iron, /area/station/commons/fitness/recreation) -"vxX" = ( -/turf/closed/mineral/random/stationside/asteroid/porus{ - mineralChance = 20 - }, -/area/station/asteroid) "vxZ" = ( /obj/machinery/atmospherics/pipe/smart/simple/dark/visible{ dir = 4 @@ -63020,6 +62943,11 @@ /obj/machinery/atmospherics/components/unary/vent_pump/siphon/monitored/plasma_output, /turf/open/floor/engine/plasma, /area/station/engineering/atmos) +"vEw" = ( +/turf/closed/mineral/random/stationside/asteroid/porus{ + mineral_chance = 20 + }, +/area/station/maintenance/central/greater) "vED" = ( /obj/structure/closet/secure_closet/warden, /obj/item/gun/energy/laser, @@ -63047,13 +62975,6 @@ /obj/effect/landmark/start/medical_doctor, /turf/open/floor/iron/white, /area/station/medical/treatment_center) -"vES" = ( -/obj/item/radio/intercom/directional/east, -/obj/effect/turf_decal/tile/purple/half/contrasted{ - dir = 4 - }, -/turf/open/floor/iron/white, -/area/station/science/lobby) "vEX" = ( /obj/structure/table/reinforced, /obj/machinery/computer/security/telescreen/entertainment/directional/north, @@ -63344,11 +63265,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/chemistry/minisat) -"vIL" = ( -/obj/effect/spawner/random/entertainment/slot_machine, -/obj/effect/turf_decal/sand/plating, -/turf/open/floor/plating, -/area/station/maintenance/central/greater) "vIO" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/decal/cleanable/dirt/dust, @@ -63608,6 +63524,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/white/smooth_large, /area/station/science/research) +"vNT" = ( +/obj/effect/spawner/random/entertainment/slot_machine, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron/grimy, +/area/station/maintenance/central/lesser) "vNZ" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment, @@ -63675,11 +63596,6 @@ }, /turf/open/floor/wood/tile, /area/station/service/bar) -"vPt" = ( -/turf/closed/mineral/random/stationside/asteroid/porus{ - mineralChance = 20 - }, -/area/station/maintenance/disposal/incinerator) "vPF" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/spawner/random/structure/grille, @@ -63863,13 +63779,6 @@ }, /turf/open/floor/iron, /area/station/cargo/storage) -"vSv" = ( -/obj/structure/sign/warning/directional/north, -/obj/effect/turf_decal/tile/purple/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron/white, -/area/station/science/lobby) "vSy" = ( /obj/structure/chair/sofa/bench{ dir = 4 @@ -63982,6 +63891,17 @@ /obj/structure/cable, /turf/open/floor/carpet, /area/station/medical/psychology) +"vUA" = ( +/obj/machinery/bouldertech/refinery/smelter{ + dir = 8 + }, +/obj/machinery/conveyor{ + dir = 6; + id = "brm" + }, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating, +/area/station/cargo/miningoffice) "vUJ" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -64369,6 +64289,10 @@ /obj/item/storage/box/drinkingglasses, /turf/open/floor/plating, /area/station/maintenance/central/greater) +"wbX" = ( +/obj/machinery/door/window/left/directional/west, +/turf/open/floor/engine, +/area/station/science/auxlab/firing_range) "wca" = ( /obj/structure/bodycontainer/morgue, /obj/structure/window/reinforced/spawner/directional/north, @@ -64615,6 +64539,11 @@ /obj/machinery/air_sensor/ordnance_burn_chamber, /turf/open/floor/engine/vacuum, /area/station/science/ordnance/burnchamber) +"wgU" = ( +/turf/closed/mineral/random/stationside/asteroid/porus{ + mineral_chance = 20 + }, +/area/station/maintenance/port/greater) "whn" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/spawner/random/trash/mess, @@ -64659,20 +64588,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/openspace, /area/station/engineering/supermatter/room) -"wij" = ( -/obj/structure/table/glass, -/obj/item/radio/intercom/directional/south, -/obj/item/tgui_book/manual/dsm{ - pixel_x = -6; - pixel_y = 4 - }, -/obj/item/tgui_book/manual/idc{ - pixel_y = 2; - pixel_x = 3 - }, -/obj/item/food/sandwich/cheese, -/turf/open/floor/iron/dark/textured, -/area/station/command/heads_quarters/cmo) "wim" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -64882,6 +64797,10 @@ /obj/machinery/light/directional/south, /turf/open/floor/iron/dark, /area/station/engineering/atmospherics_engine) +"wlL" = ( +/obj/structure/window/reinforced/spawner/directional/west, +/turf/open/floor/engine, +/area/station/science/auxlab/firing_range) "wlO" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible{ dir = 1 @@ -64955,6 +64874,11 @@ }, /turf/open/floor/wood/tile, /area/station/security/courtroom) +"wni" = ( +/turf/open/floor/iron/stairs/right{ + dir = 8 + }, +/area/station/science/lobby) "wnw" = ( /obj/effect/spawner/structure/window/hollow/reinforced/middle, /obj/machinery/door/poddoor/shutters/preopen{ @@ -64973,6 +64897,17 @@ dir = 8 }, /area/station/science/xenobiology) +"wnD" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/siding/purple{ + dir = 5 + }, +/obj/machinery/camera/autoname/directional/east, +/mob/living/basic/bot/secbot/pingsky, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron/white, +/area/station/ai/upload/foyer) "wnL" = ( /turf/open/floor/plating, /area/station/medical/medbay/central) @@ -65635,6 +65570,20 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) +"wyf" = ( +/obj/machinery/door/airlock/medical/glass{ + id_tag = "triage"; + name = "Triage" + }, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/access/any/medical/general, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/mapping_helpers/airlock/unres/delayed{ + dir = 8 + }, +/turf/open/floor/iron/white, +/area/station/medical/exam_room) "wyh" = ( /obj/structure/lattice, /obj/structure/grille, @@ -66329,21 +66278,6 @@ /obj/effect/spawner/random/entertainment/deck, /turf/open/floor/wood, /area/station/commons/lounge) -"wKv" = ( -/obj/machinery/door/airlock/medical{ - id_tag = "r2"; - name = "Room B" - }, -/obj/machinery/door/firedoor, -/obj/effect/turf_decal/tile/blue/fourcorners, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/obj/effect/mapping_helpers/airlock/access/any/medical/general, -/obj/effect/mapping_helpers/airlock/unres/delayed{ - dir = 4 - }, -/turf/open/floor/iron/white, -/area/station/medical/patients_rooms/room_b) "wKE" = ( /obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance, /obj/effect/mapping_helpers/airlock/unres/delayed, @@ -67586,20 +67520,6 @@ /obj/machinery/firealarm/directional/south, /turf/open/floor/wood/large, /area/station/cargo/boutique) -"xfG" = ( -/obj/machinery/door/airlock/medical/glass{ - name = "Treatment Centre" - }, -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/access/any/medical/general, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/mapping_helpers/airlock/unres/delayed{ - dir = 8 - }, -/turf/open/floor/iron/white, -/area/station/medical/treatment_center) "xfJ" = ( /obj/machinery/door/window/brigdoor/right/directional/west{ req_access = list("xenobiology") @@ -67869,11 +67789,20 @@ }, /turf/open/floor/plating, /area/station/maintenance/port/lesser) -"xkc" = ( -/obj/structure/cable/layer3, -/mob/living/simple_animal/bot/secbot/pingsky, -/turf/open/floor/iron/dark, -/area/station/ai/satellite/foyer) +"xkb" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Treatment Centre" + }, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/access/any/medical/general, +/obj/structure/disposalpipe/segment{ + dir = 8 + }, +/obj/effect/mapping_helpers/airlock/unres/delayed{ + dir = 8 + }, +/turf/open/floor/iron/white, +/area/station/medical/treatment_center) "xkx" = ( /obj/machinery/door/airlock/hatch{ name = "Cyborg Break Room" @@ -67979,6 +67908,18 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, /area/station/medical/chemistry) +"xmA" = ( +/obj/machinery/door/airlock/research, +/obj/effect/mapping_helpers/airlock/access/all/science/genetics, +/obj/effect/mapping_helpers/airlock/autoname, +/obj/structure/cable, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron/white/textured, +/area/station/science/genetics) "xmM" = ( /obj/structure/closet/secure_closet/freezer/fridge, /obj/machinery/power/apc/auto_name/directional/west, @@ -69026,23 +68967,6 @@ /obj/structure/closet/crate/bin, /turf/open/floor/iron, /area/station/security) -"xEb" = ( -/obj/structure/table/reinforced/rglass, -/obj/effect/turf_decal/tile/blue/fourcorners, -/obj/item/reagent_containers/cup/bottle/epinephrine{ - pixel_x = 6; - pixel_y = 9 - }, -/obj/item/storage/box/rxglasses{ - pixel_x = -4; - pixel_y = 8 - }, -/obj/item/stack/medical/wrap/gauze{ - pixel_x = 8 - }, -/obj/item/reagent_containers/syringe, -/turf/open/floor/iron/white, -/area/station/medical/treatment_center) "xEl" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/multi_tile/public/glass{ @@ -69165,10 +69089,6 @@ /obj/item/storage/box/monkeycubes, /turf/open/floor/iron/white/textured_large, /area/station/science/xenobiology) -"xGY" = ( -/obj/item/radio/intercom/directional/south, -/turf/open/floor/engine, -/area/station/science/auxlab/firing_range) "xGZ" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 4 @@ -69661,13 +69581,6 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/department/cargo) -"xPZ" = ( -/obj/structure/ladder{ - icon_state = "ladder10" - }, -/obj/machinery/light/warm/directional/north, -/turf/open/floor/grass, -/area/station/science/genetics) "xQe" = ( /obj/effect/turf_decal/tile/yellow/half/contrasted{ dir = 4 @@ -69887,6 +69800,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/white/smooth_large, /area/station/science/research) +"xVh" = ( +/obj/effect/turf_decal/tile/purple/opposingcorners, +/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/white, +/area/station/science/auxlab/firing_range) "xVt" = ( /obj/structure/window/reinforced/spawner/directional/north, /turf/open/floor/engine, @@ -69925,10 +69845,6 @@ /obj/effect/decal/cleanable/dirt/dust, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) -"xWq" = ( -/obj/structure/flora/bush/grassy/style_random, -/turf/open/floor/grass, -/area/station/science/genetics) "xWK" = ( /obj/machinery/power/apc/auto_name/directional/south, /obj/effect/turf_decal/tile/red/half/contrasted, @@ -70278,12 +70194,6 @@ }, /turf/open/floor/engine, /area/station/engineering/supermatter) -"ycq" = ( -/obj/structure/training_machine, -/obj/item/target/clown, -/obj/structure/sign/poster/random/directional/south, -/turf/open/floor/engine, -/area/station/science/auxlab/firing_range) "ycs" = ( /obj/effect/spawner/random/engineering/tank, /obj/effect/decal/cleanable/cobweb, @@ -70701,14 +70611,13 @@ "yiQ" = ( /turf/closed/wall/rust, /area/station/maintenance/port/lesser) -"yiW" = ( -/obj/effect/turf_decal/siding/purple{ - dir = 8 +"yiS" = ( +/obj/effect/turf_decal/tile/purple/opposingcorners, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 1 }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/white/textured_large, -/area/station/science/genetics) +/turf/open/floor/iron/white, +/area/station/science/auxlab/firing_range) "yjb" = ( /obj/effect/turf_decal/tile/red/half/contrasted{ dir = 8 @@ -81097,9 +81006,9 @@ cLf cLf cLf cLf -vxX -vxX -vxX +bmG +bmG +bmG rnk rnk auE @@ -81121,10 +81030,10 @@ rYJ fjg gzL jsC -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG cLf dUc cLf @@ -81353,9 +81262,9 @@ dUc cLf cLf cLf -vxX -vxX -vxX +bmG +bmG +bmG rnk rnk tdh @@ -81378,10 +81287,10 @@ oFu hrk oFu jsC -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG rnk loh loh @@ -81608,9 +81517,9 @@ cLf cLf dUc cLf -vxX -vxX -vxX +bmG +bmG +bmG rnk rnk rnk @@ -81864,10 +81773,10 @@ cLf cLf cLf dUc -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG rnk ryV rnk @@ -82100,10 +82009,10 @@ cLf cLf cLf cLf -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG cLf dUc dUc @@ -82124,7 +82033,7 @@ hCS hCS hCS hCS -vxX +bmG rnk bCv tDg @@ -83118,7 +83027,7 @@ poi fgP poi cax -eio +eYp aCx mxq mxq @@ -83374,7 +83283,7 @@ dqW vTd csl dfW -eio +eYp dDZ mMS nIJ @@ -83424,13 +83333,13 @@ rnk fjC rnk qvA -ggZ +iWx qvA xBS xBS -oMK +qzm esg -rKQ +kTs xBS tUo tUo @@ -83628,13 +83537,13 @@ cro cro cro poi -eio +eYp ngd lKZ ngd mMS mMS -eio +eYp mxq pRM mxq @@ -83890,8 +83799,8 @@ eSS dGR syR aVY -eio -eio +eYp +eYp mxq iPw tBe @@ -84148,7 +84057,7 @@ sIV syR sVn sIV -eio +eYp mxq uiy qWu @@ -84405,7 +84314,7 @@ mJL hHJ hHJ qHv -eio +eYp mxq mxq xlB @@ -84444,11 +84353,11 @@ tkr rnk rnk ryz -wKv +ogZ fzZ vGn vGn -vwx +fVF fMT kFT kFT @@ -84662,8 +84571,8 @@ abw eSS esl ggY -eio -eio +eYp +eYp mxq fGr ugu @@ -84917,10 +84826,10 @@ cDM lDP fBK eSS -eio +eYp ggY -eio -eio +eYp +eYp mxq mxq sGj @@ -86431,7 +86340,7 @@ cLf cLf cLf dUc -vxX +bmG ubm ubm hME @@ -86512,7 +86421,7 @@ aPR lUk nnv mNo -xEb +pts tYs oaY hKv @@ -86528,8 +86437,8 @@ rnk gtK oqj rnk -vxX -vxX +bmG +bmG dUc cLf cLf @@ -86688,8 +86597,8 @@ cLf cLf cLf unk -vxX -vxX +bmG +bmG ubm fae eyv @@ -86767,7 +86676,7 @@ wJy qof hHj lUk -mqG +mUB asr lyr tYs @@ -86786,7 +86695,7 @@ gtK rnk rnk rnk -vxX +bmG unk cLf cLf @@ -86944,9 +86853,9 @@ cLf cLf cLf cLf -vxX -vxX -vxX +bmG +bmG +bmG ubm eYT ohZ @@ -87043,7 +86952,7 @@ gtK rnk gaE rnk -vxX +bmG cLf cLf cLf @@ -87201,9 +87110,9 @@ cLf cLf cLf cLf -vxX -vxX -vxX +bmG +bmG +bmG ubm dMF rrF @@ -87287,7 +87196,7 @@ tYs bdv lZH nmG -uvf +ohI jSY dPt xdm @@ -87300,8 +87209,8 @@ gtK rZz beO rnk -vxX -vxX +bmG +bmG cLf cLf cLf @@ -87458,9 +87367,9 @@ cLf cLf cLf cLf -vxX -vxX -vxX +bmG +bmG +bmG ubm hME hME @@ -87557,7 +87466,7 @@ paa rnk qvN rnk -vxX +bmG cLf cLf cLf @@ -87715,9 +87624,9 @@ cLf cLf cLf cLf -vxX -vxX -vxX +bmG +bmG +bmG hHw oRD pbB @@ -87795,15 +87704,15 @@ qfB qfB dKw sia -xfG +snE sia -cQR +xkb sia dKw dKw dgp hQg -uyW +wyf dgp dgp dgp @@ -87814,7 +87723,7 @@ paa rnk rnk rnk -vxX +bmG cLf cLf cLf @@ -87972,9 +87881,9 @@ cLf cLf cLf cLf -vxX -vxX -vxX +bmG +bmG +bmG hHw mut eQY @@ -88070,7 +87979,7 @@ rnk rms loR rnk -vxX +bmG cLf cLf cLf @@ -88229,9 +88138,9 @@ cLf cLf cLf cLf -vxX -vxX -vxX +bmG +bmG +bmG hHw xjQ oMk @@ -88487,8 +88396,8 @@ cLf cLf cLf cLf -vxX -vxX +bmG +bmG hHw xjQ qEm @@ -88745,7 +88654,7 @@ cLf cLf cLf cLf -vxX +bmG hHw okV mks @@ -89335,7 +89244,7 @@ nTm cGr tjd qfB -lfF +fPs gpF avU ulQ @@ -92943,9 +92852,9 @@ rnk paa lqf rnk -vxX -vxX -vxX +bmG +bmG +bmG cLf cLf dUc @@ -93137,8 +93046,8 @@ oZz oZz pHy oZz -vxX -vxX +bmG +bmG ygw lTJ qZh @@ -93163,9 +93072,9 @@ fCy tHF tCE pXp -ltY -nLJ -hZJ +ctP +olC +vNT acc tQF hyS @@ -93200,8 +93109,8 @@ rnk paa pDQ rnk -vxX -vxX +bmG +bmG rnk rnk rnk @@ -93393,9 +93302,9 @@ fYe fYe fYe fYe -vxX -vxX -vxX +bmG +bmG +bmG ygw pgC sxC @@ -93636,10 +93545,10 @@ cLf cLf cLf cLf -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG wBC pOg cYP @@ -93652,7 +93561,7 @@ cLf fYe fYe fYe -vxX +bmG ygw ygw ygw @@ -93894,9 +93803,9 @@ cLf cLf cLf cLf -vxX -vxX -vxX +bmG +bmG +bmG wBC rKi kIK @@ -93910,10 +93819,10 @@ cLf uuN fYe fYe -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG iol iol iol @@ -94151,9 +94060,9 @@ cLf cLf cLf cLf -vxX +bmG unk -vxX +bmG wBC dQr dNn @@ -94169,8 +94078,8 @@ uuN fYe fYe fYe -vxX -vxX +bmG +bmG fri sZy otH @@ -94427,7 +94336,7 @@ cLf cLf fYe fYe -vxX +bmG fri taD nIb @@ -96530,7 +96439,7 @@ qjW rjn rjn kmu -rFV +rzn tOm sut vsJ @@ -98068,7 +97977,7 @@ qrl fXU qrl eQi -cmM +vxl rjn fux aUy @@ -98325,7 +98234,7 @@ qrl qrl iGK eQi -mqm +bXx rjn vNH tTJ @@ -103653,7 +103562,7 @@ iUF cLf cLf cLf -vxX +bmG srs eEx vDK @@ -103682,7 +103591,7 @@ iyT vfJ psj iMk -bDy +nCU irx gyl uCl @@ -103910,7 +103819,7 @@ iUF dUc dUc unk -vxX +bmG srs srs cgK @@ -104166,8 +104075,8 @@ cLf iUF cLf cLf -vxX -vxX +bmG +bmG srs lPj cqm @@ -104194,7 +104103,7 @@ lJq eRu eRu vfJ -vSv +inD qXy dko hBQ @@ -104424,7 +104333,7 @@ iUF cLf cLf cLf -vxX +bmG eOn fxo vDK @@ -104432,7 +104341,7 @@ srs eJQ vFz kbv -xkc +ufq kee jBg qjp @@ -104451,8 +104360,8 @@ vfJ vfJ vfJ vfJ -bUu -grl +vgm +rvg pJN iKc rSL @@ -104703,16 +104612,16 @@ dUc cLf cLf cLf -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG gvF -uLz -grl +wni +rvg xET iKc -hle +ddy gvF rIb wEA @@ -104959,17 +104868,17 @@ dUc dUc dUc dUc -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG gvF -dnW +gwQ rvg slL iKc -cRV +qaK caB vdR eVR @@ -105216,7 +105125,7 @@ cLf cLf cLf cLf -vxX +bmG vfJ uJt uJt @@ -105473,7 +105382,7 @@ cLf cLf cLf cLf -vxX +bmG uJt eJr wWY @@ -105708,7 +105617,7 @@ cLf iUF cLf cLf -vxX +bmG dZy fhG lQe @@ -105730,7 +105639,7 @@ cLf cLf cLf cLf -vxX +bmG uJt eJr hgX @@ -105740,7 +105649,7 @@ jUi nvQ nvQ nvQ -vES +thx kSM sAO wxa @@ -105964,8 +105873,8 @@ cLf cLf cLf cLf -vxX -vxX +bmG +bmG dZy dZy xZX @@ -105986,8 +105895,8 @@ kYu cLf cLf cLf -vxX -vxX +bmG +bmG uJt nXF tLH @@ -106221,9 +106130,9 @@ cLf cLf cLf cLf -vxX -vxX -vxX +bmG +bmG +bmG dZy tgw nes @@ -106239,12 +106148,12 @@ kYu aUD kYu kYu -vxX +bmG cLf cLf cLf -vxX -vxX +bmG +bmG uJt eJr wWY @@ -106479,8 +106388,8 @@ cLf cLf cLf cLf -vxX -vxX +bmG +bmG dZy prz idU @@ -106496,12 +106405,12 @@ lYN iPQ noc kYu -vxX -vxX +bmG +bmG cLf cLf -vxX -vxX +bmG +bmG vfJ vfJ xbu @@ -106737,7 +106646,7 @@ cLf cLf cLf cLf -vxX +bmG wfl dZy dZy @@ -106753,13 +106662,13 @@ kYu kYu kYu pIN -vxX -vxX +bmG +bmG cLf cLf -vxX -vxX -vxX +bmG +bmG +bmG vfJ eIV gMK @@ -106994,8 +106903,8 @@ cLf cLf cLf cLf -vxX -vxX +bmG +bmG wZz wZz wZz @@ -107009,14 +106918,14 @@ wZz wZz wZz fBc -vxX -vxX -vxX +bmG +bmG +bmG fYe fYe -vxX -vxX -vxX +bmG +bmG +bmG vfJ gLw jmY @@ -107251,8 +107160,8 @@ cLf cLf cLf cLf -vxX -vxX +bmG +bmG wZz wZz dxA @@ -107266,14 +107175,14 @@ dPf uCS wZz wZz -vxX -vxX +bmG +bmG uif fYe fYe fYe -vxX -vxX +bmG +bmG vfJ rXG raz @@ -107508,8 +107417,8 @@ cLf cLf cLf cLf -vxX -vxX +bmG +bmG wZz wZz tOs @@ -107523,14 +107432,14 @@ hwP wmd wZz wZz -vxX -vxX +bmG +bmG fYe fYe fYe fYe -vxX -vxX +bmG +bmG vfJ oBP raz @@ -107765,8 +107674,8 @@ cLf cLf cLf cLf -vxX -vxX +bmG +bmG wZz wZz rdK @@ -107780,13 +107689,13 @@ hwP iYC wZz wZz -vxX -vxX +bmG +bmG fYe fYe fYe uif -vxX +bmG vfJ vfJ oBP @@ -108021,9 +107930,9 @@ cLf cLf cLf cLf -vxX -vxX -vxX +bmG +bmG +bmG wZz wZz mYK @@ -108037,13 +107946,13 @@ cHP taK wZz wZz -vxX -vxX -vxX +bmG +bmG +bmG fYe fYe -vxX -vxX +bmG +bmG vfJ gZF oBP @@ -108123,9 +108032,9 @@ ykG fdj dUc mPv -vxX -vxX -vxX +bmG +bmG +bmG cLf cLf cLf @@ -108278,9 +108187,9 @@ cLf cLf cLf cLf -vxX -vxX -vxX +bmG +bmG +bmG wZz wZz fOM @@ -108294,13 +108203,13 @@ hwP tOp wZz wZz -vxX -vxX -vxX +bmG +bmG +bmG cLf cLf -vxX -vxX +bmG +bmG vfJ xAd iXp @@ -108383,8 +108292,8 @@ ykG ykG ykG ykG -vxX -vxX +bmG +bmG cLf cLf cLf @@ -108535,9 +108444,9 @@ cLf cLf cLf cLf -vxX -vxX -vxX +bmG +bmG +bmG wZz wZz toT @@ -108551,24 +108460,24 @@ hwP emn wZz wZz -vxX -vxX +bmG +bmG cLf cLf cLf -vxX -vxX +bmG +bmG dpu aku uOo xAd obA obA -lAc -lAc -lAc -lAc -cAr +obA +obA +obA +ixU +wAy sYn ejS aMU @@ -108640,8 +108549,8 @@ pRG arr aRs ykG -vxX -vxX +bmG +bmG cLf cLf cLf @@ -108793,8 +108702,8 @@ cLf cLf cLf cLf -vxX -vxX +bmG +bmG wZz wZz biC @@ -108808,23 +108717,23 @@ xZL jPg wZz wZz -vxX -vxX +bmG +bmG cLf cLf cLf -vxX -vxX -ilp +bmG +bmG +iZR aku uOo -ilp -obA -lXz -oAX -wzX -hfD -tVF +xAd +iZR +iZR +iZR +rji +iZR +ixU wAy mUP hfB @@ -108897,8 +108806,8 @@ ptc saJ arr ykG -vxX -vxX +bmG +bmG cLf cLf cLf @@ -109050,8 +108959,8 @@ cLf cLf cLf cLf -vxX -vxX +bmG +bmG wZz wZz wZz @@ -109065,23 +108974,23 @@ wZz wZz wZz wZz -vxX +bmG cLf cLf cLf cLf -vxX -vxX +bmG +bmG vfR aku uOo -ilp -obA -mxs -qQr -oft -mmV -tVF +xAd +iZR +iZR +iSU +aku +foX +ixU jiw sHn xxO @@ -109101,7 +109010,7 @@ vKd niB hjI crU -vxX +bmG dUc dUc nbu @@ -109154,8 +109063,8 @@ rrz wOy voY ykG -vxX -vxX +bmG +bmG cLf cLf cLf @@ -109308,7 +109217,7 @@ cLf cLf cLf cLf -vxX +bmG wNk wZz wZz @@ -109322,23 +109231,23 @@ wZz wZz wZz wNk -vxX +bmG cLf cLf cLf cLf -vxX -vxX -ilp +bmG +bmG +iZR aku uOo -ilp -obA -xPZ -gzr -xWq -uhc -tVF +xAd +iZR +foX +aku +aku +aku +ixU jiw qbd dzC @@ -109358,7 +109267,7 @@ aoA pXS hjI crU -vxX +bmG dUc dUc nbu @@ -109411,7 +109320,7 @@ ptc dwH arr ykG -vxX +bmG cLf cLf cLf @@ -109584,18 +109493,18 @@ cLf cLf cLf cLf -vxX -vxX -ilp +bmG +bmG +iZR aku uOo -ilp -obA -wzX -eFx -oft -hfD -tVF +xAd +iZR +aku +aku +aku +aku +ixU dfM vqv cct @@ -109615,7 +109524,7 @@ ise niB qAI crU -vxX +bmG dUc dUc nbu @@ -109668,7 +109577,7 @@ wIN arr arr ykG -vxX +bmG cLf cLf cLf @@ -109841,18 +109750,18 @@ cLf cLf cLf cLf -vxX -vxX -ilp +bmG +bmG +iZR aku uOo -ilp -obA -sOJ -uhc -uhc -uhc -tVF +iZR +rji +aku +ouA +aku +iZR +ixU dfM dfM kMA @@ -109872,7 +109781,7 @@ aoA qOs bpy crU -vxX +bmG dUc dUc nbu @@ -109925,7 +109834,7 @@ ykG ykG ykG ykG -vxX +bmG cLf cLf cLf @@ -110098,18 +110007,18 @@ cLf cLf cLf cLf -vxX -vxX +bmG +bmG ieo aku uOo -ilp -obA -obA -obA -obA -obA -lAc +iZR +aku +aku +aku +aku +iZR +ixU dcO dfM kMA @@ -110129,7 +110038,7 @@ niB niB aoA crU -vxX +bmG dUc dUc nbu @@ -110182,7 +110091,7 @@ fmr dUc cLf cLf -vxX +bmG cLf cLf cLf @@ -110354,18 +110263,18 @@ cLf cLf cLf cLf -vxX -vxX -vxX -ilp +bmG +bmG +bmG +iZR aku uOo -ilp -ilp +xAd +xAd ieo -lKk -iSU -ilp +aku +aku +iZR ixU mLH dfM @@ -110386,7 +110295,7 @@ niB ers dsL crU -vxX +bmG dUc dUc dUc @@ -110612,17 +110521,17 @@ cLf cLf cLf fYe -vxX -vxX -ilp +bmG +bmG +iZR aku uOo aku foX aku -ouA +aku jJe -ilp +iZR gOY gOY gOY @@ -110643,7 +110552,7 @@ aRf aRf crU crU -vxX +bmG fTX hfp hfp @@ -110693,8 +110602,8 @@ cpG cpG cpG cpG -vxX -vxX +bmG +bmG cLf cLf cLf @@ -110869,17 +110778,17 @@ dUc dUc dUc fYe -vxX -vxX -ilp +bmG +bmG +iZR aku uOo aku foX aku aku -ilp -ilp +iZR +iZR gOY xxN aam @@ -110892,9 +110801,9 @@ uPL sSN nal gOY -vxX +bmG cxg -vxX +bmG dUc dUc dUc @@ -110951,8 +110860,8 @@ rWI hVe cpG cpG -vxX -vxX +bmG +bmG cLf cLf cLf @@ -111126,16 +111035,16 @@ cLf cLf cLf fYe -vxX -vxX -ilp +bmG +bmG +iZR aku uOo pwZ rji foX -ilp -ilp +iZR +iZR jTB jTB jTB @@ -111151,7 +111060,7 @@ cpJ gOY cxg cxg -vxX +bmG nbu nbu nbu @@ -111208,7 +111117,7 @@ lpe xDk mcd cpG -vxX +bmG cLf cLf cLf @@ -111383,15 +111292,15 @@ cLf cLf cLf fYe -vxX -vxX -ilp +bmG +bmG +iZR vfR aku uOo aku aku -ilp +iZR jTB jTB ief @@ -111408,7 +111317,7 @@ oLj gOY wHl cxg -vxX +bmG nbu aXt rBj @@ -111641,14 +111550,14 @@ cLf cLf cLf uif -vxX -ilp -ilp -ilp +bmG +iZR +iZR +iZR uOo aku -ilp -ilp +iZR +iZR jTB jGd eBH @@ -111665,7 +111574,7 @@ gOY gOY cxg cxg -vxX +bmG nbu aXt jyO @@ -111889,8 +111798,8 @@ cLf cLf dUc cLf -vxX -vxX +bmG +bmG fYe fYe fYe @@ -111898,14 +111807,14 @@ fYe fYe fYe fYe -vxX -ilp -ilp -ilp +bmG +iZR +iZR +iZR uOo aku -ilp -ilp +iZR +iZR jTB dkr hbH @@ -111922,7 +111831,7 @@ ofG gOY cxg cxg -vxX +bmG nbu aXt aXt @@ -112144,25 +112053,25 @@ dUc dUc dUc dUc -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG fYe fYe fYe fYe fYe fYe -ilp -ilp +iZR +iZR ieo iSU uOo uro rji -ilp +iZR jTB sqJ wiT @@ -112179,7 +112088,7 @@ rYe gOY gOY cxg -vxX +bmG nbu nbu nbu @@ -112401,9 +112310,9 @@ cLf cLf cLf cLf -vxX -vxX -vxX +bmG +bmG +bmG fYe fYe fYe @@ -112413,13 +112322,13 @@ cLf cLf fYe rji -ilp +iZR vfR aku uOo aku -ilp -ilp +iZR +iZR jTB dEn lIn @@ -112436,7 +112345,7 @@ fDz gqV gOY cxg -vxX +bmG nbu pIV dLf @@ -112659,7 +112568,7 @@ cLf cLf cLf cLf -vxX +bmG cLf cLf dUc @@ -112675,8 +112584,8 @@ aku aku uOo aku -ilp -ilp +iZR +iZR jTB gbV jqY @@ -112693,7 +112602,7 @@ dyd qDM gOY cxg -vxX +bmG nbu pIV mBg @@ -112750,8 +112659,8 @@ aTv aTv cpG cpG -vxX -vxX +bmG +bmG cLf cLf cLf @@ -112932,8 +112841,8 @@ aku pkw uOo aku -ilp -ilp +iZR +iZR jTB wKR wKR @@ -112950,7 +112859,7 @@ aWM vzP gOY cxg -vxX +bmG nbu pIV pIV @@ -113007,8 +112916,8 @@ aYf aYf krW cpG -vxX -vxX +bmG +bmG cLf cLf cLf @@ -113182,7 +113091,7 @@ cLf cLf cLf fYe -vxX +bmG rji nLT aku @@ -113190,7 +113099,7 @@ aku uOo aku ieo -ilp +iZR jTB jTB qXE @@ -113207,7 +113116,7 @@ lfq mDx gOY cxg -vxX +bmG nbu nbu nbu @@ -113264,8 +113173,8 @@ aYf eRD eRD cpG -vxX -vxX +bmG +bmG cLf cLf cLf @@ -113438,17 +113347,17 @@ cLf cLf cLf cLf -vxX -vxX -ilp +bmG +bmG +iZR pkw aku aku uOo aku vfR -ilp -ilp +iZR +iZR jTB jTB jTB @@ -113464,7 +113373,7 @@ sLr mDx cxg cxg -vxX +bmG nbu msY nGp @@ -113521,8 +113430,8 @@ aYf eRD lPp cpG -vxX -vxX +bmG +bmG cLf cLf cLf @@ -113721,7 +113630,7 @@ lfq nkM cxg cxg -vxX +bmG nbu msY qNM @@ -113778,8 +113687,8 @@ prc prc prc cpG -vxX -vxX +bmG +bmG cLf cLf cLf @@ -113978,7 +113887,7 @@ vib vMR dUc cxg -vxX +bmG nbu msY msY @@ -114035,8 +113944,8 @@ prc prc prc cpG -vxX -vxX +bmG +bmG cLf cLf cLf @@ -114235,7 +114144,7 @@ egV vMR dUc cxg -vxX +bmG nbu nbu nbu @@ -114292,8 +114201,8 @@ cpG cpG cpG cpG -vxX -vxX +bmG +bmG cLf cLf cLf @@ -114492,12 +114401,12 @@ nbS vMR dUc cLf -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG dUc wRN fdC @@ -114524,7 +114433,7 @@ kGZ woo kUX uFC -vxX +bmG uFC cUD nPW @@ -114543,14 +114452,14 @@ xwD cvL psF uFC -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG kxB kxB -vxX -vxX +bmG +bmG cLf cLf cLf @@ -114726,8 +114635,8 @@ pkl pkl pkl pkl -ilp -ilp +iZR +iZR ieo aku aku @@ -114750,11 +114659,11 @@ nkM dUc cLf dUc -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG dUc fTX rLK @@ -114780,8 +114689,8 @@ edL kGZ wlG kUX -vxX -vxX +bmG +bmG uFC pbD nPW @@ -114806,8 +114715,8 @@ gjZ sqZ uuN kxB -vxX -vxX +bmG +bmG cLf cLf cLf @@ -114980,12 +114889,12 @@ cLf cLf cLf cLf -ilp -ilp -ilp -ilp -ilp -ilp +iZR +iZR +iZR +iZR +iZR +iZR vfR pkw aku @@ -115007,12 +114916,12 @@ moe dUc cLf dUc -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG dUc eTZ dUc @@ -115037,8 +114946,8 @@ cEh kGZ pul kUX -vxX -vxX +bmG +bmG uFC biG nPW @@ -115063,7 +114972,7 @@ mlk dqK sqZ kxB -vxX +bmG cLf cLf cLf @@ -115234,17 +115143,17 @@ fYe fYe wfz dUc -vxX +bmG dUc dUc -ilp -ilp -ilp -ilp -ilp -ilp -ilp -ilp +iZR +iZR +iZR +iZR +iZR +iZR +iZR +iZR aku aku aku @@ -115268,8 +115177,8 @@ dUc dUc dUc dUc -vxX -vxX +bmG +bmG nbu jWP wVI @@ -115294,8 +115203,8 @@ nPf kGZ qih kUX -vxX -vxX +bmG +bmG uFC lCu pxu @@ -115320,7 +115229,7 @@ mlk mlk wtF kxB -vxX +bmG cLf cLf cLf @@ -115486,21 +115395,21 @@ cLf cLf cLf cLf -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG fYe fYe cLf cLf cLf -ilp -ilp -ilp -ilp +iZR +iZR +iZR +iZR cLf -ilp +iZR obA lJq tsz @@ -115525,8 +115434,8 @@ cLf cLf cLf dUc -vxX -vxX +bmG +bmG nbu jxx bHa @@ -115577,7 +115486,7 @@ mlk dqK wtF kxB -vxX +bmG cLf cLf cLf @@ -115744,9 +115653,9 @@ cLf cLf cLf uif -vxX -vxX -vxX +bmG +bmG +bmG uif cLf cLf @@ -115782,8 +115691,8 @@ cLf cLf cLf dUc -vxX -vxX +bmG +bmG nbu szc azx @@ -115834,8 +115743,8 @@ mlk dqK wtF kxB -vxX -vxX +bmG +bmG cLf cLf cLf @@ -116000,10 +115909,10 @@ shs shs shs dUc -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG fYe cLf cLf @@ -116012,9 +115921,9 @@ cLf cLf cLf cLf -vxX -vxX -vxX +bmG +bmG +bmG obA lJq jBM @@ -116039,8 +115948,8 @@ cLf cLf cLf dUc -vxX -vxX +bmG +bmG nbu szc szc @@ -116066,7 +115975,7 @@ kUX kUX kUX dUc -vxX +bmG uFC spr xcm @@ -116090,9 +115999,9 @@ mlk mlk mlk wtF -vxX -vxX -vxX +bmG +bmG +bmG cLf cLf cLf @@ -116269,9 +116178,9 @@ cLf cLf cLf cLf -vxX -vxX -vxX +bmG +bmG +bmG obA cLf cPl @@ -116296,8 +116205,8 @@ cLf cLf cLf dUc -vxX -vxX +bmG +bmG nbu nbu nbu @@ -116311,7 +116220,7 @@ nbu nbu nbu nbu -vxX +bmG mUQ cLf dUc @@ -116320,10 +116229,10 @@ cLf cLf dUc cLf -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG uFC uFC jnY @@ -116347,9 +116256,9 @@ dqK mlk dqK wtF -vxX -vxX -vxX +bmG +bmG +bmG cLf cLf cLf @@ -116527,8 +116436,8 @@ cLf cLf cLf cLf -vxX -vxX +bmG +bmG obA cLf cLf @@ -116554,17 +116463,17 @@ cLf cLf dUc cLf -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe fYe @@ -116578,10 +116487,10 @@ cLf dUc cLf cLf -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG dUc cLf mDV @@ -116604,9 +116513,9 @@ dqK dqK dqK wtF -vxX -vxX -vxX +bmG +bmG +bmG cLf cLf cLf @@ -116784,8 +116693,8 @@ tyd cLf cLf cLf -vxX -vxX +bmG +bmG etW cLf cLf @@ -116812,22 +116721,22 @@ cLf dUc cLf cLf -vxX +bmG cLf dUc -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe -vxX +bmG mUQ -vxX +bmG dUc cLf cLf @@ -116836,9 +116745,9 @@ dUc cLf cLf cLf -vxX -vxX -vxX +bmG +bmG +bmG dUc cLf mDV @@ -116861,8 +116770,8 @@ dqK mlk dqK wtF -vxX -vxX +bmG +bmG cLf cLf cLf @@ -117075,16 +116984,16 @@ dUc cLf cLf cLf -vxX -vxX +bmG +bmG cLf cLf cLf -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG dUc cLf cLf @@ -117092,10 +117001,10 @@ cLf dUc cLf cLf -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG dUc dUc mDV @@ -117110,7 +117019,7 @@ adc ncv ncm uFC -vxX +bmG cxg cxg xzT @@ -117118,8 +117027,8 @@ tgj tgj tgj rwE -vxX -vxX +bmG +bmG cLf cLf cLf @@ -117340,18 +117249,18 @@ cLf cLf cLf cLf -vxX -vxX +bmG +bmG dUc iUF iUF iUF dUc -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG cLf cLf cLf @@ -117367,16 +117276,16 @@ uvN wQz kiW uFC -vxX -vxX -vxX +bmG +bmG +bmG cxg cxg cxg cxg -vxX -vxX -vxX +bmG +bmG +bmG cLf cLf cLf @@ -117605,8 +117514,8 @@ cLf cLf cLf cLf -vxX -vxX +bmG +bmG cLf mUQ fYe @@ -117625,15 +117534,15 @@ aQo kEu uFC vaU -vxX -vxX -vxX +bmG +bmG +bmG fYe fYe -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG cLf cLf cLf @@ -117869,7 +117778,7 @@ uVI fYe fYe fYe -vxX +bmG uFC uFC kEu @@ -117881,15 +117790,15 @@ kEu kEu uFC uFC -vxX -vxX -vxX +bmG +bmG +bmG mUQ uVI uVI mUQ -vxX -vxX +bmG +bmG cLf cLf cLf @@ -118126,8 +118035,8 @@ uVI uVI uVI mUQ -vxX -vxX +bmG +bmG uFC uFC uFC @@ -118137,10 +118046,10 @@ uFC uFC uFC uFC -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG fYe fYe fYe @@ -118385,18 +118294,18 @@ cLf cLf cLf cLf -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG cLf cLf fYe @@ -139440,12 +139349,12 @@ hhX hhX hhX hhX -vxX -vxX +bmG +bmG hhX hhX -vxX -vxX +bmG +bmG hhX hhX hhX @@ -139695,15 +139604,15 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hhX hhX hhX @@ -139950,21 +139859,21 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG mUQ kLL unk -vxX +bmG hhX hhX hhX @@ -140205,24 +140114,24 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe qHE -vxX -vxX -vxX +bmG +bmG +bmG hhX hhX hhX @@ -140462,25 +140371,25 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG vYz aUf vYz vYz vYz -vxX +bmG fYe fYe fYe fYe -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG hhX hhX hhX @@ -140719,8 +140628,8 @@ hhX hhX hhX hhX -vxX -vxX +bmG +bmG vYz aUf vYz @@ -140732,12 +140641,12 @@ vYz aUf aUf aUf -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG fYe -vxX +bmG hhX hhX hhX @@ -140990,9 +140899,9 @@ ory aTE aUf aUf -vxX -vxX -vxX +bmG +bmG +bmG fYe fYe hhX @@ -141247,10 +141156,10 @@ qyq fUv pkA aUf -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG fYe hhX hhX @@ -141506,8 +141415,8 @@ wMe wnw fYe fYe -vxX -vxX +bmG +bmG hhX hhX hhX @@ -143560,7 +143469,7 @@ eZo wCR vYz vYz -vxX +bmG fYe fYe hhX @@ -143816,9 +143725,9 @@ eSs iXA vYz vYz -vxX -vxX -vxX +bmG +bmG +bmG fYe hhX hhX @@ -144075,7 +143984,7 @@ iVG eYP gHN gHN -vxX +bmG hhX hhX hhX @@ -145088,7 +144997,7 @@ hhX hhX hhX hhX -vxX +bmG vYz fJV wdI @@ -145344,8 +145253,8 @@ hhX hhX hhX hhX -vxX -vxX +bmG +bmG vYz vYz rap @@ -145602,8 +145511,8 @@ hhX hhX hhX hhX -vxX -vxX +bmG +bmG vYz aUf aUf @@ -145619,9 +145528,9 @@ hhX hhX jVV hhX -vxX -vxX -vxX +bmG +bmG +bmG hhX hhX fZF @@ -145876,8 +145785,8 @@ hhX fYe fYe fYe -vxX -vxX +bmG +bmG fYe fYe qHE @@ -146110,10 +146019,10 @@ oID jVV hhX hhX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG hhX hhX hhX @@ -146365,20 +146274,20 @@ hhX hhX hhX jVV -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hhX hhX -vxX -vxX +bmG +bmG iJm iJm eYP @@ -146389,14 +146298,14 @@ dvC mUQ fYe fYe -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe fYe @@ -146622,19 +146531,19 @@ hhX hhX hhX hhX -vxX -vxX -vxX +bmG +bmG +bmG qAp fYe -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG mUQ kLL cts @@ -146646,14 +146555,14 @@ iJm mUQ mUQ fYe -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe fYe @@ -146879,19 +146788,19 @@ hhX hhX hhX hhX -vxX -vxX -vxX +bmG +bmG +bmG uif uif -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG iJm iJm foL @@ -146900,31 +146809,31 @@ gZt dPG foL iJm -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG fnh fnh fnh fnh fnh fnh -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG fYe fYe fYe fYe -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG hhX hhX hhX @@ -147108,9 +147017,9 @@ hhX hhX hhX hhX -vxX -vxX -vxX +bmG +bmG +bmG hhX hhX hhX @@ -147135,20 +147044,20 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe hSF -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG iJm iJm foL @@ -147158,31 +147067,31 @@ plV foL dcl qHE -vxX -vxX -vxX +bmG +bmG +bmG fnh vTt dBK aQD vTt fnh -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hhX hhX hhX @@ -147365,10 +147274,10 @@ fYe fYe fYe hhX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG hhX hhX hhX @@ -147392,8 +147301,8 @@ hhX hhX hhX hhX -vxX -vxX +bmG +bmG gNV gNV gNV @@ -147402,10 +147311,10 @@ gNV gNV gNV uif -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG iJm iJm foL @@ -147424,22 +147333,22 @@ mlK mlK fSp fnh -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -jjp -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +ldy +bmG +bmG hhX hhX hhX @@ -147619,13 +147528,13 @@ fYe fYe fYe fYe -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG hhX hhX hhX @@ -147650,7 +147559,7 @@ aZg aZg aZg aZg -vxX +bmG gNV bMZ tKm @@ -147658,11 +147567,11 @@ lib qmf iSw gNV -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG iJm iJm eYP @@ -147681,22 +147590,22 @@ mlK mlK dBK fnh -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hhX hhX hhX @@ -147873,28 +147782,28 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG lLo sMT lLo @@ -147907,7 +147816,7 @@ umg umg umg umg -vxX +bmG gNV rwu eiI @@ -147915,11 +147824,11 @@ hvV kkK pha gNV -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG iJm iJm iJm @@ -147928,7 +147837,7 @@ wku plV gHN fYe -qoN +lZW fnh diz jMW @@ -147938,8 +147847,8 @@ aQD dBK vTt fnh -vxX -vxX +bmG +bmG fnh fnh fnh @@ -147947,12 +147856,12 @@ fnh fnh fnh fnh -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG hhX hhX hhX @@ -148130,27 +148039,27 @@ fNW hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG pEH pEH pEH -vxX +pEH +bmG iaN iaN aJP @@ -148172,12 +148081,12 @@ tXr qia qtT gNV -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG iJm uKm eYP @@ -148185,7 +148094,7 @@ pmp ldf eYP fnh -qoN +lZW fnh fnh jMW @@ -148204,10 +148113,10 @@ fnh wXY whx fnh -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG hhX hhX hhX @@ -148387,26 +148296,26 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +fWn pEH -pEH -bBo -bBo +fWn +fWn +fWn iaN iaN iig @@ -148430,19 +148339,19 @@ gNV gNV gNV dLR -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG fnh mUA iLo lYg oHC fnh -qoN +lZW fnh lTj jMW @@ -148461,10 +148370,10 @@ mkc kzS uym fnh -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG hhX hhX hhX @@ -148646,24 +148555,24 @@ fYe fYe fYe fYe -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -pEH +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +fWn +fWn ixo dcg -nxd +sTW iaN kVX bUJ @@ -148691,8 +148600,8 @@ vLs aCv vLs aCv -qoN -qoN +lZW +lZW kGS rPT atT @@ -148718,10 +148627,10 @@ fnh qlO guP fnh -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG hhX hhX hhX @@ -148903,24 +148812,24 @@ hhX hhX fYe fYe -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG pEH +sUW xok -ljG -fFE +aWs +gkg iaN mPH dhv @@ -148975,10 +148884,10 @@ fnh fnh fnh fnh -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG hhX hhX hhX @@ -149160,23 +149069,23 @@ jVV jVV jVV fYe -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -pEH -cbn -ljG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +fWn +mSn +efm +qXY qXY iaN gEQ @@ -149232,10 +149141,10 @@ nFS fnh dxD aRn -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG hhX hhX hhX @@ -149415,25 +149324,25 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG pEH -nuu -ilO +huG +ekO +qYf qXY wds uRO @@ -149458,12 +149367,12 @@ fLe xRj xXY kYT -qoN -qoN -qoN +lZW +lZW +lZW aCv wWJ -qoN +lZW aCv ygt dXH @@ -149490,10 +149399,10 @@ fnh ibx ibx rFK -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG fYe fYe fYe @@ -149686,9 +149595,9 @@ dOG dOG dOG dOG -vxX -vxX -bBo +bmG +fWn +huG efm ljG qXY @@ -149718,9 +149627,9 @@ wOU wOU wOU kYT -qoN +lZW wWJ -qoN +lZW bGk bGk tuL @@ -149747,12 +149656,12 @@ fnh fnh uXS fnh -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe hhX @@ -149943,12 +149852,12 @@ qog gcQ bEn dOG -vxX -vxX -bBo -iee +bmG +pEH +luS +vUA bPu -bBo +fWn iaN fON jds @@ -149975,9 +149884,9 @@ dCv fxF fxF kYT -qoN +lZW taj -qoN +lZW bGk mqc mfw @@ -150004,14 +149913,14 @@ qrg eQI iMT fnh -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hhX hhX hhX @@ -150200,12 +150109,12 @@ dOG dOG mkN dOG -vxX -vxX -vxX -bBo -bBo -bBo +bmG +bmG +fWn +fWn +fWn +fWn iaN iaN dlY @@ -150234,7 +150143,7 @@ fxF kYT wWJ wWJ -qoN +lZW bGk sHo mJD @@ -150262,13 +150171,13 @@ eAq lGe fnh fnh -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG fYe -vxX -vxX +bmG +bmG hhX hhX hhX @@ -150457,12 +150366,12 @@ ouF ouF lbr dOG -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +pEH +fWn +pEH iaN qIa fBm @@ -150490,8 +150399,8 @@ mYd uUP kYT wWJ -qoN -qoN +lZW +lZW bGk jfq dhj @@ -150519,9 +150428,9 @@ rcy cIi siK fnh -vxX -vxX -vxX +bmG +bmG +bmG fYe fYe fYe @@ -150714,12 +150623,12 @@ gAQ eBa eWJ dOG -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG iaN iaN poi @@ -150776,9 +150685,9 @@ qpR lGe oJJ fnh -vxX -vxX -vxX +bmG +bmG +bmG fYe hhX hhX @@ -150971,14 +150880,14 @@ jqd jmU mKW dOG -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG poi xeh jir @@ -151033,9 +150942,9 @@ fnh fnh fnh fnh -vxX -vxX -vxX +bmG +bmG +bmG fYe hhX hhX @@ -151228,14 +151137,14 @@ dOG dOG dOG dOG -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG poi rEK poi @@ -151257,9 +151166,9 @@ wOU wAm lzu wOU -vxX -vxX -qoN +bmG +bmG +lZW wWJ kYT auB @@ -151290,9 +151199,9 @@ vYQ ezM qMn iMq -vxX -vxX -vxX +bmG +bmG +bmG hhX hhX hhX @@ -151484,15 +151393,15 @@ xey egY rai uZc -vxX -vxX +bmG +bmG fYe fYe fYe -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG poi tdq xTb @@ -151514,9 +151423,9 @@ wOU cNr ugI wOU -vxX -vxX -qoN +bmG +bmG +lZW wWJ kYT xtb @@ -151547,9 +151456,9 @@ spA spA gBY iMq -vxX -vxX -vxX +bmG +bmG +bmG fYe hhX hhX @@ -151741,8 +151650,8 @@ cJZ rai rai uZc -vxX -vxX +bmG +bmG wkX fYe fYe @@ -151771,9 +151680,9 @@ wOU ntd pZj wOU -vxX -vxX -qoN +bmG +bmG +lZW wWJ kYT auB @@ -151804,9 +151713,9 @@ iom tjn aRZ iMq -vxX -vxX -vxX +bmG +bmG +bmG hhX hhX hhX @@ -151998,7 +151907,7 @@ uZc uZc uZc uZc -vxX +bmG hen hen hen @@ -152009,7 +151918,7 @@ fYe fYe fYe fYe -vxX +bmG sdc oZQ oZQ @@ -152029,8 +151938,8 @@ epK epK epK fnh -qoN -qoN +lZW +lZW taj kYT jEu @@ -152061,9 +151970,9 @@ dpj cUm tve iMq -vxX -vxX -vxX +bmG +bmG +bmG fYe fYe hhX @@ -152225,10 +152134,10 @@ hhX hhX fYe fYe -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG jOV skb wSc @@ -152252,10 +152161,10 @@ xtp oPN bWJ uZc -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG hen hen hen @@ -152266,7 +152175,7 @@ hen fYe fYe fYe -vxX +bmG sdc oZQ oZQ @@ -152286,7 +152195,7 @@ pkt xMY aDW fnh -qoN +lZW rNJ rNJ kYT @@ -152318,9 +152227,9 @@ niI mnA jKj iMq -vxX -vxX -vxX +bmG +bmG +bmG fYe fYe fYe @@ -152482,10 +152391,10 @@ hhX hhX fYe fYe -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG jOV skb wSc @@ -152509,8 +152418,8 @@ crb iqE mMp hED -vxX -vxX +bmG +bmG fYe fYe hen @@ -152523,7 +152432,7 @@ hen fYe fYe fYe -vxX +bmG sdc oZQ oZQ @@ -152547,7 +152456,7 @@ bgY bgY bgY dog -qoN +lZW fnh wnL oFa @@ -152575,9 +152484,9 @@ iMq beR iMq iMq -vxX -vxX -vxX +bmG +bmG +bmG fYe fYe hhX @@ -152739,10 +152648,10 @@ hhX hhX fYe fYe -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG jOV kDb ctL @@ -152752,10 +152661,10 @@ nvR fDi uEX jOV -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG mIW sUM rhc @@ -152767,7 +152676,7 @@ ylZ buu hED hED -vxX +bmG wkX fYe hen @@ -152780,7 +152689,7 @@ hen fYe fYe fYe -vxX +bmG sdc sdc sdc @@ -152800,11 +152709,11 @@ mlh jpx aLE fnh -qoN +lZW rNJ koX dog -qoN +lZW fnh igq igq @@ -152832,9 +152741,9 @@ iMq avC oEC iMq -vxX -vxX -vxX +bmG +bmG +bmG fYe fYe fYe @@ -152996,7 +152905,7 @@ hhX hhX fYe fYe -vxX +bmG hHw hHw hHw @@ -153009,10 +152918,10 @@ jOV jOV jOV jOV -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG mIW thT thT @@ -153024,7 +152933,7 @@ ccI cPP tTz hED -vxX +bmG fYe fYe hen @@ -153036,9 +152945,9 @@ hen hen fYe fYe -vxX -vxX -vxX +bmG +bmG +bmG bNL xsj lFN @@ -153061,7 +152970,7 @@ aCv cGs vFq dog -qoN +lZW fnh evQ evQ @@ -153089,9 +152998,9 @@ iMq lsq iBP iMq -vxX -vxX -vxX +bmG +bmG +bmG fYe fYe hhX @@ -153262,14 +153171,14 @@ wSc rwW wSc jOV -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG mIW sTS thT @@ -153277,11 +153186,11 @@ thT hED stF uaT -bZI +mmX ipc tME hED -vxX +bmG fYe hen hen @@ -153293,9 +153202,9 @@ hen hen fYe fYe -vxX -vxX -vxX +bmG +bmG +bmG bNL xWQ cVb @@ -153314,11 +153223,11 @@ gnE xeA otY fnh -qoN +lZW rNJ blM dog -qoN +lZW fnh evQ evQ @@ -153346,9 +153255,9 @@ iMq frv cxP iMq -vxX -vxX -vxX +bmG +bmG +bmG fYe fYe hhX @@ -153519,14 +153428,14 @@ xbr qFS wSc jOV -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG mIW thT thT @@ -153538,21 +153447,21 @@ tGw ipc eQJ hED -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG hen hen fYe fYe -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG bNL exg bcj @@ -153571,11 +153480,11 @@ qBu fIm otY fnh -qoN -qoN +lZW +lZW rNJ kpx -qoN +lZW fnh gWX bAV @@ -153603,9 +153512,9 @@ aOm aOm aOm aOm -vxX -vxX -vxX +bmG +bmG +bmG fYe hhX hhX @@ -153776,14 +153685,14 @@ hHw dAq jOV jOV -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG mIW thT thT @@ -153795,21 +153704,21 @@ rAq xNy iUV hED -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe fYe fYe -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG bNL xgQ oRE @@ -153828,8 +153737,8 @@ vOu vOu vOu fnh -qoN -qoN +lZW +lZW rNJ kpx qcU @@ -153860,9 +153769,9 @@ fnU udG xzP oZt -vxX -vxX -vxX +bmG +bmG +bmG fYe hhX hhX @@ -154034,13 +153943,13 @@ aCb aCb hHw hHw -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG mIW mIW mIW @@ -154052,21 +153961,21 @@ hED hED hED hED -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe fYe -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG bNL hxg bcj @@ -154079,13 +153988,13 @@ tFD wjC rPt sdc -vxX -vxX -vxX -vxX -vxX -vxX -qoN +bmG +bmG +bmG +bmG +bmG +bmG +lZW rNJ rNJ kpx @@ -154105,7 +154014,7 @@ wYo cLD nzb xnq -wij +muE xhJ oZt fQG @@ -154117,10 +154026,10 @@ aRN nqD hZN oZt -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG hhX hhX hhX @@ -154291,39 +154200,39 @@ uRG uRG uRG hHw -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hED npn okF aum hED -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG bNL pNs dpH @@ -154336,8 +154245,8 @@ sdc sdc sdc sdc -vxX -vxX +bmG +bmG fnh fnh fnh @@ -154346,7 +154255,7 @@ fnh qcU kpx kpx -qoN +lZW fnh sxa mpp @@ -154374,10 +154283,10 @@ fnU xzP nrW oZt -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG hhX hhX hhX @@ -154548,53 +154457,53 @@ uRG uRG uRG hHw -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hED ocl kkC phJ hED -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG bNL bNL bNL bNL bNL bNL -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fnh bmu tMP @@ -154603,7 +154512,7 @@ pSV kpx bzu qcU -qoN +lZW fnh igq igq @@ -154631,9 +154540,9 @@ gcy aRN aRN oZt -vxX +bmG fYe -vxX +bmG mUQ jOM hhX @@ -154805,66 +154714,66 @@ hHw hHw hHw hHw -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hED hED hED hED hED -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe fYe -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG gYW gYW gYW gYW -vxX -vxX -vxX +bmG +bmG +bmG fnh bmu bMl uJA fnh -qoN +lZW rNJ doZ -qoN -vxX -vxX -vxX -vxX +lZW +bmG +bmG +bmG +bmG igq igq igq @@ -154884,11 +154793,11 @@ teV oZt rix ixR -uzT -rIX +qro +hOh vau oZt -vxX +bmG kqj xcq gVN @@ -155061,41 +154970,41 @@ hhX hhX hhX okm -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe fYe -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG gYW gYW gYW @@ -155106,25 +155015,25 @@ gYW jbP gLD gYW -vxX -vxX -vxX +bmG +bmG +bmG fnh fnh fnh fnh fnh -qoN +lZW aCv tBL aCv -lDQ -lDQ -lDQ -lDQ -vxX -vxX -vxX +iaA +iaA +iaA +iaA +bmG +bmG +bmG gvw gvw gvw @@ -155318,41 +155227,41 @@ hhX hhX hhX okm -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe mEN -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG gYW dTy vsD @@ -155366,25 +155275,25 @@ gYW gYW gYW gYW -lDQ -lDQ -lDQ -lDQ +iaA +iaA +iaA +iaA nev dtt dtt dtt dtt dtt -lDQ -lDQ -lDQ -vxX -vxX -vxX -vxX -vxX -vxX +iaA +iaA +iaA +bmG +bmG +bmG +bmG +bmG +bmG gvw gjt jEf @@ -155392,9 +155301,9 @@ kQV uKv evg gvw -vxX -vxX -vxX +bmG +bmG +bmG oZt jCU tkh @@ -155402,10 +155311,10 @@ cgw fMY uHE oZt -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG jVV hhX hhX @@ -155575,41 +155484,41 @@ fYe hhX hhX okm -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe unk -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG gYW fdQ oMn @@ -155631,17 +155540,17 @@ dtt dtt dtt nev -lDQ +iaA dtt -lDQ -lDQ -lDQ -vxX -vxX -vxX -vxX -vxX -vxX +iaA +iaA +iaA +bmG +bmG +bmG +bmG +bmG +bmG gvw gvw gvw @@ -155649,7 +155558,7 @@ gvw gvw gvw gvw -vxX +bmG unk unk oZt @@ -155659,10 +155568,10 @@ oZt oZt oZt oZt -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG hhX hhX hhX @@ -155832,37 +155741,37 @@ pnS hhX hhX okm -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe iRm fYe -vxX -vxX -vxX +bmG +bmG +bmG gYW gYW gYW @@ -155887,26 +155796,26 @@ dtt dtt dtt dtt -lDQ -lDQ +iaA +iaA dtt dtt nev mGn -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -dGk +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +dKd unk hhX hhX @@ -155914,10 +155823,10 @@ hhX hhX hhX unk -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG hhX hhX hhX @@ -156089,36 +155998,36 @@ fYe hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe -vxX +bmG unk fYe fYe -vxX +bmG fYe oSk esQ @@ -156137,15 +156046,15 @@ wjI wjI wjI gYW -lDQ -lDQ -lDQ +iaA +iaA +iaA dtt dtt -lDQ +iaA dtt uXD -lDQ +iaA dtt dtt dtt @@ -156157,24 +156066,24 @@ azk azk azk azk -vxX -vxX +bmG +bmG gMk -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG hhX hhX hhX hhX hhX unk -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG hhX hhX hhX @@ -156346,32 +156255,32 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe -vxX -vxX +bmG +bmG fYe fYe fYe @@ -156396,7 +156305,7 @@ dSl gYW uXD uXD -lDQ +iaA ldo ldo ldo @@ -156412,26 +156321,26 @@ cHs uXD uXD uXD -vxX +bmG azk azk azk azk azk -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG fYe hhX hhX hhX hhX unk -tXg -vxX -vxX -vxX +jvx +bmG +bmG +bmG hhX hhX hhX @@ -156603,37 +156512,37 @@ hhX hhX hhX okm -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe -vxX -vxX +bmG +bmG fYe fYe fYe fYe -vxX +bmG oSk wAv wAv @@ -156669,26 +156578,26 @@ qIf vwL pbn uXD -vxX -vxX +bmG +bmG uet gMk -vxX +bmG azk azk -vxX -vxX -vxX +bmG +bmG +bmG fYe hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG hhX hhX hhX @@ -156860,33 +156769,33 @@ hhX fNW hhX okm -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe -vxX -vxX +bmG +bmG fYe gYW gYW @@ -156928,24 +156837,24 @@ dFc uXD uXD uXD -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG azk -vxX -vxX -vxX +bmG +bmG +bmG fYe hhX hhX hhX hhX unk -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG hhX hhX hhX @@ -157117,34 +157026,34 @@ hhX hhX hhX okm -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe -vxX -vxX +bmG +bmG gYW dum hdN @@ -157185,24 +157094,24 @@ sZF pLP kEs uXD -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG azk -vxX -vxX +bmG +bmG unk unk unk -vxX +bmG unk unk unk -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG hhX hhX hhX @@ -157374,34 +157283,34 @@ hhX hhX hhX okm -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe -vxX -vxX -vxX +bmG +bmG +bmG gYW kwW tQy @@ -157442,23 +157351,23 @@ sZF pLP pLP uXD -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG azk azk azk azk unk dra -vxX -nuH -vxX -vxX -vxX -bme -vxX +bmG +nQS +bmG +bmG +bmG +tkW +bmG hhX hhX hhX @@ -157631,34 +157540,34 @@ hhX hhX hhX okm -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe -vxX -vxX +bmG +bmG gYW hbQ saY @@ -157701,17 +157610,17 @@ uXD uXD uKm uKm -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG azk iEl gMk uet uet -vxX +bmG gMk mGM unk @@ -157888,34 +157797,34 @@ hhX hhX okm okm -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe fYe -vxX -vxX +bmG +bmG gYW gYW gYW @@ -157958,14 +157867,14 @@ gMk dij atB uKm -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG azk azk unk -vxX +bmG gMk gMk gMk @@ -158145,35 +158054,35 @@ hhX hhX okm okm -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG unk unk gbv any unk unk -vxX -vxX +bmG +bmG gYW kGy mMN @@ -158214,18 +158123,18 @@ uXD uet gMk mZs -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG azk -vxX -vxX -vxX +bmG +bmG +bmG gMk -vxX -vxX +bmG +bmG ent bCg unk @@ -158402,26 +158311,26 @@ hhX hhX okm okm -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG unk unk fYe @@ -158430,7 +158339,7 @@ fYe fYe unk unk -vxX +bmG gYW kGy mMN @@ -158471,22 +158380,22 @@ rzJ gMk gMk gMk -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG azk gMk -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hhX hhX hhX @@ -158659,26 +158568,26 @@ hhX hhX okm okm -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe dsG fYe fYe fYe -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG unk fYe fYe @@ -158728,22 +158637,22 @@ uXD uXD uXD gMk -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG azk -vxX -vxX -vxX +bmG +bmG +bmG rnk rnk rnk rnk rnk rnk -vxX +bmG hhX hhX hhX @@ -158916,13 +158825,13 @@ hhX hhX okm okm -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe hen @@ -158934,8 +158843,8 @@ fYe fYe dsG dsG -vxX -vxX +bmG +bmG unk fYe ivx @@ -158985,15 +158894,15 @@ pLP kEs uXD gMk -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG gMk azk -vxX -vxX -vxX +bmG +bmG +bmG rnk vGs dwI @@ -159173,13 +159082,13 @@ hhX hhX hhX fYe -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe hen @@ -159243,14 +159152,14 @@ pLP uXD gMk gMk -vxX -vxX -vxX +bmG +bmG +bmG azk azk gMk uet -vxX +bmG rnk iQt noh @@ -159430,13 +159339,13 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe hen @@ -159498,13 +159407,13 @@ wLu uXD uXD uXD -vxX +bmG gMk uet uet -vxX +bmG azk -vxX +bmG gMk gMk gMk @@ -159687,13 +159596,13 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe hen @@ -159715,8 +159624,8 @@ fYe fYe unk unk -vxX -vxX +bmG +bmG jCD jCD jCD @@ -159754,17 +159663,17 @@ lvw xGo oEp ibx -vxX -vxX +bmG +bmG azk azk azk azk azk -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG rnk bzj eMq @@ -159944,13 +159853,13 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe fYe @@ -159964,19 +159873,19 @@ hen hen hen fYe -vxX +bmG unk unk unk unk unk unk -vxX -vxX -vxX -vxX -vxX -tAa +bmG +bmG +bmG +bmG +bmG +vEw gYW gYW gYW @@ -160014,13 +159923,13 @@ ibx uet azk azk -vxX -vxX +bmG +bmG pfg -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG hhX rnk rnk @@ -160201,13 +160110,13 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe fYe @@ -160221,21 +160130,21 @@ hen hen hen fYe -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hwW dTe -tAa +vEw gYW gYW gYW @@ -160270,14 +160179,14 @@ ibx ibx ibx azk -vxX -vxX -vxX +bmG +bmG +bmG iDq -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG hhX hhX hhX @@ -160458,15 +160367,15 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe hen hen @@ -160478,23 +160387,23 @@ hen hen hen hen -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG oSk qGN dTe -tAa -tAa -tAa +vEw +vEw +vEw gYW gYW wjI @@ -160516,7 +160425,7 @@ fZv fZv vbY jGB -kpe +uCi slM feu xWd @@ -160715,15 +160624,15 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe hen @@ -160735,24 +160644,24 @@ hen hen hen hen -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fAV aIB dTe eyf eyf -tAa -tAa +vEw +vEw gYW wjI wjI @@ -160779,9 +160688,9 @@ qaE klJ lSD jGB -vxX +bmG pfg -vxX +bmG ibx ftX piS @@ -160972,15 +160881,15 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe hen @@ -160991,15 +160900,15 @@ hen hen hen hen -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG gYW gYW gYW @@ -161009,7 +160918,7 @@ pjn aWJ aWJ hwW -tAa +vEw gYW tXp gYW @@ -161038,7 +160947,7 @@ jGB jGB cOD uet -vxX +bmG ibx lgp hzF @@ -161229,15 +161138,15 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe hen @@ -161248,15 +161157,15 @@ hen hen hen hen -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG gYW gnx dTe @@ -161487,14 +161396,14 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe hen @@ -161505,15 +161414,15 @@ hen hen hen hen -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG gYW rLJ srv @@ -161523,7 +161432,7 @@ pLE tXp aWJ aIB -tAa +vEw gYW tXp gYW @@ -161744,14 +161653,14 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe fYe @@ -161762,15 +161671,15 @@ dsG fYe fYe fYe -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG gYW gYW hCT @@ -162002,33 +161911,33 @@ oID jVV jVV jVV -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG dsG -vxX -vxX -vxX +bmG +bmG +bmG fYe -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG gYW gYW gYW @@ -162274,21 +162183,21 @@ ttt oaF ttt ttt -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vIL +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +nzw aih fne dTe @@ -162535,17 +162444,17 @@ ttt ttt ttt ttt -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vIL +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +nzw pqB fne sUY @@ -162792,23 +162701,23 @@ bjn bjn rRY ttt -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vIL +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +nzw aih qCf ycw ksf hmF -tAa +vEw gYW wAv gYW @@ -163049,23 +162958,23 @@ tMp bjn nen ttt -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fne dTe dTe nMj nfj -tAa +vEw gYW wAv wAv @@ -163306,23 +163215,23 @@ wcH fib fDf ttt -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG lIZ dTe fne dTe -tAa +vEw gYW kIB gYW @@ -163579,7 +163488,7 @@ ycN wbT wub uMY -tAa +vEw gYW gYW gYW @@ -163836,9 +163745,9 @@ ycN unk unk unk -vxX -vxX -vxX +bmG +bmG +bmG gYW uSe cjp @@ -164090,12 +163999,12 @@ cHh kNJ vaC ycN -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG gYW uSe cjp @@ -164347,12 +164256,12 @@ hqg ukY vaC ycN -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG gYW gYW gYW @@ -164604,14 +164513,14 @@ kqS rtN jlI ycN -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG gYW wyK tuR @@ -164651,7 +164560,7 @@ hzF hzF hzF hzF -vxX +bmG jVV jVV jVV @@ -164861,14 +164770,14 @@ brV hQA yhW ycN -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG gYW kdc jYp @@ -164891,24 +164800,24 @@ mBw qxU fAT apQ -vxX -vxX +bmG +bmG gMk gMk -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hhX hhX hhX @@ -165118,14 +165027,14 @@ daK wad vaC ycN -vxX -vxX -vxX +bmG +bmG +bmG gMk gMk -vxX -vxX -vxX +bmG +bmG +bmG gYW imU mhD @@ -165148,26 +165057,26 @@ hPP rhW kNO apQ -vxX +bmG gMk gMk gMk -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hhX hhX hhX @@ -165375,14 +165284,14 @@ hqg ukY vaC ycN -vxX +bmG gMk gMk gMk gMk uet -vxX -vxX +bmG +bmG gYW gYW gYW @@ -165405,13 +165314,13 @@ apQ kOE rMQ apQ -vxX -vxX +bmG +bmG gMk gMk -vxX -vxX -vxX +bmG +bmG +bmG lAj lAj lAj @@ -165425,7 +165334,7 @@ lAj lAj lAj lAj -vxX +bmG fYe hhX hhX @@ -165639,9 +165548,9 @@ gMk gMk gMk gMk -vxX -vxX -tAa +bmG +bmG +vEw aWJ dTe dTe @@ -165662,13 +165571,13 @@ apQ kOE uDd apQ -vxX -vxX +bmG +bmG gMk gMk gMk -vxX -vxX +bmG +bmG lAj pBg xJT @@ -165682,7 +165591,7 @@ vmB ctv rPC lAj -vxX +bmG fYe hhX hhX @@ -165889,15 +165798,15 @@ vaC vaC vaC ycN -vxX -vxX +bmG +bmG gMk gMk gMk gMk gMk -vxX -vxX +bmG +bmG oSk nlZ dTe @@ -165919,13 +165828,13 @@ apQ kOE rMQ apQ -vxX -vxX +bmG +bmG gMk gMk gMk -vxX -vxX +bmG +bmG lAj ebz sbo @@ -165939,7 +165848,7 @@ uBn rts gdZ lAj -vxX +bmG fYe hhX hhX @@ -166115,7 +166024,7 @@ hhX hhX hhX hhX -vxX +bmG juw prr juw @@ -166146,16 +166055,16 @@ ycN ycN ycN ycN -vxX -vxX -vxX +bmG +bmG +bmG gMk gMk gMk gMk -vxX -vxX -tAa +bmG +bmG +vEw aWJ hUN dTe @@ -166176,9 +166085,9 @@ apQ kOE rMQ apQ -vxX -vxX -vxX +bmG +bmG +bmG gMk gMk lAj @@ -166196,7 +166105,7 @@ ajS ajS gdZ lAj -vxX +bmG fYe hhX hhX @@ -166372,51 +166281,51 @@ hhX hhX hhX hhX -vxX -vxX +bmG +bmG dsG -vxX -vxX +bmG +bmG dsG dsG -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG gMk gMk -vxX -vxX -vxX -vxX -tAa +bmG +bmG +bmG +bmG +vEw aWJ fAJ qaS -tAa +vEw apQ hCb rwX @@ -166433,9 +166342,9 @@ oNo vRt pXB apQ -vxX -vxX -vxX +bmG +bmG +bmG gMk rcP lAj @@ -166453,7 +166362,7 @@ ajS ajS gdZ lAj -vxX +bmG fYe hhX hhX @@ -166637,43 +166546,43 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG uet xUx -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG oSk lhO oSk oSk -tAa +vEw apQ dzQ vjT @@ -166690,8 +166599,8 @@ anZ jIf eaS apQ -vxX -vxX +bmG +bmG uet gMk obD @@ -166710,8 +166619,8 @@ ajS ajS bag lAj -vxX -vxX +bmG +bmG hhX hhX hhX @@ -166896,41 +166805,41 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG xUx uet -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG gMk gMk gMk gMk -vxX -vxX +bmG +bmG apQ qEn tRl @@ -166947,8 +166856,8 @@ rwU sTl apQ apQ -vxX -vxX +bmG +bmG gMk alx obD @@ -166967,8 +166876,8 @@ ajS ajS gdZ lAj -vxX -vxX +bmG +bmG hhX hhX hhX @@ -167153,41 +167062,41 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG unk -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG gMk gMk -vxX -vxX +bmG +bmG gMk gMk gMk gMk uet -vxX -vxX +bmG +bmG apQ apQ apQ @@ -167204,8 +167113,8 @@ apQ apQ apQ apQ -vxX -vxX +bmG +bmG gMk gMk sDP @@ -167224,7 +167133,7 @@ ajS ajS gdZ lAj -vxX +bmG fYe hhX hhX @@ -167412,58 +167321,58 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG gMk his gMk -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG gMk gMk -vxX +bmG gMk gMk gMk gMk gMk -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG gMk vDa rBU @@ -167481,7 +167390,7 @@ ajS ajS gdZ lAj -vxX +bmG fYe hhX hhX @@ -167669,57 +167578,57 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG voq jmp gMk xkI cGl -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG gMk gMk gMk gMk gMk gMk -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG vDa vDa vDa @@ -167738,7 +167647,7 @@ ajS ajS gdZ lAj -vxX +bmG hhX hhX hhX @@ -167926,56 +167835,56 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG syX cGl gMk syX gMk cGl -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG gMk gMk gMk -vxX +bmG gMk gMk gMk -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG gMk vDa gMk @@ -167995,7 +167904,7 @@ ajS ajS gdZ lAj -vxX +bmG hhX hhX hhX @@ -168183,11 +168092,11 @@ hhX umg asZ umg -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG ura syX qIA @@ -168195,22 +168104,22 @@ cGl gMk syX qIA -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG gMk gMk -vxX -vxX +bmG +bmG gMk gMk gMk @@ -168218,25 +168127,25 @@ gMk gMk gMk gMk -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG mUQ gMk gMk -vxX +bmG gMk vDa gMk -vxX +bmG lAj lAj lAj @@ -168252,7 +168161,7 @@ ajS ajS lxR lAj -vxX +bmG hhX hhX hhX @@ -168440,11 +168349,11 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG aHe gMk xkI @@ -168452,39 +168361,39 @@ syX jmp gMk cGl -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG gMk gMk gMk gMk gMk gMk -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG gMk iEl gMk @@ -168492,10 +168401,10 @@ gMk vDa vDa vDa -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG lAj fiI rts @@ -168509,10 +168418,10 @@ mRd sbo gdZ lAj -vxX +bmG fYe fYe -vxX +bmG hhX hhX hhX @@ -168697,50 +168606,50 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG syX cGl gMk gMk gMk -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG gMk gMk gMk -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG uet gMk iEl @@ -168748,11 +168657,11 @@ gMk gMk vDa gMk -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG lAj hXu xQe @@ -168769,7 +168678,7 @@ lAj fYe fYe fYe -vxX +bmG hhX hhX hhX @@ -168954,62 +168863,62 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG pfg pfg pfg -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG gMk gMk -vxX +bmG gMk uet -vxX -vxX +bmG +bmG gMk gMk -vxX +bmG gMk gMk mUQ -vxX -vxX +bmG +bmG vDa uet -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG lAj lAj lAj @@ -169026,7 +168935,7 @@ lAj fYe fYe fYe -vxX +bmG hhX hhX hhX @@ -169211,40 +169120,40 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG gMk gMk gMk -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG gMk gMk gMk @@ -169257,33 +169166,33 @@ gMk gMk gMk gMk -vxX -vxX -vxX +bmG +bmG +bmG vDa -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG gMk gMk gMk -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG fYe fYe fYe -vxX +bmG hhX hhX hhX @@ -169468,38 +169377,38 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG gMk gMk gMk -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG uet gMk gMk gMk -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG gMk gMk gMk @@ -169514,32 +169423,32 @@ gMk gMk gMk gMk -vxX -vxX -vxX +bmG +bmG +bmG vDa vDa -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe -vxX +bmG hhX hhX hhX @@ -169709,7 +169618,7 @@ mCt riQ jNg mbL -and +wnD stj fEe xIl @@ -169723,11 +169632,11 @@ mxt hhX hhX hhX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG gvF gvF gvF @@ -169737,25 +169646,25 @@ gvF gvF gvF gvF -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG xUx uet -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG gMk nyq gMk uQl gMk gMk -vxX -vxX +bmG +bmG uet gMk gMk @@ -169763,37 +169672,37 @@ gMk gMk gMk gMk -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG gMk gMk gMk -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG vDa -vxX -vxX +bmG +bmG mUQ -vxX +bmG gMk gMk gMk gMk gMk -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hhX hhX hhX @@ -169980,9 +169889,9 @@ mxt hhX hhX hhX -vxX -vxX -vxX +bmG +bmG +bmG gvF gvF gvF @@ -169994,42 +169903,42 @@ tqD mMO fhP gvF -vxX +bmG bKL gMk gMk rZg gMk gMk -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG gMk gMk gqm gMk gMk gMk -vxX -vxX +bmG +bmG gMk gMk gMk -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG gMk gMk -vxX -vxX +bmG +bmG woL woL cMJ @@ -170038,19 +169947,19 @@ stz stz gMk gMk -vxX +bmG gMk gMk gMk gMk -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hhX hhX hhX @@ -170244,12 +170153,12 @@ jam bjb fft wpG -oAs gOc -gOc -gOc -oAs -jqf +oiH +oiH +oiH +oiH +rFG oWg gMk fXf @@ -170259,55 +170168,55 @@ gMk gMk gMk fVf -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG rBv gMk tbp gMk gMk -vxX +bmG gMk gMk gMk gMk -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG uet -vxX -vxX +bmG +bmG gMk -vxX -vxX +bmG +bmG woL eAk cMJ stz jPq woL -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG uet gMk -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hhX hhX hhX @@ -170499,16 +170408,16 @@ fYe fYe jam cVt -qFa +mGL wny gOc -gOc -gOc -gOc -gOc -gOc +jLN +oiH +oiH +oiH +oAL gvF -vxX +bmG xUx gMk gMk @@ -170516,27 +170425,27 @@ gMk gMk gMk gMk -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG gMk gMk -vxX +bmG uet -vxX +bmG mNZ gMk gMk gMk gMk -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG ent gMk gMk @@ -170555,16 +170464,16 @@ ltS ltS ltS ltS -vxX +bmG gMk gMk -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG hhX hhX hhX @@ -170756,17 +170665,17 @@ fYe uif jam iBs -qFa -wny -gOc -gOc -gOc -gOc -gOc -gOc +ilc +cDz +oAL +oAL +dxC +dxC +dxC +oAL gvF -vxX -vxX +bmG +bmG uet gMk tui @@ -170774,15 +170683,15 @@ gMk gMk gMk gMk -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG mNZ mNZ gMk @@ -170790,17 +170699,17 @@ gMk gMk gMk mNZ -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG gMk gMk gMk gMk gMk -vxX +bmG woL sVT cMJ @@ -170813,15 +170722,15 @@ lQL aoy ltS mpc -vxX +bmG gMk -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG hhX hhX hhX @@ -171005,7 +170914,7 @@ mwe dUl bGg sJT -vxX +bmG hhX hhX hhX @@ -171013,17 +170922,17 @@ fYe uif jam afF -hbr -bUU -gOc -gOc -gOc -gOc -gOc -gOc -gvF -vxX -vxX +tSk +lAc +lAc +hOJ +sck +hOJ +lAc +lAc +bmG +bmG +bmG hyM gMk cgu @@ -171032,14 +170941,14 @@ gMk gMk gMk gMk -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG mNZ mNZ mNZ @@ -171047,8 +170956,8 @@ gMk gMk gMk gMk -vxX -vxX +bmG +bmG kxB kxB kxB @@ -171059,7 +170968,7 @@ eOx kxB kxB bkk -rPy +wgU cMJ msi ppD @@ -171072,13 +170981,13 @@ lls mpc gMk gMk -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG hhX hhX hhX @@ -171262,7 +171171,7 @@ rBZ lPi meH sJT -vxX +bmG hhX hhX hhX @@ -171271,32 +171180,32 @@ mNZ gvF hAx pof -wny -gOc -gOc -gOc -gOc -gOc -gOc -gvF -vxX -vxX -vxX +lAc +jBR +emQ +eIL +hWM +aCF +lAc +bmG +bmG +bmG +bmG gMk cgu yjm -vxX -vxX +bmG +bmG gMk gMk gMk -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG mNZ mNZ mNZ @@ -171304,8 +171213,8 @@ mNZ gMk gMk gMk -vxX -vxX +bmG +bmG kxB hhX hhX @@ -171328,17 +171237,17 @@ pVB pHr cXo tOw -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hhX hhX hhX @@ -171502,7 +171411,7 @@ hhX hhX cxg cxg -vxX +bmG imZ mQE fTj @@ -171519,41 +171428,41 @@ tww jlL sJT ogb -vxX -vxX +bmG +bmG hhX fYe mNZ mNZ -vxX +bmG vfJ fhN -obA -dpp -dpp -dpp -dpp -cMZ -cMZ -cMZ -cMZ -cMZ -vxX +lAc +lGl +csX +mKg +aEE +qNw +lAc +kxB +kxB +kxB +bmG uet cgu -vxX -vxX +bmG +bmG uet gMk qIA gMk -vxX -vxX -vxX +bmG +bmG +bmG uKm -vxX -vxX -vxX +bmG +bmG +bmG mNZ mNZ gMk @@ -171561,8 +171470,8 @@ mNZ mNZ gMk gMk -vxX -vxX +bmG +bmG kxB hhX xAy @@ -171586,16 +171495,16 @@ mry mpc gMk yeS -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hhX hhX hhX @@ -171759,8 +171668,8 @@ hhX hhX cxg pvT -vxX -vxX +bmG +bmG mQE vNg kWb @@ -171775,9 +171684,9 @@ kWb sae sJT sJT -vxX -vxX -vxX +bmG +bmG +bmG hhX fYe mNZ @@ -171785,32 +171694,32 @@ mNZ vfJ vfJ quM -obA -noO -vzj -vzj -vzj -oka -nas -bbe -ycq -cMZ +lAc +eFs +ftQ +nLt +aEE +sPM +umJ +wzX +hfD +ipx ipx dVt -cdl +gaM ipx -vxX -vxX +bmG +bmG gMk gMk gMk gMk -vxX -vxX +bmG +bmG kTV gMk -vxX -vxX +bmG +bmG fJz gMk gMk @@ -171843,16 +171752,16 @@ cuW cuW cuW cuW -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hhX hhX hhX @@ -172015,9 +171924,9 @@ hhX hhX hhX hhX -vxX -vxX -vxX +bmG +bmG +bmG mQE lJv kWb @@ -172032,7 +171941,7 @@ kWb wYj pdo sJT -vxX +bmG uif hhX hhX @@ -172042,37 +171951,37 @@ mNZ vfJ piE pmT -obA -kvj -twm -aqM -fFq -suO -ukx -hOa -jnw -gKt +lAc +vlW +ftQ +ukI +aEE +guk +gpp +mmV +mmV +dVp gTf dOg kqf ipx ipx -vxX +bmG gMk -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG xUx gMk gMk -vxX -vxX -vxX +bmG +bmG +bmG gMk gMk -vxX -vxX +bmG +bmG gMk gMk dtQ @@ -172102,14 +172011,14 @@ gun cuW cuW cuW -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hhX hhX hhX @@ -172272,9 +172181,9 @@ hhX hhX hhX hhX -vxX -vxX -vxX +bmG +bmG +bmG kWb kWb kWb @@ -172289,8 +172198,8 @@ kWb kWb kWb kWb -vxX -vxX +bmG +bmG hhX hhX fYe @@ -172299,16 +172208,16 @@ mNZ vfJ qIo uat -obA -pvo -dHa -sXG -bzB -suO -hOa -ukx -xGY -gKt +lAc +bxq +aAS +oMq +iiA +tZQ +tUQ +rYC +pPW +dVp oGQ aIX oSG @@ -172318,19 +172227,19 @@ xCX gMk xUx uet -vxX -vxX +bmG +bmG gMk ceN gMk gMk gMk -vxX +bmG xKx -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG gMk dtQ gMk @@ -172359,14 +172268,14 @@ yhy dlX iUq cuW -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hhX hhX hhX @@ -172529,9 +172438,9 @@ hhX hhX hhX hhX -vxX -vxX -vxX +bmG +bmG +bmG kWb kWb kWb @@ -172545,9 +172454,9 @@ lRk kWb kWb kWb -vxX -vxX -vxX +bmG +bmG +bmG hhX hhX fYe @@ -172556,16 +172465,16 @@ mNZ vfJ pZP raz -obA -fAU -rjr -mYN -vzj -suK -nas -nas -vwd -gKt +lAc +qvP +bMI +hLJ +efP +iUH +lqd +mmV +uhc +dVp xNo suw fdN @@ -172575,22 +172484,22 @@ xCX gMk gMk gMk -vxX -vxX -vxX +bmG +bmG +bmG lmn gMk -vxX +bmG gMk -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG gMk -vxX -vxX +bmG +bmG dtQ -vxX +bmG kxB hhX xAy @@ -172616,17 +172525,17 @@ pMw nME iJb cuW -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hhX hhX hhX @@ -172786,8 +172695,8 @@ hhX hhX hhX hhX -vxX -vxX +bmG +bmG kWb kWb kWb @@ -172803,8 +172712,8 @@ qWB kWb kWb kWb -vxX -vxX +bmG +bmG hhX hhX hhX @@ -172813,41 +172722,41 @@ mNZ vfJ vfJ jmY -obA -gKt -dpp -izV -dpp -gKt -dpp -dpp -dpp -gKt +lAc +lAc +qSv +xmA +qLx +lAc +lAc +jnA +jnA +dVp dVp dRh xBU xje ipx -vxX +bmG gMk gMk -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG xIP xIP uKm elE -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG gMk vkv -vxX +bmG dtQ -vxX +bmG kxB hhX cLf @@ -172873,18 +172782,18 @@ jGP cYe qbZ cuW -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hhX hhX hhX @@ -173043,8 +172952,8 @@ hhX hhX hhX hhX -vxX -vxX +bmG +bmG kWb kWb kWb @@ -173060,8 +172969,8 @@ vAB kWb kWb kWb -vxX -vxX +bmG +bmG hhX hhX hhX @@ -173073,7 +172982,7 @@ xeJ vRP bWi bWi -iHH +jCy dfM wPX dfM @@ -173089,15 +172998,15 @@ uKm mWS gMk ent -vxX +bmG gMk gMk gMk uet cPE gMk -vxX -vxX +bmG +bmG gMk gMk gMk @@ -173136,10 +173045,10 @@ aWD uYG uYG uYG -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG uYG uYG uYG @@ -173301,7 +173210,7 @@ hhX hhX hhX unk -vxX +bmG kWb kWb kWb @@ -173317,8 +173226,8 @@ vAB kWb kWb kWb -vxX -vxX +bmG +bmG hhX hhX hhX @@ -173330,8 +173239,8 @@ raz obA obA bdz -rcx -eua +lnX +ecn dsi vnX bNp @@ -173342,20 +173251,20 @@ fFg fFg dhR ipx -vxX +bmG uet gMk -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG gMk xUx -vxX +bmG dsF gMk -vxX -vxX +bmG +bmG gMk gMk gMk @@ -173574,8 +173483,8 @@ qDl aKU kWb kWb -vxX -vxX +bmG +bmG hhX hhX fYe @@ -173588,7 +173497,7 @@ eUj obA oJr vRA -oXa +vdu gak bdz pIp @@ -173599,22 +173508,22 @@ dVt dVt ipx ipx -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG gMk gMk xUx -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG gMk gMk dtQ @@ -173661,8 +173570,8 @@ tNE cEG cEG uYG -vxX -vxX +bmG +bmG jVV jVV jGa @@ -173815,7 +173724,7 @@ hhX hhX hhX unk -vxX +bmG kWb kWb kWb @@ -173831,8 +173740,8 @@ vAB kWb kWb kWb -vxX -vxX +bmG +bmG hhX hhX fYe @@ -173845,7 +173754,7 @@ obA obA vRA vRA -oXa +vdu vjv vRA vRA @@ -173855,22 +173764,22 @@ vRA vRA vRA ixU -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG uet -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG xKo xKo xKo @@ -173918,8 +173827,8 @@ tNE tNE dYZ uYG -vxX -vxX +bmG +bmG jVV hhX hhX @@ -174071,8 +173980,8 @@ hhX hhX hhX hhX -vxX -vxX +bmG +bmG kWb kWb kWb @@ -174088,7 +173997,7 @@ vAB kWb kWb kWb -vxX +bmG hhX hhX hhX @@ -174102,7 +174011,7 @@ obA gbR omL omL -acY +rfU aqa vRA vRA @@ -174112,9 +174021,9 @@ vRA vRA vRA ixU -vxX -vxX -vxX +bmG +bmG +bmG kxB uKm uKm @@ -174122,12 +174031,12 @@ uKm uKm uKm uKm -vxX +bmG gMk -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG xKo rhn lWF @@ -174328,8 +174237,8 @@ hhX hhX hhX hhX -vxX -vxX +bmG +bmG kWb kWb kWb @@ -174356,10 +174265,10 @@ riv vpK raz obA -dOl -nmj -iJS -fTN +rpO +dfM +iHH +bWi gTA vRA vRA @@ -174377,14 +174286,14 @@ iHO iHO jZY ouE -vxX +bmG lzE -vxX +bmG gMk gMk uet -vxX -vxX +bmG +bmG xKo ljN eqC @@ -174586,7 +174495,7 @@ hhX hhX hhX hhX -vxX +bmG kWb kWb kWb @@ -174613,11 +174522,11 @@ vfJ vfJ jmY obA -lAc -kuX -nIu -frt -gYY +cMZ +dpp +ctI +dpp +cMZ vRA vRA vRA @@ -174636,12 +174545,12 @@ uKm uKm uKm uKm -vxX -vxX +bmG +bmG gMk gMk -vxX -vxX +bmG +bmG xKo fEQ eeB @@ -174844,7 +174753,7 @@ hhX hhX hhX hhX -vxX +bmG kWb kWb kWb @@ -174870,11 +174779,11 @@ fYe lJq raz obA -irf -tsy -jCT -rin -sIY +noO +vzj +xVh +ryW +cMZ vRA vRA vRA @@ -174893,12 +174802,12 @@ twx twx twx twx -vxX -vxX +bmG +bmG gMk gMk -vxX -vxX +bmG +bmG xKo xKo xKo @@ -175101,8 +175010,8 @@ hhX hhX hhX hhX -vxX -vxX +bmG +bmG kWb kWb kWb @@ -175127,11 +175036,11 @@ fYe lJq raz obA -dES -fuo -iXv -iXv -aki +dKU +vzj +xVh +bzB +dpp vRA vRA vRA @@ -175150,12 +175059,12 @@ twx twx twx twx -vxX -vxX +bmG +bmG gMk gMk -vxX -vxX +bmG +bmG xKo tmR xKo @@ -175359,16 +175268,16 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG kWb kWb kWb kWb kWb -vxX +bmG hhX hhX hhX @@ -175384,11 +175293,11 @@ fYe lJq wWE obA -jCg -iXv -iXv -iXv -qVD +pvo +dHa +xVh +yiS +dpp vRA vRA vRA @@ -175407,12 +175316,12 @@ twx twx twx twx -vxX +bmG uKm aXH gMk xUx -vxX +bmG xKo nqu ikD @@ -175458,11 +175367,11 @@ nUy uYG uYG uYG -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG jVV pnS hhX @@ -175617,8 +175526,8 @@ hhX hhX hhX hhX -vxX -vxX +bmG +bmG hhX hhX jVV @@ -175641,13 +175550,13 @@ fYe lJq jmY obA -gOB -yiW -gFg -pQz -itV -lgK -dDI +rEX +vzj +hbp +nOH +cMZ +vRA +vRA vRA vRA vRA @@ -175665,11 +175574,11 @@ twx twx twx uKm -vxX +bmG gMk -vxX -vxX -vxX +bmG +bmG +bmG xKo xKo xKo @@ -175716,10 +175625,10 @@ uYG hhX hhX hhX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG jVV hhX vUj @@ -175898,13 +175807,13 @@ fYe lJq raz obA -bxq -qfu -nje -jXb -aLe -cCb -dwV +kCo +wbX +wlL +wlL +cMZ +vRA +vRA vRA qfr vRA @@ -175924,9 +175833,9 @@ twx uKm xwA gMk -vxX -vxX -vxX +bmG +bmG +bmG xKo dor lVx @@ -175974,8 +175883,8 @@ hhX hhX hhX hhX -vxX -vxX +bmG +bmG hhX jVV hhX @@ -176155,11 +176064,11 @@ fYe lJq raz obA -qvP -tOO -jXb -sMl -amn +pvu +ukx +hOa +nas +cMZ jxa jxa jxa @@ -176181,9 +176090,9 @@ mxq uKm gMk uet -vxX -vxX -vxX +bmG +bmG +bmG xKo lVx bkk @@ -176224,14 +176133,14 @@ vzC aWD wlV aWD -vxX -vxX +bmG +bmG mUQ rGg rGg mUQ -vxX -vxX +bmG +bmG hhX hhX jVV @@ -176412,12 +176321,12 @@ fYe lJq raz obA -obA -uFt -nhf -guk -jxa -jxa +nas +hOa +ukx +nas +cMZ +qcX rHF mHf xfK @@ -176431,15 +176340,15 @@ ixU dtQ dtQ gMk -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG xUx -vxX -vxX -vxX +bmG +bmG +bmG ent cIN lVx @@ -176481,13 +176390,13 @@ xwm sCp sCp aWD -vxX -vxX -vxX +bmG +bmG +bmG tOG ufA -vxX -vxX +bmG +bmG uif hhX hhX @@ -176668,7 +176577,7 @@ fYe fYe lJq xeJ -jAB +obA obA obA lno @@ -176689,14 +176598,14 @@ dtQ gMk gMk gMk -vxX +bmG gMk -vxX +bmG uKm aXH lgL rQP -vxX +bmG gMk vWx dor @@ -176738,13 +176647,13 @@ xwm mog mog aWD -vxX -vxX -vxX +bmG +bmG +bmG uif fYe -vxX -vxX +bmG +bmG hhX hhX hhX @@ -176995,12 +176904,12 @@ muB mog mog aWD -vxX -vxX -vxX +bmG +bmG +bmG fYe fYe -vxX +bmG mUQ jVV hhX @@ -177185,8 +177094,8 @@ raz vfJ vfJ obA -krg oQW +gJn bjp fmK fwM @@ -177252,8 +177161,8 @@ mog mog cYw aWD -vxX -vxX +bmG +bmG fYe fYe fYe @@ -177464,9 +177373,9 @@ sqL rlw khP rlw -vxX -vxX -vxX +bmG +bmG +bmG xKo wlR lNe @@ -177509,12 +177418,12 @@ mog mog mog aWD -vxX -vxX -vxX +bmG +bmG +bmG fYe -vxX -vxX +bmG +bmG mUQ eCF hhX @@ -177699,8 +177608,8 @@ raz occ fMz obA -gSY -oQW +dcZ +mSY ddZ nXL nXL @@ -177716,14 +177625,14 @@ ixU gMk gMk gMk -vxX -vxX +bmG +bmG sqL uoY sqL -vxX -vxX -vxX +bmG +bmG +bmG xKo jBG oEN @@ -177766,14 +177675,14 @@ mog mog mog aWD -vxX -vxX -vxX +bmG +bmG +bmG fYe -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG hhX hhX hhX @@ -177957,8 +177866,8 @@ vfJ vfJ obA lno -mSY -kLw +lno +lno nXL fBO naj @@ -177971,16 +177880,16 @@ xbC cIE ixU gMk -vxX +bmG gMk -vxX -vxX +bmG +bmG sqL uoY sqL gMk -vxX -vPt +bmG +hBd woL iNv xKo @@ -178023,14 +177932,14 @@ bkW bkW bkW aWD -vxX -vxX +bmG +bmG fYe fYe fYe -vxX -vxX -vxX +bmG +bmG +bmG hhX hhX hhX @@ -178214,7 +178123,7 @@ uba nke cYs obA -obA +hHW obA lWd vfJ @@ -178227,17 +178136,17 @@ lsx idr lsx hEi -vxX -vxX +bmG +bmG iOE -vxX -vxX +bmG +bmG sqL uoY gbP fWJ -vPt -vPt +hBd +hBd wPU uab qhG @@ -178280,13 +178189,13 @@ tel tel lhg uFC -vxX -vxX +bmG +bmG fYe -vxX +bmG fYe -vxX -vxX +bmG +bmG fYe hhX hhX @@ -178470,8 +178379,8 @@ jmY jmY uba agO -vfJ -hHW +uba +uba uba raz vfJ @@ -178485,10 +178394,10 @@ cHn sAN hEi hEi -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG sqL uoY sqL @@ -178537,13 +178446,13 @@ tGb tGb xlG uFC -vxX -vxX +bmG +bmG fYe -vxX +bmG fYe -vxX -vxX +bmG +bmG fYe hhX hhX @@ -178744,8 +178653,8 @@ uaY iFN iFN iFN -vxX -vxX +bmG +bmG sqL uoY sqL @@ -178775,7 +178684,7 @@ pMG lXi ldl iZa -vxX +bmG uFC xlG tGb @@ -178794,13 +178703,13 @@ tGb tGb xlG uFC -vxX -vxX +bmG +bmG fYe -vxX +bmG fYe -vxX -vxX +bmG +bmG fYe hhX hhX @@ -179002,11 +178911,11 @@ iFN ekR iFN iFN -vxX +bmG rlw eGM rlw -vxX +bmG dsP nQs ohk @@ -179032,7 +178941,7 @@ lRU wZb vxp iZa -vxX +bmG uFC xlG tGb @@ -179051,13 +178960,13 @@ tGb tGb xlG uFC -vxX -vxX +bmG +bmG fYe tOG fYe -vxX -vxX +bmG +bmG uif hhX hhX @@ -179259,12 +179168,12 @@ qJN uHQ szk iFN -vxX +bmG sqL uoY sqL -vxX -vPt +bmG +hBd alu ohk jMN @@ -179289,7 +179198,7 @@ qWT grz grz grz -vxX +bmG uFC xlG tGb @@ -179308,13 +179217,13 @@ tGb tGb xlG uFC -vxX +bmG uKm uKm iDu uKm uKm -vxX +bmG fYe hhX hhX @@ -179516,13 +179425,13 @@ kHf xkL uSX iFN -vxX +bmG sqL uoY sqL -vxX -vPt -vPt +bmG +hBd +hBd hFa tUc qhG @@ -179545,8 +179454,8 @@ uLS uyZ esc grz -vxX -vxX +bmG +bmG uFC xlG tGb @@ -179565,13 +179474,13 @@ tGb tGb xlG uFC -vxX -vxX +bmG +bmG iJm iJm iJm uKm -vxX +bmG fYe hhX hhX @@ -179773,16 +179682,16 @@ aXl fyJ aXl iFN -vxX +bmG sqL uoY sqL -vxX -vxX -vxX +bmG +bmG +bmG dsP -vPt -vPt +hBd +hBd stP tNK vkp @@ -179802,8 +179711,8 @@ urI kdE xjL grz -vxX -vxX +bmG +bmG uFC xlG tGb @@ -179822,7 +179731,7 @@ tGb tGb xlG uFC -vxX +bmG fYe fYe iJm @@ -180030,16 +179939,16 @@ mZn oND iem iFN -vxX +bmG sqL uoY sqL gMk -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG qhG pql qhG @@ -180059,8 +179968,8 @@ rAP odk jDl grz -vxX -vxX +bmG +bmG uFC pFg gsg @@ -180079,13 +179988,13 @@ tGb tGb xlG uFC -vxX +bmG fYe fYe fYe iJm uKm -vxX +bmG fYe hhX hhX @@ -180287,15 +180196,15 @@ rEv vjQ evN iFN -vxX +bmG sqL uoY sqL gMk -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG fYe vnb jCm @@ -180317,7 +180226,7 @@ odk kOU grz fYe -vxX +bmG uFC bMb xlG @@ -180336,13 +180245,13 @@ tGb tGb xgN uFC -vxX -vxX +bmG +bmG fYe -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG fYe hhX hhX @@ -180544,7 +180453,7 @@ iFN iFN iFN iFN -vxX +bmG eIO ehY rlw @@ -180593,13 +180502,13 @@ tGb tGb xlG uFC -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG hen -vxX -vxX +bmG +bmG hhX hhX hhX @@ -180797,11 +180706,11 @@ wkG wkG rzI moe -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG rlw wvS uCp @@ -180850,13 +180759,13 @@ tGb tGb xlG uFC -vxX +bmG hen hen hen hen -vxX -vxX +bmG +bmG hhX hhX hhX @@ -181054,10 +180963,10 @@ jYT jYT rIJ moe -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG hhX rlw sqL @@ -181112,8 +181021,8 @@ hen hen hen hen -vxX -vxX +bmG +bmG hhX hhX hhX @@ -181311,9 +181220,9 @@ wkG wkG wkG moe -vxX -vxX -vxX +bmG +bmG +bmG hhX hhX jVV @@ -181370,7 +181279,7 @@ hen hen hen kxB -vxX +bmG fYe hhX hhX @@ -181567,9 +181476,9 @@ jYT wkG ivx ivx -vxX -vxX -vxX +bmG +bmG +bmG hhX hhX hhX @@ -181626,8 +181535,8 @@ hen hen hen hen -vxX -vxX +bmG +bmG fYe hhX hhX @@ -181825,8 +181734,8 @@ moe rGg rGg fqD -vxX -vxX +bmG +bmG hhX hhX hhX @@ -181848,18 +181757,18 @@ tAo vbd vbd fYe -vxX -vxX +bmG +bmG hhX nbk smD pBC hhX -vxX -vxX -vxX +bmG +bmG +bmG fYe -vxX +bmG uFC uFC uFC @@ -181883,8 +181792,8 @@ hen hen hen hen -vxX -vxX +bmG +bmG fYe hhX hhX @@ -182105,42 +182014,42 @@ uLR avQ uLR tAo -vxX -vxX +bmG +bmG hhX hHZ mxt eRO hhX -vxX -vxX -vxX +bmG +bmG +bmG fYe -vxX -vxX +bmG +bmG hhX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hen hen hen hen hen -vxX +bmG fYe uif hhX @@ -182363,41 +182272,41 @@ fYe uLR fYe fYe -vxX -vxX +bmG +bmG hhX mxt hhX hhX -vxX -vxX -vxX +bmG +bmG +bmG fYe -vxX -vxX +bmG +bmG hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hen hen hen hen hen -vxX +bmG fYe hhX hhX @@ -182612,11 +182521,11 @@ rlw uVI uVI mUQ -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG mUQ uVI uVI @@ -182626,35 +182535,35 @@ hhX mxt hhX hhX -vxX -vxX +bmG +bmG fYe fYe -vxX -vxX +bmG +bmG hhX hhX hhX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG gMk -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hen hen hen hen hen hen -vxX +bmG fYe hhX hhX @@ -182868,13 +182777,13 @@ uoY sqL fYe fYe -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG fYe fYe fYe @@ -182887,31 +182796,31 @@ fYe fYe fYe fYe -vxX +bmG hhX hhX hhX hhX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG gMk gMk -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hen hen hen hen -vxX -vxX +bmG +bmG fYe hhX hhX @@ -183128,9 +183037,9 @@ hhX jVV hhX hhX -vxX +bmG hhX -vxX +bmG hhX hhX hhX @@ -183149,25 +183058,25 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG gMk xKx -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hen hen -vxX -vxX +bmG +bmG uif fYe hhX @@ -183405,21 +183314,21 @@ rjp hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG bZr rjp rjp @@ -183662,21 +183571,21 @@ rjp rjp rjp bZr -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hhX hhX hhX @@ -183920,20 +183829,20 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG +bmG hhX hhX hhX @@ -184178,18 +184087,18 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG +bmG +bmG hhX hhX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG hhX hhX hhX @@ -184436,10 +184345,10 @@ hhX hhX hhX hhX -vxX -vxX -vxX -vxX +bmG +bmG +bmG +bmG hhX hhX hhX @@ -184621,16 +184530,16 @@ hhX hhX hhX hhX -hhX -hhX -hhX -hhX -hhX -hhX -hhX -hhX -hhX -hhX +cLf +cLf +cLf +cLf +cLf +cLf +cLf +cLf +cLf +cLf hhX hhX hhX @@ -184878,16 +184787,16 @@ hhX hhX hhX hhX -hhX -hhX -hhX -hhX -hhX -hhX -hhX -hhX -hhX -hhX +cLf +cLf +cLf +cLf +cLf +cLf +cLf +cLf +cLf +cLf hhX hhX hhX @@ -185135,16 +185044,16 @@ hhX hhX hhX hhX -hhX -hhX -hhX -hhX -hhX -hhX -hhX -hhX -hhX -hhX +cLf +cLf +cLf +cLf +cLf +cLf +cLf +cLf +cLf +cLf hhX hhX hhX @@ -185392,16 +185301,16 @@ hhX hhX hhX hhX -hhX -hhX -hhX -hhX -hhX -hhX -hhX -hhX -hhX -hhX +cLf +cLf +cLf +cLf +cLf +cLf +cLf +cLf +cLf +cLf hhX hhX hhX @@ -185649,16 +185558,16 @@ hhX hhX hhX hhX -hhX -hhX -hhX -hhX -hhX -hhX -hhX -hhX -hhX -hhX +cLf +cLf +cLf +cLf +cLf +cLf +cLf +cLf +cLf +cLf hhX hhX hhX @@ -185906,16 +185815,16 @@ hhX hhX hhX hhX -hhX -hhX -hhX -hhX -hhX -hhX -hhX -hhX -hhX -hhX +cLf +cLf +cLf +cLf +cLf +cLf +cLf +cLf +cLf +cLf hhX hhX hhX diff --git a/_maps/minigame/deathmatch/deep_space.dmm b/_maps/minigame/deathmatch/deep_space.dmm new file mode 100644 index 00000000000..cf0e389d0d6 --- /dev/null +++ b/_maps/minigame/deathmatch/deep_space.dmm @@ -0,0 +1,3377 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"ah" = ( +/obj/effect/mob_spawn/corpse/human/clown, +/obj/item/stack/ore/bananium, +/turf/open/space/basic, +/area/deathmatch) +"ap" = ( +/obj/item/tank/jetpack/improvised, +/turf/open/floor/plating, +/area/deathmatch) +"aF" = ( +/obj/structure/fluff/tram_rail/floor, +/obj/item/assembly/igniter, +/turf/open/floor/plating/airless, +/area/deathmatch) +"aH" = ( +/obj/structure/fluff/tram_rail/floor, +/turf/open/misc/asteroid/airless, +/area/deathmatch) +"bL" = ( +/obj/effect/turf_decal/sand/plating, +/obj/item/stack/sheet/mineral/wood, +/turf/open/floor/plating/airless, +/area/deathmatch) +"bN" = ( +/turf/open/floor/iron/corner{ + dir = 1 + }, +/area/deathmatch) +"bP" = ( +/obj/structure/lattice/catwalk, +/obj/structure/marker_beacon/yellow, +/turf/open/space/basic, +/area/deathmatch) +"bW" = ( +/obj/structure/flora/tree/palm, +/turf/open/floor/grass, +/area/deathmatch) +"cb" = ( +/obj/structure/sign/warning/directional/south, +/turf/closed/mineral/asteroid, +/area/deathmatch) +"cF" = ( +/obj/structure/lattice/catwalk, +/obj/item/assembly/igniter, +/turf/open/space/basic, +/area/deathmatch) +"cT" = ( +/obj/machinery/power/shuttle_engine/heater{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plating/airless, +/area/deathmatch) +"cW" = ( +/obj/effect/turf_decal/sand/plating, +/obj/structure/sign/warning/directional/south, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating/airless, +/area/deathmatch) +"cX" = ( +/obj/structure/flora/rock/style_random{ + color = "#E09C96" + }, +/turf/open/misc/asteroid/airless, +/area/deathmatch) +"dh" = ( +/obj/structure/sign/warning/directional/west, +/turf/open/space/basic, +/area/deathmatch) +"dx" = ( +/obj/structure/window/reinforced/spawner/directional/east, +/obj/effect/turf_decal/tile/blue/opposingcorners, +/turf/open/floor/iron/white, +/area/deathmatch) +"dH" = ( +/turf/closed/wall, +/area/deathmatch) +"eb" = ( +/obj/machinery/computer{ + dir = 4 + }, +/turf/open/floor/mineral/plastitanium, +/area/deathmatch) +"el" = ( +/obj/item/gun/energy/recharge/kinetic_accelerator, +/obj/item/borg/upgrade/modkit/damage, +/obj/item/borg/upgrade/modkit/range, +/obj/structure/glowshroom/single, +/turf/open/misc/asteroid/airless, +/area/deathmatch) +"em" = ( +/obj/effect/turf_decal/tile/blue/anticorner/contrasted{ + dir = 1 + }, +/obj/structure/sign/warning/no_smoking/circle/directional/north, +/turf/open/floor/iron/white, +/area/deathmatch) +"ep" = ( +/obj/structure/sign/warning/directional/east, +/obj/machinery/power/floodlight, +/obj/effect/light_emitter{ + set_cap = 2; + light_color = "#DEEFFF"; + set_luminosity = 4 + }, +/obj/effect/turf_decal/sand/plating, +/obj/structure/cable, +/turf/open/floor/plating/airless, +/area/deathmatch) +"eB" = ( +/obj/machinery/door/airlock/shuttle, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/mineral/titanium/tiled/blue/airless, +/area/deathmatch) +"eE" = ( +/obj/effect/turf_decal/sand/plating, +/obj/item/stack/rods/ten, +/turf/open/floor/plating/airless, +/area/deathmatch) +"fd" = ( +/obj/structure/railing, +/obj/effect/mapping_helpers/broken_floor, +/obj/item/grenade/c4/x4, +/turf/open/floor/plating/airless, +/area/deathmatch) +"fs" = ( +/obj/machinery/light/broken/directional/south, +/obj/machinery/porta_turret_construct{ + anchored = 1 + }, +/turf/open/floor/iron, +/area/deathmatch) +"fF" = ( +/obj/item/mecha_ammo/lmg, +/obj/item/mecha_ammo/lmg{ + pixel_y = 12 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/sand/plating, +/obj/item/mecha_parts/mecha_equipment/thrusters/ion, +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg{ + pixel_y = -8 + }, +/turf/open/floor/plating/airless, +/area/deathmatch) +"fG" = ( +/obj/structure/lattice, +/obj/effect/landmark/deathmatch_player_spawn, +/turf/open/space/basic, +/area/deathmatch) +"fH" = ( +/obj/effect/turf_decal/sand/plating, +/obj/structure/fluff/tram_rail/floor{ + dir = 1 + }, +/turf/open/floor/plating/airless, +/area/deathmatch) +"fL" = ( +/turf/closed/indestructible/fakedoor/maintenance, +/area/deathmatch) +"fP" = ( +/obj/structure/railing/corner/end/flip{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plating/airless, +/area/deathmatch) +"gd" = ( +/obj/structure/fluff/iced_abductor, +/turf/open/misc/asteroid, +/area/deathmatch) +"gf" = ( +/obj/machinery/light/small/directional/west, +/obj/structure/sign/warning/vacuum/directional/west, +/obj/machinery/suit_storage_unit/open, +/obj/item/tank/internals/oxygen, +/turf/open/floor/plating, +/area/deathmatch) +"gC" = ( +/obj/structure/fluff/tram_rail{ + dir = 1 + }, +/obj/structure/lattice, +/turf/open/space/basic, +/area/deathmatch) +"gK" = ( +/obj/machinery/door/airlock/external, +/obj/structure/fans/tiny, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/turf/open/floor/iron/white/small, +/area/deathmatch) +"gP" = ( +/obj/effect/spawner/random/trash/food_packaging, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/herringbone, +/area/deathmatch) +"hk" = ( +/obj/structure/sign/warning/directional/west, +/turf/open/misc/asteroid/dug, +/area/deathmatch) +"hu" = ( +/obj/item/stack/sheet/iron/ten, +/obj/item/stack/cable_coil, +/turf/open/floor/plating/airless, +/area/deathmatch) +"hH" = ( +/obj/effect/turf_decal/tile/blue/anticorner/contrasted, +/obj/item/storage/medkit/fire, +/obj/item/storage/medkit/brute{ + pixel_y = 6 + }, +/obj/structure/rack, +/turf/open/floor/iron/white, +/area/deathmatch) +"hJ" = ( +/obj/structure/table/wood, +/obj/effect/decal/cleanable/dirt/dust, +/obj/item/trash/fleet_ration{ + pixel_y = 9 + }, +/obj/item/reagent_containers/cup/glass/coffee/no_lid{ + pixel_x = 8; + pixel_y = 2 + }, +/obj/item/cigbutt{ + pixel_x = -9; + pixel_y = 2 + }, +/turf/open/floor/wood, +/area/deathmatch) +"hM" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron/grimy, +/area/deathmatch) +"ip" = ( +/turf/open/floor/plating, +/area/deathmatch) +"ir" = ( +/obj/item/gun/ballistic/rocketlauncher/unrestricted{ + pixel_x = 3 + }, +/turf/open/misc/asteroid/dug, +/area/deathmatch) +"is" = ( +/obj/machinery/light/broken/directional/north, +/obj/machinery/porta_turret_construct{ + anchored = 1 + }, +/turf/open/floor/iron, +/area/deathmatch) +"iV" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/small, +/area/deathmatch) +"jb" = ( +/mob/living/basic/cow/moonicorn, +/turf/open/misc/asteroid, +/area/deathmatch) +"jS" = ( +/obj/effect/mapping_helpers/broken_floor, +/turf/open/floor/plating/airless, +/area/deathmatch) +"jY" = ( +/obj/structure/chair/wood/wings{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood, +/area/deathmatch) +"kK" = ( +/obj/structure/table_frame, +/turf/open/floor/plating, +/area/deathmatch) +"kO" = ( +/obj/effect/mob_spawn/corpse/human/miner/explorer, +/turf/open/misc/asteroid/dug, +/area/deathmatch) +"lb" = ( +/obj/item/resonator/upgraded, +/obj/effect/turf_decal/sand/plating, +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating/airless, +/area/deathmatch) +"lf" = ( +/obj/effect/decal/cleanable/blood/old, +/obj/effect/mapping_helpers/broken_floor, +/obj/item/gun/ballistic/shotgun/lethal, +/obj/item/ammo_casing/shotgun/buckshot{ + pixel_x = 11; + pixel_y = 7 + }, +/obj/item/ammo_casing/shotgun/buckshot{ + pixel_x = -3; + pixel_y = -9 + }, +/obj/item/ammo_casing/shotgun/buckshot{ + pixel_x = -9; + pixel_y = 10 + }, +/turf/open/floor/mineral/titanium/tiled/blue/airless, +/area/deathmatch) +"li" = ( +/obj/structure/railing{ + dir = 1 + }, +/obj/effect/mob_spawn/corpse/human/charredskeleton, +/obj/effect/mapping_helpers/broken_floor, +/turf/open/floor/plating/airless, +/area/deathmatch) +"lv" = ( +/obj/structure/fans/tiny, +/obj/effect/decal/cleanable/blood/tracks{ + dir = 4 + }, +/obj/machinery/door/airlock/titanium, +/turf/open/floor/iron/small, +/area/deathmatch) +"lE" = ( +/obj/effect/mob_spawn/corpse/human/monkey, +/turf/open/space/basic, +/area/deathmatch) +"lF" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/fluff/fake_scrubber, +/turf/open/floor/iron/herringbone, +/area/deathmatch) +"lH" = ( +/obj/structure/lattice/catwalk, +/obj/item/stack/sheet/iron/five, +/turf/open/space/basic, +/area/deathmatch) +"lL" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/sand/plating, +/obj/item/gun/ballistic/revolver/badass{ + pixel_x = 5; + pixel_y = 6 + }, +/turf/open/floor/plating/airless, +/area/deathmatch) +"lV" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plating/airless, +/area/deathmatch) +"lZ" = ( +/obj/machinery/power/tracker, +/obj/structure/cable, +/turf/open/floor/plating/airless, +/area/deathmatch) +"mi" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/deathmatch) +"mq" = ( +/turf/open/floor/iron/half, +/area/deathmatch) +"mL" = ( +/turf/closed/indestructible/fakedoor, +/area/deathmatch) +"mO" = ( +/obj/effect/turf_decal/stripes/line, +/obj/item/stack/sheet/iron/ten, +/turf/open/floor/plating/airless, +/area/deathmatch) +"nc" = ( +/obj/machinery/door/airlock/external, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/structure/fans/tiny, +/turf/open/floor/plating, +/area/deathmatch) +"ne" = ( +/obj/structure/lattice/catwalk, +/obj/structure/reagent_dispensers/watertank, +/turf/open/space/basic, +/area/deathmatch) +"ni" = ( +/obj/machinery/door/airlock/survival_pod/glass{ + dir = 4 + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/obj/structure/fans/tiny, +/turf/open/floor/grass, +/area/deathmatch) +"nu" = ( +/obj/effect/light_emitter{ + set_cap = 2; + light_color = "#DEEFFF"; + set_luminosity = 4 + }, +/obj/item/stack/rods/twentyfive, +/turf/open/floor/plating/airless, +/area/deathmatch) +"ny" = ( +/obj/structure/lattice/catwalk, +/obj/structure/railing{ + dir = 4 + }, +/turf/open/space/basic, +/area/deathmatch) +"nE" = ( +/obj/structure/fluff/fake_vent, +/turf/open/floor/iron/corner{ + dir = 8 + }, +/area/deathmatch) +"nK" = ( +/mob/living/basic/pet/cat/space, +/turf/open/space/basic, +/area/deathmatch) +"nQ" = ( +/obj/machinery/light/floor/broken, +/obj/effect/light_emitter{ + set_cap = 2; + light_color = "#DEEFFF"; + set_luminosity = 4 + }, +/turf/open/floor/plating/airless, +/area/deathmatch) +"nW" = ( +/obj/structure/girder, +/turf/open/floor/plating/airless, +/area/deathmatch) +"og" = ( +/obj/effect/mapping_helpers/broken_floor, +/turf/closed/wall/mineral/titanium, +/area/deathmatch) +"oi" = ( +/obj/structure/flora/bush/flowers_br/style_random, +/turf/open/floor/grass, +/area/deathmatch) +"oJ" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/sand/plating, +/obj/item/ammo_box/speedloader/c357, +/obj/item/ammo_box/speedloader/c357{ + pixel_x = -8; + pixel_y = -2 + }, +/turf/open/floor/plating/airless, +/area/deathmatch) +"oO" = ( +/obj/machinery/door/airlock/external, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/obj/structure/fans/tiny, +/turf/open/floor/plating, +/area/deathmatch) +"oU" = ( +/obj/effect/turf_decal/siding/wood/corner{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/landmark/deathmatch_player_spawn, +/turf/open/floor/iron/grimy, +/area/deathmatch) +"oZ" = ( +/obj/machinery/light/directional/north, +/obj/effect/decal/cleanable/dirt, +/obj/structure/fluff/fake_scrubber, +/turf/open/floor/iron/herringbone, +/area/deathmatch) +"pf" = ( +/obj/structure/fluff/tram_rail/anchor, +/obj/structure/lattice, +/turf/open/space/basic, +/area/deathmatch) +"pk" = ( +/obj/structure/lattice/catwalk, +/obj/structure/railing{ + dir = 4 + }, +/obj/item/stack/cable_coil, +/turf/open/space/basic, +/area/deathmatch) +"px" = ( +/obj/structure/railing{ + dir = 5 + }, +/turf/open/floor/plating/airless, +/area/deathmatch) +"pK" = ( +/obj/structure/fluff/tram_rail, +/obj/structure/lattice, +/turf/open/space/basic, +/area/deathmatch) +"pP" = ( +/obj/structure/flora/rock/pile/icy/style_random{ + color = "#E09C96" + }, +/turf/open/floor/grass, +/area/deathmatch) +"qg" = ( +/turf/closed/wall/mineral/titanium, +/area/deathmatch) +"qi" = ( +/obj/structure/lattice/catwalk, +/obj/item/crowbar/large, +/turf/open/space/basic, +/area/deathmatch) +"qv" = ( +/obj/effect/light_emitter{ + set_cap = 2; + light_color = "#DEEFFF"; + set_luminosity = 4 + }, +/turf/open/floor/plating/airless, +/area/deathmatch) +"qw" = ( +/obj/effect/decal/cleanable/rubble{ + color = "#E09C96" + }, +/turf/open/misc/asteroid/airless, +/area/deathmatch) +"qK" = ( +/obj/effect/turf_decal/siding/wood, +/mob/living/basic/bot/cleanbot/autopatrol, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron/grimy, +/area/deathmatch) +"rb" = ( +/obj/item/ammo_box/rocket{ + pixel_x = -5 + }, +/turf/open/space/basic, +/area/deathmatch) +"rg" = ( +/turf/open/floor/iron/corner, +/area/deathmatch) +"rj" = ( +/obj/item/weldingtool, +/turf/open/floor/plating/foam, +/area/deathmatch) +"ry" = ( +/obj/structure/sign/warning/directional/north, +/obj/effect/turf_decal/sand/plating, +/obj/structure/cable, +/obj/machinery/power/port_gen/pacman/pre_loaded, +/turf/open/floor/plating/airless, +/area/deathmatch) +"rC" = ( +/turf/open/floor/plating/foam, +/area/deathmatch) +"rG" = ( +/obj/effect/decal/cleanable/glass/titanium, +/obj/item/storage/pod/directional/south, +/obj/effect/mapping_helpers/broken_floor, +/obj/machinery/computer/pod{ + dir = 8 + }, +/obj/machinery/light/broken/directional/south, +/turf/open/floor/mineral/titanium/tiled/blue/airless, +/area/deathmatch) +"rN" = ( +/turf/closed/mineral/asteroid, +/area/deathmatch) +"sy" = ( +/obj/structure/lattice/catwalk, +/obj/item/toy/crayon/spraycan{ + pixel_x = -5; + pixel_y = 4 + }, +/turf/open/space/basic, +/area/deathmatch) +"sT" = ( +/obj/structure/falsewall, +/turf/open/misc/asteroid/airless, +/area/deathmatch) +"sW" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/fluff/fake_vent, +/turf/open/floor/iron/herringbone, +/area/deathmatch) +"tc" = ( +/obj/structure/fans/tiny/shield, +/obj/machinery/door/poddoor/shutters{ + id = "dm_deepspace" + }, +/turf/open/floor/vault, +/area/deathmatch) +"tA" = ( +/obj/effect/turf_decal/sand/plating, +/obj/structure/holosign/barrier/engineering, +/turf/open/floor/plating/airless, +/area/deathmatch) +"uv" = ( +/obj/effect/turf_decal/siding/wood/corner{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/sign/warning/yes_smoking/circle/directional/north, +/turf/open/floor/iron/grimy, +/area/deathmatch) +"uA" = ( +/obj/structure/lattice/catwalk, +/obj/structure/railing/corner/end{ + dir = 8 + }, +/turf/open/space/basic, +/area/deathmatch) +"uI" = ( +/obj/effect/turf_decal/siding/wood/corner{ + dir = 4 + }, +/obj/effect/turf_decal/siding/wood/corner{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron/grimy, +/area/deathmatch) +"uX" = ( +/obj/structure/sign/departments/engineering/directional/south, +/obj/machinery/light/directional/south, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/herringbone, +/area/deathmatch) +"ve" = ( +/obj/structure/table/glass, +/obj/effect/turf_decal/tile/blue/anticorner/contrasted{ + dir = 8 + }, +/obj/item/reagent_containers/hypospray/medipen, +/turf/open/floor/iron/white, +/area/deathmatch) +"vh" = ( +/obj/machinery/light/directional/north, +/obj/machinery/porta_turret/syndicate/energy, +/turf/open/floor/iron, +/area/deathmatch) +"vn" = ( +/obj/effect/spawner/random/structure/billboard, +/turf/open/misc/asteroid/airless, +/area/deathmatch) +"vs" = ( +/obj/vehicle/sealed/mecha/ripley, +/turf/open/floor/plating/foam, +/area/deathmatch) +"vu" = ( +/turf/closed/indestructible/fakedoor/glass_airlock, +/area/deathmatch) +"vy" = ( +/obj/effect/mob_spawn/corpse/human/damaged, +/turf/open/space/basic, +/area/deathmatch) +"vz" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/blood/oil, +/turf/open/floor/iron/herringbone, +/area/deathmatch) +"vB" = ( +/obj/structure/fans/tiny, +/obj/machinery/door/airlock/titanium, +/turf/open/floor/iron/small, +/area/deathmatch) +"vJ" = ( +/obj/structure/railing{ + dir = 9 + }, +/turf/open/floor/plating/airless, +/area/deathmatch) +"vY" = ( +/obj/structure/fluff/tram_rail/floor{ + dir = 1 + }, +/obj/item/wrench/bolter, +/turf/open/floor/plating/airless, +/area/deathmatch) +"wd" = ( +/obj/structure/fluff/tram_rail/anchor, +/turf/open/space/basic, +/area/deathmatch) +"wf" = ( +/turf/open/space/basic, +/area/deathmatch) +"wu" = ( +/obj/machinery/power/solar{ + id = "foreport"; + name = "Fore-Port Solar Array" + }, +/obj/structure/cable, +/turf/open/floor/iron/solarpanel/airless, +/area/deathmatch) +"wL" = ( +/obj/item/grown/bananapeel, +/turf/open/space/basic, +/area/deathmatch) +"xa" = ( +/obj/effect/turf_decal/siding/wood/corner, +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/extinguisher_cabinet/directional/east, +/turf/open/floor/iron/grimy, +/area/deathmatch) +"xp" = ( +/obj/structure/sign/directions/engineering/directional/south{ + pixel_y = -36 + }, +/obj/structure/sign/directions/supply/directional/south{ + pixel_y = -28; + dir = 8 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron/grimy, +/area/deathmatch) +"xB" = ( +/obj/machinery/door/airlock/survival_pod/glass, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, +/obj/structure/fans/tiny, +/turf/open/floor/grass, +/area/deathmatch) +"xJ" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/mob_spawn/corpse/human/engineer, +/turf/open/floor/plating/airless, +/area/deathmatch) +"xL" = ( +/obj/structure/sign/poster/contraband/kss13/directional/west, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron/grimy, +/area/deathmatch) +"xM" = ( +/obj/structure/marker_beacon{ + light_color = "#FFE8AA"; + light_range = 20 + }, +/turf/open/floor/grass, +/area/deathmatch) +"yb" = ( +/obj/effect/light_emitter/fake_outdoors, +/turf/open/floor/grass, +/area/deathmatch) +"yf" = ( +/obj/effect/mob_spawn/corpse/human/nanotrasensoldier, +/obj/effect/decal/cleanable/blood/splatter/over_window{ + pixel_x = -32 + }, +/obj/effect/decal/cleanable/blood/gibs, +/turf/open/floor/iron, +/area/deathmatch) +"yg" = ( +/turf/closed/wall/r_wall/plastitanium/syndicate, +/area/deathmatch) +"yl" = ( +/obj/effect/turf_decal/stripes/line, +/obj/machinery/transport/crossing_signal/northeast, +/turf/open/floor/plating/airless, +/area/deathmatch) +"ys" = ( +/obj/structure/lattice/catwalk, +/turf/open/space/basic, +/area/deathmatch) +"yt" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/structure/closet/crate/bin, +/obj/effect/spawner/random/trash/crushed_can, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron/grimy, +/area/deathmatch) +"yu" = ( +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron/grimy, +/area/deathmatch) +"yw" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/structure/shipping_container/kahraman/alt, +/turf/open/floor/plating/airless, +/area/deathmatch) +"yB" = ( +/obj/structure/lattice, +/obj/structure/marker_beacon/cerulean, +/turf/open/space/basic, +/area/deathmatch) +"yL" = ( +/obj/structure/sign/warning/directional/north, +/turf/closed/indestructible/reinforced, +/area/deathmatch) +"yM" = ( +/obj/item/tank/jetpack/carbondioxide, +/turf/open/floor/vault, +/area/deathmatch) +"yN" = ( +/turf/closed/indestructible/fakedoor/engineering, +/area/deathmatch) +"yO" = ( +/obj/structure/ore_box, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating/airless, +/area/deathmatch) +"yP" = ( +/obj/structure/fluff/fake_scrubber, +/turf/open/floor/iron/white, +/area/deathmatch) +"za" = ( +/obj/structure/sign/warning/directional/north, +/turf/closed/mineral/asteroid, +/area/deathmatch) +"zj" = ( +/obj/structure/flora/bush/fullgrass/style_random, +/turf/open/floor/grass, +/area/deathmatch) +"zk" = ( +/obj/effect/decal/cleanable/greenglow, +/turf/open/floor/iron/white, +/area/deathmatch) +"zB" = ( +/obj/item/weldingtool, +/turf/open/floor/plating/airless, +/area/deathmatch) +"zC" = ( +/obj/effect/spawner/random/structure/grille, +/turf/open/floor/plating/airless, +/area/deathmatch) +"zE" = ( +/obj/machinery/porta_turret/syndicate{ + on = 0; + dir = 9 + }, +/turf/closed/wall/r_wall/plastitanium/syndicate, +/area/deathmatch) +"zJ" = ( +/obj/structure/fluff/tram_rail/floor{ + dir = 1 + }, +/turf/open/misc/asteroid/airless, +/area/deathmatch) +"zY" = ( +/obj/machinery/door/airlock/external, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/structure/fans/tiny, +/turf/open/floor/iron/white/small, +/area/deathmatch) +"Ai" = ( +/obj/structure/window/reinforced/spawner/directional/north, +/obj/structure/window/reinforced/spawner/directional/south, +/obj/effect/turf_decal/tile/blue/opposingcorners, +/turf/open/floor/iron/white, +/area/deathmatch) +"Ar" = ( +/obj/structure/holosign/barrier/engineering, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating/airless, +/area/deathmatch) +"AD" = ( +/obj/structure/lattice/catwalk, +/obj/structure/railing{ + dir = 1 + }, +/turf/open/space/basic, +/area/deathmatch) +"AJ" = ( +/obj/effect/turf_decal/tile/blue/half{ + dir = 1 + }, +/obj/structure/sign/departments/exam_room/directional/north, +/turf/open/floor/iron/white, +/area/deathmatch) +"AM" = ( +/obj/structure/fluff/tram_rail/anchor{ + dir = 1 + }, +/turf/open/space/basic, +/area/deathmatch) +"AY" = ( +/obj/structure/railing{ + dir = 8 + }, +/turf/open/floor/plating/airless, +/area/deathmatch) +"Bc" = ( +/obj/structure/railing/corner/end/flip{ + dir = 4 + }, +/obj/effect/turf_decal/caution, +/obj/effect/turf_decal/arrows{ + dir = 1; + pixel_y = -12 + }, +/turf/open/floor/plating/airless, +/area/deathmatch) +"Bh" = ( +/turf/open/floor/vault, +/area/deathmatch) +"Bx" = ( +/obj/machinery/door/airlock/external, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/obj/structure/fans/tiny, +/turf/open/floor/plating, +/area/deathmatch) +"Bz" = ( +/obj/machinery/light/small/directional/south, +/obj/structure/sign/warning/vacuum/directional/south, +/obj/machinery/suit_storage_unit/open, +/obj/item/tank/internals/oxygen, +/turf/open/floor/plating, +/area/deathmatch) +"BX" = ( +/obj/effect/portal/permanent{ + id = "dm_deepspace" + }, +/turf/open/space/basic, +/area/deathmatch) +"CA" = ( +/obj/structure/fluff/tram_rail/floor{ + dir = 1 + }, +/turf/open/floor/plating/airless, +/area/deathmatch) +"CE" = ( +/obj/structure/fluff/fake_camera{ + dir = 9 + }, +/turf/open/space/basic, +/area/deathmatch) +"CP" = ( +/obj/structure/rack, +/obj/machinery/light/directional/north, +/obj/item/melee/energy/sword/saber/red{ + pixel_x = 8; + pixel_y = 8 + }, +/obj/machinery/button/door/directional/east{ + id = "dm_deepspace" + }, +/turf/open/floor/iron, +/area/deathmatch) +"CT" = ( +/obj/effect/turf_decal/delivery, +/turf/open/floor/plating/airless, +/area/deathmatch) +"CV" = ( +/obj/machinery/nuclearbomb{ + anchored = 1 + }, +/obj/effect/light_emitter{ + set_cap = 2; + light_color = "#DEEFFF"; + set_luminosity = 4 + }, +/obj/effect/turf_decal/recharge, +/turf/open/floor/iron/large, +/area/deathmatch) +"CW" = ( +/obj/structure/fluff/fake_camera, +/turf/open/space/basic, +/area/deathmatch) +"CY" = ( +/obj/effect/mob_spawn/corpse/human/doctor, +/turf/open/space/basic, +/area/deathmatch) +"Di" = ( +/obj/structure/lattice/catwalk, +/obj/structure/railing/corner/end/flip{ + dir = 4 + }, +/turf/open/space/basic, +/area/deathmatch) +"Dn" = ( +/obj/effect/spawner/structure/window/hollow, +/obj/structure/flora/bush/large/style_random, +/turf/open/floor/grass, +/area/deathmatch) +"Dy" = ( +/obj/structure/chair/wood/wings{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood, +/area/deathmatch) +"DD" = ( +/obj/machinery/vending/cola/pwr_game, +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/fluff/fake_camera{ + dir = 10 + }, +/turf/open/floor/wood, +/area/deathmatch) +"DP" = ( +/obj/item/clothing/glasses/welding/up, +/turf/open/floor/plating/foam, +/area/deathmatch) +"DW" = ( +/obj/item/storage/belt/grenade{ + pixel_x = 10; + pixel_y = -7 + }, +/obj/item/grenade/smokebomb{ + pixel_x = 13; + pixel_y = -6 + }, +/obj/item/grenade/smokebomb{ + pixel_x = -12; + pixel_y = -10 + }, +/obj/item/grenade/empgrenade{ + pixel_x = -9; + pixel_y = 16 + }, +/obj/item/grenade/stingbang{ + pixel_y = 8; + pixel_x = 10 + }, +/turf/open/floor/plating/airless, +/area/deathmatch) +"Eb" = ( +/turf/closed/indestructible/reinforced, +/area/deathmatch) +"El" = ( +/obj/structure/fluff/tram_rail, +/turf/open/space/basic, +/area/deathmatch) +"Eu" = ( +/obj/structure/railing/corner/end/flip{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plating/airless, +/area/deathmatch) +"EB" = ( +/obj/structure/lattice/catwalk, +/obj/structure/marker_beacon/burgundy, +/turf/open/space/basic, +/area/deathmatch) +"EI" = ( +/obj/item/ammo_box/rocket{ + pixel_x = 4; + pixel_y = 8 + }, +/turf/open/space/basic, +/area/deathmatch) +"EJ" = ( +/obj/structure/sign/departments/cargo/directional/west, +/obj/effect/turf_decal/siding/wood, +/obj/machinery/light/directional/west, +/obj/effect/spawner/random/trash/food_packaging, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron/grimy, +/area/deathmatch) +"Fp" = ( +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/structure/fans/tiny, +/obj/machinery/door/airlock/external, +/turf/open/floor/iron/white/small, +/area/deathmatch) +"Fy" = ( +/obj/machinery/light/directional/east, +/obj/effect/decal/cleanable/dirt, +/obj/structure/fluff/fake_vent, +/turf/open/floor/iron/herringbone, +/area/deathmatch) +"FN" = ( +/obj/machinery/door/airlock/external, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/obj/structure/fans/tiny, +/turf/open/floor/plating, +/area/deathmatch) +"FP" = ( +/turf/open/misc/asteroid/dug, +/area/deathmatch) +"FS" = ( +/obj/machinery/door/airlock/external, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/obj/structure/fans/tiny, +/turf/open/floor/iron/white/small, +/area/deathmatch) +"FT" = ( +/obj/structure/sign/nanotrasen/directional/south, +/turf/open/space/basic, +/area/deathmatch) +"FZ" = ( +/mob/living/basic/pet/gondola, +/obj/structure/flora/bush/flowers_yw/style_random, +/turf/open/floor/grass, +/area/deathmatch) +"Gl" = ( +/obj/effect/turf_decal/tile/blue/anticorner/contrasted, +/obj/item/gun/energy/laser, +/obj/structure/table, +/turf/open/floor/iron/white, +/area/deathmatch) +"Gq" = ( +/obj/structure/fluff/fake_scrubber, +/turf/open/floor/iron/corner{ + dir = 4 + }, +/area/deathmatch) +"Gr" = ( +/obj/effect/decal/cleanable/rubble, +/turf/open/misc/asteroid/airless, +/area/deathmatch) +"Gu" = ( +/obj/structure/lattice, +/obj/machinery/light/broken/directional/north, +/turf/open/space/basic, +/area/deathmatch) +"GM" = ( +/obj/effect/turf_decal/sand/plating, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating/airless, +/area/deathmatch) +"Hc" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/mob_spawn/corpse/human/cargo_tech, +/turf/open/floor/iron/herringbone, +/area/deathmatch) +"Hg" = ( +/obj/effect/landmark/deathmatch_player_spawn, +/turf/open/floor/grass, +/area/deathmatch) +"Hv" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron/grimy, +/area/deathmatch) +"HH" = ( +/obj/structure/chair/comfy/shuttle/tactical{ + dir = 8 + }, +/obj/effect/light_emitter{ + set_cap = 2; + light_color = "#DEEFFF"; + set_luminosity = 4 + }, +/obj/effect/landmark/deathmatch_player_spawn, +/turf/open/floor/mineral/plastitanium, +/area/deathmatch) +"HI" = ( +/obj/machinery/power/shuttle_engine/propulsion/right{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plating/airless, +/area/deathmatch) +"HK" = ( +/obj/effect/mob_spawn/corpse/human/nanotrasensoldier, +/obj/effect/decal/cleanable/blood/gibs, +/turf/open/floor/plating/airless, +/area/deathmatch) +"HS" = ( +/obj/item/mecha_parts/mecha_equipment/thrusters/ion, +/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill, +/obj/item/mecha_parts/mecha_equipment/drill, +/turf/open/floor/plating/airless, +/area/deathmatch) +"HZ" = ( +/obj/structure/sign/warning/directional/east, +/turf/open/misc/asteroid/airless, +/area/deathmatch) +"Ic" = ( +/obj/structure/flora/rock/pile/icy/style_random{ + color = "#E09C96" + }, +/mob/living/basic/carp, +/obj/structure/festivus/anchored, +/turf/open/misc/asteroid/airless, +/area/deathmatch) +"Iv" = ( +/obj/structure/lattice/catwalk, +/obj/effect/landmark/deathmatch_player_spawn, +/turf/open/space/basic, +/area/deathmatch) +"Iw" = ( +/obj/effect/spawner/structure/window/reinforced/indestructible, +/turf/open/floor/plating, +/area/deathmatch) +"Ix" = ( +/obj/structure/sign/warning/directional/north, +/obj/structure/lattice, +/turf/open/space/basic, +/area/deathmatch) +"IC" = ( +/obj/machinery/door/airlock/survival_pod/glass{ + dir = 4 + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/structure/fans/tiny, +/turf/open/floor/grass, +/area/deathmatch) +"IG" = ( +/obj/structure/water_source/puddle, +/obj/structure/flora/bush/reed/style_random, +/turf/open/floor/grass, +/area/deathmatch) +"IK" = ( +/obj/structure/rack, +/obj/machinery/light/directional/south, +/obj/item/melee/energy/sword/saber/blue{ + pixel_x = 8; + pixel_y = 8 + }, +/obj/machinery/button/door/directional/west{ + id = "dm_deepspace" + }, +/turf/open/floor/iron, +/area/deathmatch) +"IT" = ( +/obj/structure/sign/poster/contraband/free_drone/directional/south, +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/vending/coffee, +/turf/open/floor/wood, +/area/deathmatch) +"IU" = ( +/obj/structure/chair/comfy/shuttle{ + dir = 4 + }, +/obj/structure/lattice, +/turf/open/misc/asteroid/airless, +/area/deathmatch) +"IX" = ( +/obj/structure/marker_beacon{ + light_color = "#FFE8AA"; + light_range = 20 + }, +/mob/living/basic/pet/gondola, +/turf/open/floor/grass, +/area/deathmatch) +"IY" = ( +/obj/effect/spawner/random/trash/cigbutt, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/herringbone, +/area/deathmatch) +"Jb" = ( +/obj/structure/sign/departments/maint/directional/west, +/obj/machinery/light/directional/west, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/vomit, +/turf/open/floor/iron/herringbone, +/area/deathmatch) +"Jn" = ( +/obj/effect/landmark/deathmatch_player_spawn, +/turf/open/floor/plating/airless, +/area/deathmatch) +"Jv" = ( +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating/airless, +/area/deathmatch) +"Kf" = ( +/obj/effect/decal/cleanable/blood/footprints{ + pixel_y = -21 + }, +/turf/open/floor/plating/airless, +/area/deathmatch) +"Kh" = ( +/mob/living/basic/pet/gondola, +/turf/open/floor/grass, +/area/deathmatch) +"Ki" = ( +/obj/item/tank/jetpack/improvised{ + pixel_x = -4; + pixel_y = 3 + }, +/obj/item/cigarette/greytide{ + pixel_x = 13; + pixel_y = 10 + }, +/turf/open/misc/asteroid/airless, +/area/deathmatch) +"Km" = ( +/obj/effect/decal/cleanable/ash, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/herringbone, +/area/deathmatch) +"Ko" = ( +/mob/living/basic/carp/mega, +/turf/open/misc/asteroid/airless, +/area/deathmatch) +"KJ" = ( +/turf/open/floor/plating/airless, +/area/deathmatch) +"KK" = ( +/obj/structure/sign/warning/directional/north, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating/airless, +/area/deathmatch) +"KN" = ( +/obj/structure/barricade/wooden, +/obj/structure/fans/tiny/invisible, +/turf/open/misc/asteroid/airless, +/area/deathmatch) +"KQ" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/item/tank/jetpack, +/turf/open/floor/plating/airless, +/area/deathmatch) +"Lw" = ( +/obj/structure/lattice/catwalk, +/obj/item/ammo_casing/rebar/syndie, +/obj/effect/decal/cleanable/blood, +/turf/open/space/basic, +/area/deathmatch) +"LO" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/herringbone, +/area/deathmatch) +"LV" = ( +/obj/structure/flora/bush/flowers_yw/style_random, +/turf/open/floor/grass, +/area/deathmatch) +"Mh" = ( +/obj/effect/turf_decal/sand/plating, +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/deathmatch_player_spawn, +/turf/open/floor/plating/airless, +/area/deathmatch) +"Mw" = ( +/obj/structure/spacevine{ + can_spread = 0; + can_tangle = 0; + color = "#E09C96" + }, +/turf/open/misc/asteroid/airless, +/area/deathmatch) +"MS" = ( +/obj/structure/sign/warning/directional/west, +/obj/structure/flora/rock/style_random{ + color = "#E09C96" + }, +/turf/open/misc/asteroid/airless, +/area/deathmatch) +"Nc" = ( +/obj/structure/shipping_container/cybersun, +/turf/open/floor/plating/airless, +/area/deathmatch) +"Ny" = ( +/obj/structure/railing/corner/end{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/mapping_helpers/broken_floor, +/obj/item/grenade/c4/x4, +/turf/open/floor/plating/airless, +/area/deathmatch) +"NF" = ( +/obj/structure/bed/medical/emergency, +/turf/open/space/basic, +/area/deathmatch) +"NK" = ( +/obj/effect/turf_decal/sand/plating, +/obj/structure/fluff/tram_rail/floor, +/turf/open/floor/plating/airless, +/area/deathmatch) +"NP" = ( +/obj/item/storage/box/smart_metal_foam, +/turf/open/floor/plating/airless, +/area/deathmatch) +"NS" = ( +/obj/structure/fluff/fake_vent, +/turf/open/floor/iron/white, +/area/deathmatch) +"Od" = ( +/obj/item/gun/ballistic/rifle/boltaction/pipegun/prime, +/obj/item/ammo_casing/shotgun/scatterlaser, +/obj/item/ammo_casing/shotgun/scatterlaser, +/obj/item/ammo_casing/shotgun/scatterlaser, +/turf/open/misc/asteroid/airless, +/area/deathmatch) +"Ov" = ( +/obj/effect/spawner/structure/window/reinforced/plasma/plastitanium, +/turf/open/floor/plating, +/area/deathmatch) +"OC" = ( +/obj/item/pickaxe/mini, +/turf/open/misc/asteroid/dug, +/area/deathmatch) +"OG" = ( +/obj/structure/table/glass, +/obj/effect/turf_decal/tile/blue/anticorner/contrasted{ + dir = 8 + }, +/obj/effect/spawner/random/medical/surgery_tool_advanced, +/turf/open/floor/iron/white, +/area/deathmatch) +"OL" = ( +/obj/vehicle/sealed/mecha/gygax, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating/airless, +/area/deathmatch) +"OQ" = ( +/obj/effect/turf_decal/tile/blue/anticorner/contrasted{ + dir = 4 + }, +/obj/structure/sign/poster/official/moth_epi/directional/north, +/turf/open/floor/iron/white, +/area/deathmatch) +"PM" = ( +/obj/structure/girder/displaced, +/turf/open/misc/asteroid/airless, +/area/deathmatch) +"PR" = ( +/obj/structure/glowshroom/single, +/turf/open/misc/asteroid/airless, +/area/deathmatch) +"Qt" = ( +/turf/open/floor/iron/half{ + dir = 8 + }, +/area/deathmatch) +"QE" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable, +/turf/open/space/basic, +/area/deathmatch) +"Rd" = ( +/obj/effect/turf_decal/tile/blue/half{ + dir = 1 + }, +/obj/structure/fluff/fake_camera{ + dir = 9 + }, +/mob/living/basic/bot/medbot/stationary, +/obj/machinery/wall_healer/free/directional/north, +/turf/open/floor/iron/white, +/area/deathmatch) +"Rf" = ( +/obj/structure/fluff/tram_rail/floor, +/obj/item/stack/cable_coil, +/turf/open/floor/plating/airless, +/area/deathmatch) +"Rh" = ( +/turf/open/floor/iron/white, +/area/deathmatch) +"Rm" = ( +/obj/structure/sign/warning/directional/south, +/turf/open/space/basic, +/area/deathmatch) +"Rr" = ( +/obj/structure/railing/corner/end{ + dir = 8 + }, +/obj/effect/turf_decal/caution, +/obj/effect/turf_decal/arrows{ + dir = 1; + pixel_y = -12 + }, +/turf/open/floor/plating/airless, +/area/deathmatch) +"RG" = ( +/obj/machinery/porta_turret/syndicate{ + on = 0; + dir = 10 + }, +/turf/closed/wall/r_wall/plastitanium/syndicate, +/area/deathmatch) +"RU" = ( +/obj/machinery/door/airlock/survival_pod/glass{ + dir = 1 + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/obj/structure/fans/tiny, +/turf/open/floor/grass, +/area/deathmatch) +"RV" = ( +/obj/structure/lattice, +/turf/open/space/basic, +/area/deathmatch) +"Sj" = ( +/obj/structure/railing/corner/end{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/item/storage/toolbox/electrical, +/turf/open/floor/plating/airless, +/area/deathmatch) +"So" = ( +/obj/item/bikehorn/airhorn, +/turf/open/space/basic, +/area/deathmatch) +"SJ" = ( +/obj/structure/fluff/tram_rail/anchor{ + dir = 1 + }, +/obj/structure/lattice, +/turf/open/space/basic, +/area/deathmatch) +"SS" = ( +/obj/effect/turf_decal/sand/plating, +/obj/item/wirecutters, +/turf/open/floor/plating/airless, +/area/deathmatch) +"Tb" = ( +/obj/structure/railing/corner, +/obj/item/stock_parts/power_store/cell/high, +/turf/open/floor/plating/airless, +/area/deathmatch) +"Tq" = ( +/obj/effect/mob_spawn/corpse/human/roboticist, +/turf/open/misc/asteroid/airless, +/area/deathmatch) +"TP" = ( +/obj/effect/mob_spawn/corpse/human/skeleton, +/turf/open/misc/asteroid/airless, +/area/deathmatch) +"Uy" = ( +/obj/structure/lattice/catwalk, +/obj/item/stack/sheet/iron/twenty, +/turf/open/space/basic, +/area/deathmatch) +"Uz" = ( +/turf/open/floor/iron, +/area/deathmatch) +"Vf" = ( +/obj/structure/sign/nanotrasen/directional/north, +/turf/open/space/basic, +/area/deathmatch) +"Vm" = ( +/obj/structure/table/glass, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/item/statuebust/hippocratic{ + pixel_y = 13 + }, +/obj/machinery/light/floor, +/turf/open/floor/iron/white, +/area/deathmatch) +"Vn" = ( +/obj/structure/grille/broken, +/obj/item/flashlight/glowstick/red{ + start_on = 1 + }, +/turf/open/misc/asteroid/airless, +/area/deathmatch) +"Vo" = ( +/obj/structure/spacevine, +/obj/item/gun/energy/recharge/ebow, +/turf/open/floor/grass, +/area/deathmatch) +"Vz" = ( +/obj/structure/grille/broken, +/obj/effect/decal/cleanable/glass/titanium, +/obj/item/shard/titanium, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/mineral/titanium/tiled/blue/airless, +/area/deathmatch) +"VN" = ( +/turf/open/floor/grass, +/area/deathmatch) +"Wc" = ( +/obj/effect/turf_decal/tile/blue, +/obj/machinery/light/floor, +/obj/machinery/recharger, +/obj/structure/table, +/turf/open/floor/iron/white, +/area/deathmatch) +"WA" = ( +/obj/structure/marker_beacon/burgundy, +/turf/open/misc/asteroid/airless, +/area/deathmatch) +"Xf" = ( +/obj/structure/window/reinforced/spawner/directional/west, +/obj/effect/turf_decal/tile/blue/opposingcorners, +/turf/open/floor/iron/white, +/area/deathmatch) +"Xr" = ( +/obj/structure/flora/rock/pile/icy/style_random{ + color = "#E09C96" + }, +/turf/open/misc/asteroid/airless, +/area/deathmatch) +"Xs" = ( +/obj/structure/lattice/catwalk, +/obj/structure/reagent_dispensers/fueltank, +/turf/open/space/basic, +/area/deathmatch) +"Xu" = ( +/obj/structure/lattice, +/obj/item/tank/jetpack, +/turf/open/space/basic, +/area/deathmatch) +"XE" = ( +/obj/structure/ore_box, +/turf/open/misc/asteroid/airless, +/area/deathmatch) +"XI" = ( +/obj/structure/lattice/catwalk, +/obj/structure/marker_beacon/teal, +/turf/open/space/basic, +/area/deathmatch) +"XJ" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plating/airless, +/area/deathmatch) +"Yo" = ( +/obj/structure/fluff/tram_rail{ + dir = 1 + }, +/turf/open/space/basic, +/area/deathmatch) +"Yt" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 5 + }, +/obj/effect/light_emitter{ + set_cap = 2; + light_color = "#DEEFFF"; + set_luminosity = 4 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron/grimy, +/area/deathmatch) +"YJ" = ( +/obj/item/pickaxe/mini, +/turf/open/misc/asteroid/airless, +/area/deathmatch) +"YK" = ( +/obj/machinery/door/airlock/external, +/obj/structure/fans/tiny, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 4 + }, +/turf/open/floor/iron/white/small, +/area/deathmatch) +"YX" = ( +/obj/effect/turf_decal/delivery, +/obj/item/stock_parts/power_store/cell/high, +/turf/open/floor/plating/airless, +/area/deathmatch) +"Zf" = ( +/obj/machinery/door/airlock/external, +/obj/structure/fans/tiny, +/turf/open/floor/mineral/plastitanium, +/area/deathmatch) +"Zw" = ( +/obj/structure/lattice/catwalk, +/obj/item/clothing/glasses/welding/up, +/turf/open/space/basic, +/area/deathmatch) +"ZJ" = ( +/obj/effect/decal/cleanable/blood/tracks{ + dir = 4 + }, +/turf/open/floor/plating/airless, +/area/deathmatch) +"ZK" = ( +/turf/open/misc/asteroid/airless, +/area/deathmatch) +"ZS" = ( +/obj/effect/turf_decal/sand/plating, +/obj/structure/barricade/wooden, +/turf/open/floor/plating/airless, +/area/deathmatch) +"ZU" = ( +/obj/machinery/power/shuttle_engine/propulsion/right{ + dir = 8 + }, +/turf/closed/wall/mineral/titanium/nodiagonal, +/area/deathmatch) +"ZW" = ( +/obj/machinery/light/directional/south, +/obj/machinery/porta_turret/syndicate/energy, +/turf/open/floor/iron, +/area/deathmatch) + +(1,1,1) = {" +rN +rN +rN +rN +rN +rN +rN +rN +rN +rN +rN +rN +rN +rN +rN +ZK +aH +ZK +zJ +ZK +rN +rN +rN +rN +rN +rN +rN +Eb +Eb +Eb +Eb +fL +Eb +Eb +yL +Eb +mL +Eb +Eb +Eb +"} +(2,1,1) = {" +rN +rN +rN +rN +rN +rN +Kh +LV +rN +rN +rN +rN +rN +rN +dH +KK +NK +Jv +fH +Jv +vJ +AY +ys +cF +NP +ne +Xs +Eb +gf +Eb +lF +Hc +Jb +LO +xL +yu +yu +EJ +DD +Eb +"} +(3,1,1) = {" +rN +jb +rN +rN +VN +zj +xM +VN +oi +VN +IC +VN +ni +sT +bL +KJ +Rf +YX +CA +mO +Rr +KJ +Uy +ys +qv +qi +ys +nc +ap +Bx +iV +gP +LO +Fy +xa +hM +oU +qK +IT +Eb +"} +(4,1,1) = {" +rN +rN +rN +LV +VN +bW +Hg +IG +xM +VN +rN +rN +rN +dH +ZS +hu +aF +CT +vY +yl +Bc +Tb +pk +lH +HS +ys +ny +Eb +mi +Eb +mi +mi +mi +Eb +Eb +Dy +Yt +uI +yt +Eb +"} +(5,1,1) = {" +rN +rN +pP +VN +VN +oi +VN +VN +bW +VN +zj +rN +rN +rN +dH +Ix +pK +RV +gC +RV +li +fd +rC +rC +rC +rj +DP +RV +RV +RV +RV +RV +RV +RV +mi +hJ +jY +Hv +xp +Eb +"} +(6,1,1) = {" +rN +rN +bW +xM +zj +Vo +yb +zj +LV +IX +pP +rN +rN +rN +dh +wf +El +wf +Yo +wf +Ny +Eu +wf +rC +vs +rC +wf +wf +wf +wf +wf +wf +wf +RV +mi +mi +Eb +uv +yu +Eb +"} +(7,1,1) = {" +rN +rN +FZ +zj +oi +pP +zj +xM +VN +rN +rN +rN +rN +wf +wf +wf +El +wf +Yo +wf +wf +wf +wf +wf +rC +wf +wf +wf +wf +wf +wf +BX +wf +bP +RV +RV +Eb +oZ +Km +yN +"} +(8,1,1) = {" +rN +rN +xM +bW +VN +VN +bW +oi +rN +rN +rN +rN +wf +wf +wf +wf +El +wf +Yo +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +RV +mi +IY +uX +Eb +"} +(9,1,1) = {" +rN +rN +rN +oi +xM +LV +xM +rN +rN +rN +Mw +Mw +wf +wf +wf +vy +El +wf +Yo +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +RV +mi +LO +vz +yN +"} +(10,1,1) = {" +rN +rN +rN +RU +rN +rN +rN +rN +rN +FP +ZK +Mw +Mw +wf +wf +wf +El +wf +Yo +wf +wf +yg +Ov +yg +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +RV +mi +iV +sW +Eb +"} +(11,1,1) = {" +rN +rN +rN +VN +rN +gd +rN +rN +rN +ZK +Xr +rN +rN +rN +wf +wf +El +wf +Yo +wf +wf +zE +eb +RG +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +RV +Eb +FN +Eb +Eb +"} +(12,1,1) = {" +rN +rN +rN +xB +rN +rN +dH +og +IU +eB +ZU +rN +rN +wf +wf +wf +El +wf +Yo +wf +yg +yg +HH +yg +yg +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +RV +mi +ap +Bz +Eb +"} +(13,1,1) = {" +dH +za +rN +Mw +rN +Xr +hk +ZK +Vn +lf +PM +ZK +Mw +wf +wf +wf +El +wf +Yo +wf +cT +yg +Zf +yg +cT +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +RV +Eb +oO +Eb +Eb +"} +(14,1,1) = {" +MS +ZK +ZK +qw +ZK +ZK +ZK +ZK +TP +rG +qg +Mw +Mw +wf +wf +wf +El +wf +Yo +wf +HI +cT +ys +cT +HI +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +AD +ys +Xs +rN +"} +(15,1,1) = {" +wf +YJ +wf +wf +wf +wf +wf +qw +PM +Vz +og +cX +rN +rN +wf +wf +El +wf +Yo +wf +wf +HI +wf +HI +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +uA +ys +ne +rN +"} +(16,1,1) = {" +wf +wf +wf +wf +wf +wf +wf +wf +ZK +ZK +ZK +rN +rN +rN +dH +KJ +pf +CT +AM +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +KJ +DW +zB +rN +"} +(17,1,1) = {" +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +ZK +rN +rN +rN +dH +KJ +pf +CT +AM +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +Di +Lw +Zw +rN +"} +(18,1,1) = {" +zC +zC +zC +wf +zC +zC +zC +wf +wf +wf +wf +Xr +rN +rN +wf +wf +El +wf +Yo +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +AD +ys +ys +rN +"} +(19,1,1) = {" +RV +wf +RV +wf +RV +wf +Xu +wf +wf +wf +wf +wf +wf +wf +wf +wf +El +wf +Yo +RV +wf +wf +wf +wf +wf +wf +wf +bP +RV +KQ +lV +lV +yw +RV +RV +RV +Sj +KJ +eE +rN +"} +(20,1,1) = {" +RV +wu +RV +wu +RV +wu +RV +wf +wf +wf +wf +wf +wf +wf +wf +wf +El +RV +jS +jS +wf +wf +wf +wf +wf +wf +wf +wf +RV +KJ +Nc +Jn +KJ +wf +wf +wf +xJ +nu +SS +rN +"} +(21,1,1) = {" +RV +wu +RV +wu +RV +wu +RV +wf +wf +wf +wf +wf +wf +wf +wf +wf +El +HK +fs +og +CE +wf +wf +wf +wf +wf +wf +wf +RV +KJ +KJ +KJ +KJ +wf +wf +wf +fP +KJ +Jv +rN +"} +(22,1,1) = {" +QE +QE +QE +QE +QE +QE +QE +lZ +wf +wf +wf +wf +wf +wf +wf +wf +nW +lv +og +nW +wf +wf +wf +wf +wf +wf +wf +bP +RV +XJ +XJ +XJ +XJ +RV +RV +RV +px +Jv +rN +rN +"} +(23,1,1) = {" +RV +wu +wf +wu +RV +wu +RV +wf +wf +wf +wf +wf +wf +wf +wf +wf +yB +ZJ +yB +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +Rm +dH +rN +rN +"} +(24,1,1) = {" +RV +wu +wf +wu +fG +wu +RV +wf +wf +wf +wf +wf +wf +wf +wf +qg +qg +lv +qg +qg +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +qw +rN +rN +"} +(25,1,1) = {" +RV +wf +wf +wf +RV +wf +RV +wf +wf +wf +wf +wf +wf +wf +CW +qg +vh +Uz +IK +qg +Vf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +OC +rN +wf +wf +ZK +Ic +rN +"} +(26,1,1) = {" +zC +zC +zC +wf +zC +zC +zC +wf +wf +wf +wf +wf +wf +wf +wf +tc +rg +Qt +Gq +tc +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +rN +rN +rN +wf +ir +Ko +rN +"} +(27,1,1) = {" +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +tc +mq +CV +mq +tc +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +rN +rN +rN +rb +EI +ZK +rN +"} +(28,1,1) = {" +wf +wf +wf +wf +So +wf +wf +wf +rN +Ki +EB +wf +wf +wf +wf +tc +nE +Qt +bN +tc +wf +wf +wf +yg +Ov +yg +wf +wf +wf +wf +rN +Xr +wf +XE +rN +wf +wf +wf +ZK +rN +"} +(29,1,1) = {" +wf +wf +wf +ah +NF +wf +lE +rN +rN +Od +vn +ys +wf +wf +FT +qg +CP +Uz +ZW +qg +CE +wf +wf +zE +eb +RG +wf +wf +wf +rN +lL +rN +wf +wf +wf +wf +wf +wf +wf +rN +"} +(30,1,1) = {" +wf +wf +wf +wf +wL +wf +wf +rN +rN +ZK +ZK +Iv +wf +wf +wf +qg +qg +vB +qg +qg +wf +wf +yg +yg +HH +yg +yg +wf +wf +rN +oJ +rN +wf +wf +wf +wf +wf +wf +ZK +rN +"} +(31,1,1) = {" +wf +YK +wf +wf +wf +CY +wf +wf +rN +ZK +ZK +sy +wf +wf +wf +wf +yB +ip +yB +wf +wf +wf +cT +yg +Zf +yg +cT +wf +wf +qw +rN +wf +wf +rN +cX +wf +wf +ZK +Xr +rN +"} +(32,1,1) = {" +RV +Ai +RV +RV +wf +wf +wf +wf +rN +rN +WA +ys +wf +wf +wf +qg +og +vB +qg +nW +wf +wf +HI +cT +ys +cT +HI +wf +wf +wf +wf +wf +rN +rN +rN +wf +wf +XE +rN +rN +"} +(33,1,1) = {" +Eb +gK +mi +mi +XI +wf +wf +wf +wf +rN +Gr +wf +wf +wf +CW +og +is +Kf +yf +nW +wf +wf +wf +HI +wf +HI +wf +wf +wf +wf +wf +wf +rN +rN +rN +wf +cW +dH +rN +rN +"} +(34,1,1) = {" +Eb +em +ve +Dn +mi +RV +wf +wf +wf +wf +wf +wf +wf +wf +wf +Bh +kK +jS +KJ +yM +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +wf +rN +wf +wf +Mh +KN +qw +rN +"} +(35,1,1) = {" +mL +Rh +Vm +OG +mi +RV +wf +wf +wf +wf +wf +wf +wf +wf +wf +KJ +jS +nQ +RV +jS +wf +wf +wf +ZK +wf +wf +ZK +Xr +wf +tA +wf +wf +wf +wf +wf +wf +cW +dH +PR +rN +"} +(36,1,1) = {" +Eb +AJ +NS +Rh +Fp +Xf +Xf +FS +wf +wf +wf +wf +wf +wf +wf +jS +RV +jS +Yo +wf +wf +Xr +wf +wf +wf +Tq +rN +rN +FP +Ar +GM +wf +wf +wf +wf +ZK +rN +rN +ZK +rN +"} +(37,1,1) = {" +Eb +Rd +zk +yP +zY +dx +dx +FS +wf +nK +wf +wf +wf +wf +wf +nW +Gu +wf +Yo +wf +wf +wf +wf +HZ +rN +rN +rN +rN +rN +ep +lb +GM +wf +wf +YJ +rN +rN +kO +PR +rN +"} +(38,1,1) = {" +mL +Rh +Wc +hH +mi +RV +wf +wf +wf +wf +wf +wf +wf +BX +wf +RV +El +wf +Yo +wf +wf +YJ +cb +dH +rN +rN +rN +rN +rN +dH +ry +Jv +wf +wf +ZK +rN +rN +Xr +el +rN +"} +(39,1,1) = {" +Eb +OQ +Gl +Dn +mi +RV +wf +wf +ZK +rN +FP +ZK +wf +wf +wf +wf +wd +CT +SJ +KJ +dH +rN +rN +rN +rN +rN +OL +fF +rN +rN +rN +yO +wf +wf +Xr +rN +rN +rN +rN +rN +"} +(40,1,1) = {" +Eb +vu +Iw +Iw +XI +wf +wf +cX +rN +rN +rN +rN +qw +wf +wf +wf +wd +CT +SJ +KJ +dH +rN +rN +rN +rN +rN +rN +rN +rN +rN +rN +rN +wf +wf +rN +rN +rN +rN +rN +rN +"} diff --git a/_maps/shuttles/emergency_casino.dmm b/_maps/shuttles/emergency_casino.dmm index e4521dc80b6..09a114aeac2 100644 --- a/_maps/shuttles/emergency_casino.dmm +++ b/_maps/shuttles/emergency_casino.dmm @@ -1188,7 +1188,7 @@ /obj/item/storage/crayons, /obj/item/storage/crayons, /obj/item/storage/crayons, -/mob/living/basic/bot/honkbot, +/mob/living/basic/bot/secbot/honkbot/nopatrol, /turf/open/floor/sepia, /area/shuttle/escape) "NN" = ( diff --git a/_maps/shuttles/emergency_shadow.dmm b/_maps/shuttles/emergency_shadow.dmm index ac2807c70f3..b1b61cc376a 100644 --- a/_maps/shuttles/emergency_shadow.dmm +++ b/_maps/shuttles/emergency_shadow.dmm @@ -582,7 +582,7 @@ /turf/open/floor/eighties, /area/shuttle/escape) "BJ" = ( -/mob/living/simple_animal/bot/secbot{ +/mob/living/basic/bot/secbot{ name = "Officer McCuff" }, /turf/open/floor/iron/dark/smooth_large, diff --git a/_maps/shuttles/infiltrator_basic.dmm b/_maps/shuttles/infiltrator_basic.dmm index b1b00f10d57..61f8ea231df 100644 --- a/_maps/shuttles/infiltrator_basic.dmm +++ b/_maps/shuttles/infiltrator_basic.dmm @@ -382,11 +382,11 @@ "bK" = ( /obj/effect/turf_decal/siding/thinplating_new/dark/corner, /obj/effect/mapping_helpers/airlock/autoname, -/obj/machinery/door/airlock/hatch, /obj/effect/turf_decal/siding/thinplating_new{ dir = 8 }, /obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/obj/machinery/door/airlock/highsecurity/syndicate, /turf/open/floor/mineral/plastitanium/red, /area/shuttle/syndicate/medical) "bM" = ( @@ -397,8 +397,8 @@ dir = 8 }, /obj/effect/mapping_helpers/airlock/autoname, -/obj/machinery/door/airlock/hatch, /obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/obj/machinery/door/airlock/highsecurity/syndicate, /turf/open/floor/mineral/plastitanium/red, /area/shuttle/syndicate/engineering) "bO" = ( @@ -629,12 +629,12 @@ /turf/open/floor/iron/dark, /area/shuttle/syndicate/engineering) "lm" = ( -/obj/machinery/door/airlock/hatch, /obj/effect/mapping_helpers/airlock/autoname, /obj/effect/turf_decal/stripes/red/line{ dir = 1 }, /obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/obj/machinery/door/airlock/highsecurity/syndicate, /turf/open/floor/iron/dark, /area/shuttle/syndicate/bridge) "lo" = ( @@ -645,8 +645,8 @@ dir = 4 }, /obj/effect/mapping_helpers/airlock/autoname, -/obj/machinery/door/airlock/hatch, /obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/obj/machinery/door/airlock/highsecurity/syndicate, /turf/open/floor/mineral/plastitanium/red, /area/shuttle/syndicate/eva) "lJ" = ( @@ -1068,9 +1068,9 @@ /area/shuttle/syndicate/airlock) "Tu" = ( /obj/effect/mapping_helpers/airlock/autoname, -/obj/machinery/door/airlock/hatch, /obj/effect/turf_decal/stripes/red/line, /obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/obj/machinery/door/airlock/highsecurity/syndicate, /turf/open/floor/iron/dark, /area/shuttle/syndicate/hallway) "TD" = ( diff --git a/_maps/templates/battlecruiser_starfury.dmm b/_maps/templates/battlecruiser_starfury.dmm index bb32515c5a1..24c52bda672 100644 --- a/_maps/templates/battlecruiser_starfury.dmm +++ b/_maps/templates/battlecruiser_starfury.dmm @@ -1857,7 +1857,7 @@ /area/shuttle/sbc_starfury) "hc" = ( /obj/effect/turf_decal/delivery, -/obj/machinery/door/poddoor/shutters{ +/obj/machinery/door/poddoor/shutters/syndicate{ id = "syndie_battlecruiser_mech" }, /turf/open/floor/pod/light, @@ -2182,12 +2182,11 @@ /area/shuttle/sbc_starfury) "hX" = ( /obj/effect/mapping_helpers/airlock/locked, -/obj/machinery/door/airlock/highsecurity{ - id_tag = "syndie_battlecruiser_armory"; - name = "Starfury Armory" - }, /obj/effect/mapping_helpers/airlock/access/all/syndicate/general, /obj/effect/mapping_helpers/airlock/cutaiwire, +/obj/machinery/door/airlock/highsecurity/syndicate{ + name = "Starfury Armory" + }, /turf/open/floor/iron/dark, /area/shuttle/sbc_starfury) "hZ" = ( @@ -4389,11 +4388,11 @@ /area/shuttle/sbc_starfury) "Ay" = ( /obj/effect/turf_decal/delivery, -/obj/machinery/door/poddoor/shutters{ - id = "syndie_battlecruiser_mech" - }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/door/poddoor/shutters/syndicate{ + id = "syndie_battlecruiser_mech" + }, /turf/open/floor/pod/light, /area/shuttle/sbc_starfury) "AF" = ( @@ -5814,12 +5813,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/mapping_helpers/airlock/locked, -/obj/machinery/door/airlock/highsecurity{ - id_tag = "syndie_battlecruiser_armory"; - name = "Starfury Armory" - }, /obj/effect/mapping_helpers/airlock/access/all/syndicate/general, /obj/effect/mapping_helpers/airlock/cutaiwire, +/obj/machinery/door/airlock/highsecurity/syndicate{ + name = "Starfury Armory" + }, /turf/open/floor/iron/dark, /area/shuttle/sbc_starfury) "ZR" = ( diff --git a/_maps/templates/holodeck_medicalsim.dmm b/_maps/templates/holodeck_medicalsim.dmm index 11cb6662f49..e0dc07ddbd2 100644 --- a/_maps/templates/holodeck_medicalsim.dmm +++ b/_maps/templates/holodeck_medicalsim.dmm @@ -473,6 +473,10 @@ dir = 1 }, /obj/structure/closet/crate/freezer/organ, +/obj/item/bodypart/leg/left, +/obj/item/bodypart/leg/right, +/obj/item/bodypart/arm/right, +/obj/item/bodypart/arm/left, /turf/open/floor/holofloor{ icon_state = "white" }, diff --git a/_maps/templates/holodeck_prison.dmm b/_maps/templates/holodeck_prison.dmm new file mode 100644 index 00000000000..615491e6bd1 --- /dev/null +++ b/_maps/templates/holodeck_prison.dmm @@ -0,0 +1,475 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"b" = ( +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 1 + }, +/turf/open/floor/holofloor, +/area/template_noop) +"c" = ( +/obj/effect/turf_decal/caution, +/turf/open/floor/holofloor/dark, +/area/template_noop) +"d" = ( +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 8 + }, +/turf/open/floor/holofloor, +/area/template_noop) +"e" = ( +/obj/effect/turf_decal/board_number/two{ + pixel_y = 21 + }, +/turf/open/floor/holofloor, +/area/template_noop) +"f" = ( +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 9 + }, +/obj/machinery/flasher/directional/east{ + id = "Holodeck Cell 3"; + pixel_x = 0 + }, +/obj/structure/window/reinforced/spawner/directional/north, +/turf/open/floor/holofloor/white, +/area/template_noop) +"g" = ( +/obj/structure/table, +/obj/machinery/button/flasher{ + id = "Holodeck Cell 2"; + name = "Cell 2"; + pixel_y = 8 + }, +/obj/machinery/button/flasher{ + id = "Holodeck Cell 4"; + name = "Cell 4"; + pixel_y = -3 + }, +/obj/item/restraints/handcuffs{ + pixel_x = -17; + pixel_y = 9 + }, +/obj/item/restraints/handcuffs{ + pixel_x = -17; + pixel_y = -3 + }, +/turf/open/floor/holofloor/dark, +/area/template_noop) +"h" = ( +/obj/machinery/computer/security{ + dir = 4 + }, +/turf/open/floor/holofloor/dark, +/area/template_noop) +"j" = ( +/obj/structure/bed, +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 9 + }, +/obj/item/bedsheet/red, +/turf/open/floor/holofloor/white, +/area/template_noop) +"k" = ( +/obj/structure/chair/e_chair{ + dir = 1 + }, +/obj/effect/turf_decal/bot, +/turf/open/floor/holofloor/dark, +/area/template_noop) +"l" = ( +/obj/machinery/status_display/door_timer{ + id = "Holodeck Cell 2"; + req_access = null; + name = "Cell 2" + }, +/obj/structure/table, +/turf/open/floor/holofloor/dark, +/area/template_noop) +"n" = ( +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 10 + }, +/obj/structure/closet/secure_closet/brig/holodeck{ + id = "Holodeck Cell 4" + }, +/turf/open/floor/holofloor/white, +/area/template_noop) +"o" = ( +/obj/effect/turf_decal/board_number/four, +/turf/open/floor/holofloor, +/area/template_noop) +"p" = ( +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 5 + }, +/obj/item/instrument/harmonica, +/obj/machinery/door/window/brigdoor/security/holodeck/left/directional/north{ + id = "Holodeck Cell 3"; + name = "Cell 3" + }, +/turf/open/floor/holofloor/white, +/area/template_noop) +"q" = ( +/obj/effect/turf_decal/board_number/one{ + pixel_y = 21 + }, +/turf/open/floor/holofloor, +/area/template_noop) +"r" = ( +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 6 + }, +/obj/structure/closet/secure_closet/brig/holodeck{ + id = "Holodeck Cell 3" + }, +/turf/open/floor/holofloor/white, +/area/template_noop) +"s" = ( +/turf/open/floor/holofloor, +/area/template_noop) +"t" = ( +/obj/item/book/manual/wiki/security_space_law{ + pixel_y = 13 + }, +/obj/structure/table, +/obj/machinery/recharger, +/obj/item/restraints/handcuffs{ + pixel_x = -17; + pixel_y = 9 + }, +/obj/item/restraints/handcuffs{ + pixel_x = -17; + pixel_y = -3 + }, +/turf/open/floor/holofloor/dark, +/area/template_noop) +"u" = ( +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 5 + }, +/obj/structure/closet/secure_closet/brig/holodeck{ + id = "Holodeck Cell 1" + }, +/turf/open/floor/holofloor/white, +/area/template_noop) +"v" = ( +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 9 + }, +/obj/structure/closet/secure_closet/brig/holodeck{ + id = "Holodeck Cell 2" + }, +/turf/open/floor/holofloor/white, +/area/template_noop) +"x" = ( +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 5 + }, +/obj/structure/bed, +/obj/item/bedsheet/red, +/turf/open/floor/holofloor/white, +/area/template_noop) +"y" = ( +/obj/structure/window/reinforced/fulltile, +/turf/open/floor/holofloor/dark, +/area/template_noop) +"z" = ( +/obj/machinery/computer/records/security{ + dir = 8 + }, +/turf/open/floor/holofloor/dark, +/area/template_noop) +"A" = ( +/obj/effect/turf_decal/trimline/red/filled/warning{ + dir = 1 + }, +/turf/open/floor/holofloor/dark, +/area/template_noop) +"B" = ( +/obj/structure/closet{ + name = "evidence closet" + }, +/turf/open/floor/holofloor/dark, +/area/template_noop) +"C" = ( +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 6 + }, +/obj/item/coin/antagtoken, +/obj/machinery/door/window/brigdoor/security/holodeck/left/directional/south{ + id = "Holodeck Cell 1"; + name = "Cell 1" + }, +/turf/open/floor/holofloor/white, +/area/template_noop) +"D" = ( +/obj/machinery/status_display/door_timer{ + id = "Holodeck Cell 1"; + name = "Cell 1"; + req_access = null + }, +/obj/structure/table, +/turf/open/floor/holofloor/dark, +/area/template_noop) +"G" = ( +/obj/effect/turf_decal/trimline/red/filled/corner{ + dir = 4 + }, +/turf/open/floor/holofloor, +/area/template_noop) +"H" = ( +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 6 + }, +/obj/machinery/flasher/directional/west{ + id = "Holodeck Cell 2"; + pixel_x = 1 + }, +/obj/structure/window/reinforced/spawner/directional/south, +/turf/open/floor/holofloor/white, +/area/template_noop) +"I" = ( +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 10 + }, +/obj/machinery/flasher/directional/east{ + id = "Holodeck Cell 1"; + pixel_x = 0 + }, +/obj/structure/window/reinforced/spawner/directional/south, +/turf/open/floor/holofloor/white, +/area/template_noop) +"J" = ( +/obj/effect/turf_decal/trimline/red/filled/warning, +/turf/open/floor/holofloor/dark, +/area/template_noop) +"K" = ( +/obj/effect/turf_decal/trimline/red/filled/line, +/turf/open/floor/holofloor, +/area/template_noop) +"L" = ( +/obj/effect/turf_decal/trimline/red/filled/corner{ + dir = 8 + }, +/turf/open/floor/holofloor, +/area/template_noop) +"M" = ( +/obj/effect/turf_decal/trimline/red/filled/corner{ + dir = 1 + }, +/turf/open/floor/holofloor, +/area/template_noop) +"N" = ( +/obj/machinery/status_display/door_timer{ + id = "Holodeck Cell 4"; + req_access = null; + name = "Cell 4" + }, +/obj/structure/table, +/turf/open/floor/holofloor/dark, +/area/template_noop) +"O" = ( +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 5 + }, +/obj/machinery/flasher/directional/west{ + id = "Holodeck Cell 4"; + pixel_x = 0 + }, +/obj/structure/window/reinforced/spawner/directional/north, +/turf/open/floor/holofloor/white, +/area/template_noop) +"P" = ( +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 9 + }, +/obj/item/dice/d6, +/obj/machinery/door/window/brigdoor/security/holodeck/right/directional/north{ + name = "Cell 4"; + id = "Holodeck Cell 4" + }, +/turf/open/floor/holofloor/white, +/area/template_noop) +"Q" = ( +/obj/structure/table, +/obj/machinery/button/flasher{ + id = "Holodeck Cell 3"; + name = "Cell 3"; + pixel_y = -3 + }, +/obj/machinery/button/flasher{ + id = "Holodeck Cell 1"; + name = "Cell 1"; + pixel_y = 8 + }, +/turf/open/floor/holofloor/dark, +/area/template_noop) +"R" = ( +/obj/effect/turf_decal/board_number/three, +/turf/open/floor/holofloor, +/area/template_noop) +"S" = ( +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 4 + }, +/turf/open/floor/holofloor, +/area/template_noop) +"T" = ( +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 6 + }, +/obj/structure/bed, +/obj/item/bedsheet/red, +/turf/open/floor/holofloor/white, +/area/template_noop) +"U" = ( +/obj/machinery/status_display/door_timer{ + id = "Holodeck Cell 3"; + req_access = null; + name = "Cell 3" + }, +/obj/structure/table, +/turf/open/floor/holofloor/dark, +/area/template_noop) +"V" = ( +/obj/effect/turf_decal/trimline/red/filled/warning{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, +/turf/open/floor/holofloor/dark, +/area/template_noop) +"W" = ( +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 10 + }, +/obj/item/toy/figure/prisoner, +/obj/machinery/door/window/brigdoor/security/holodeck/right/directional/south{ + name = "Cell 2"; + id = "Holodeck Cell 2" + }, +/turf/open/floor/holofloor/white, +/area/template_noop) +"X" = ( +/obj/effect/turf_decal/trimline/red/filled/corner, +/turf/open/floor/holofloor, +/area/template_noop) +"Y" = ( +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 10 + }, +/obj/structure/bed, +/obj/item/bedsheet/red, +/turf/open/floor/holofloor/white, +/area/template_noop) +"Z" = ( +/obj/structure/chair/comfy/black, +/turf/open/floor/holofloor/dark, +/area/template_noop) + +(1,1,1) = {" +j +I +s +s +s +s +s +s +f +Y +"} +(2,1,1) = {" +u +C +q +X +S +S +G +R +p +r +"} +(3,1,1) = {" +y +y +s +K +D +U +b +s +y +y +"} +(4,1,1) = {" +B +J +s +K +h +Q +b +s +A +c +"} +(5,1,1) = {" +B +J +s +K +Z +t +b +s +V +k +"} +(6,1,1) = {" +B +J +s +K +z +g +b +s +A +c +"} +(7,1,1) = {" +y +y +s +K +l +N +b +s +y +y +"} +(8,1,1) = {" +v +W +e +L +d +d +M +o +P +n +"} +(9,1,1) = {" +x +H +s +s +s +s +s +s +O +T +"} diff --git a/_maps/templates/lazy_templates/nukie_base.dmm b/_maps/templates/lazy_templates/nukie_base.dmm index 537fe8fda84..707e8a251f3 100644 --- a/_maps/templates/lazy_templates/nukie_base.dmm +++ b/_maps/templates/lazy_templates/nukie_base.dmm @@ -254,7 +254,7 @@ /area/centcom/syndicate_mothership) "du" = ( /obj/structure/chair/stool/directional/north, -/obj/effect/landmark/start/nukeop, +/obj/effect/landmark/start/nukeop_base, /obj/structure/sign/poster/contraband/donk_co/directional/south, /turf/open/floor/wood/tile, /area/centcom/syndicate_mothership/control) @@ -1126,7 +1126,7 @@ /turf/open/floor/mineral/plastitanium/red, /area/centcom/syndicate_mothership/expansion_bioterrorism) "my" = ( -/obj/effect/landmark/start/nukeop_leader, +/obj/effect/landmark/start/nukeop_base/leader, /obj/effect/turf_decal/tile/bar/opposingcorners, /turf/open/floor/iron, /area/centcom/syndicate_mothership/control) @@ -1181,11 +1181,12 @@ /obj/effect/turf_decal/siding/thinplating_new/dark{ dir = 1 }, -/obj/machinery/door/poddoor/shutters{ - id = "FBBZ1"; - name = "Security Shutters" - }, /obj/structure/fans/tiny, +/obj/machinery/door/poddoor/shutters/syndicate{ + id = "FBBZ1"; + name = "Security Shutters"; + dir = 1 + }, /turf/open/floor/mineral/titanium, /area/centcom/syndicate_mothership/control) "nk" = ( @@ -1441,7 +1442,7 @@ /obj/structure/chair/greyscale{ dir = 4 }, -/obj/effect/landmark/start/nukeop_overwatch, +/obj/effect/landmark/start/nukeop_base/overwatch, /turf/open/floor/mineral/plastitanium, /area/centcom/syndicate_mothership) "pU" = ( @@ -1627,11 +1628,20 @@ dir = 1 }, /obj/effect/turf_decal/siding/wideplating, -/obj/machinery/door/poddoor/shutters/indestructible{ - name = "Subterrainian Cargo Lift" +/obj/machinery/door/poddoor/shutters/syndicate/indestructible{ + name = "Base Lift"; + dir = 1; + id_tag = "nukiespawnlift"; + id = "nukiespawnlift" }, /turf/open/floor/iron/dark/textured_half, /area/centcom/syndicate_mothership/control) +"rw" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 6 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/centcom/syndicate_mothership/control) "rA" = ( /obj/effect/turf_decal/siding/purple{ dir = 1 @@ -2032,6 +2042,12 @@ /obj/effect/turf_decal/siding/thinplating_new/dark, /turf/open/floor/mineral/titanium, /area/centcom/syndicate_mothership/control) +"we" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 5 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/centcom/syndicate_mothership/control) "wg" = ( /obj/structure/fence/corner{ dir = 6 @@ -2096,6 +2112,10 @@ dir = 8 }, /area/centcom/syndicate_mothership/control) +"wS" = ( +/obj/effect/landmark/nukeop_elevator/exterior, +/turf/closed/indestructible/syndicate, +/area/centcom/syndicate_mothership/control) "wW" = ( /obj/structure/flora/rock/pile/style_random, /obj/effect/light_emitter{ @@ -2390,12 +2410,11 @@ /obj/effect/turf_decal/siding/thinplating_new/dark{ dir = 1 }, -/obj/machinery/door/poddoor/shutters/window{ - id = "FBBZ1"; - name = "Security Shutters" - }, /obj/structure/fans/tiny, /obj/effect/turf_decal/tile/bar/opposingcorners, +/obj/machinery/door/poddoor/shutters/syndicate{ + dir = 1 + }, /turf/open/floor/iron, /area/centcom/syndicate_mothership/control) "AO" = ( @@ -2424,7 +2443,7 @@ icon_state = "map-left-MS"; pixel_y = 32 }, -/obj/effect/landmark/start/nukeop, +/obj/effect/landmark/start/nukeop_base, /turf/open/floor/wood/tile, /area/centcom/syndicate_mothership/control) "AW" = ( @@ -2740,9 +2759,6 @@ /obj/structure/flora/rock/icy/style_random, /turf/open/misc/asteroid/snow/icemoon, /area/centcom/syndicate_mothership/control) -"Ev" = ( -/turf/open/floor/plating/elevatorshaft, -/area/centcom/syndicate_mothership/control) "Ez" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/general/hidden, /obj/machinery/atmospherics/pipe/smart/manifold4w/yellow/hidden/layer2, @@ -3225,6 +3241,12 @@ }, /turf/open/floor/iron/dark/textured_large, /area/centcom/syndicate_mothership/control) +"Ja" = ( +/obj/machinery/light/small/red/directional/north{ + allow_break_on_init = 0 + }, +/turf/open/floor/mineral/plastitanium, +/area/centcom/syndicate_mothership/control) "Jc" = ( /obj/structure/table/wood, /obj/machinery/chem_dispenser/drinks/beer{ @@ -3615,7 +3637,7 @@ dir = 8 }, /obj/structure/chair/stool/directional/east, -/obj/effect/landmark/start/nukeop, +/obj/effect/landmark/start/nukeop_base, /turf/open/floor/wood/tile, /area/centcom/syndicate_mothership/control) "Nb" = ( @@ -3672,10 +3694,10 @@ /obj/effect/turf_decal/siding/wideplating/dark{ dir = 4 }, -/obj/machinery/door/airlock/highsecurity{ +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/obj/machinery/door/airlock/highsecurity/syndicate{ name = "Sky Bridge" }, -/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, /turf/open/floor/iron/textured_large, /area/centcom/syndicate_mothership/control) "Oc" = ( @@ -3813,11 +3835,11 @@ /obj/effect/turf_decal/siding/wideplating/dark{ dir = 4 }, -/obj/machinery/door/airlock/highsecurity{ - name = "Sky Bridge" - }, /obj/structure/cable, /obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/obj/machinery/door/airlock/highsecurity/syndicate{ + name = "Sky Bridge" + }, /turf/open/floor/iron/textured_large, /area/centcom/syndicate_mothership/control) "OX" = ( @@ -3886,15 +3908,6 @@ /obj/structure/flora/grass/both/style_random, /turf/open/misc/asteroid/snow/airless, /area/centcom/syndicate_mothership) -"Qe" = ( -/obj/machinery/button/door/directional/south{ - desc = "Looks like the elevator is under maintenance.."; - name = "Elevator Button" - }, -/turf/open/floor/iron/smooth_half{ - dir = 1 - }, -/area/centcom/syndicate_mothership/control) "Qh" = ( /obj/structure/window/reinforced/survival_pod/spawner/directional/south{ name = "Frosted Window" @@ -4339,6 +4352,12 @@ }, /turf/open/floor/wood/tile, /area/centcom/syndicate_mothership/control) +"TH" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 10 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/centcom/syndicate_mothership/control) "TK" = ( /obj/structure/barricade/sandbags, /obj/effect/light_emitter{ @@ -4354,11 +4373,11 @@ /obj/effect/turf_decal/siding/wideplating/dark{ dir = 4 }, -/obj/machinery/door/airlock/highsecurity{ - name = "Sky Bridge" - }, /obj/structure/cable, /obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/obj/machinery/door/airlock/highsecurity/syndicate{ + name = "Sky Bridge" + }, /turf/open/floor/iron/textured_large, /area/centcom/syndicate_mothership/control) "TS" = ( @@ -4646,7 +4665,7 @@ /area/centcom/syndicate_mothership) "Xu" = ( /obj/structure/chair/stool/directional/west, -/obj/effect/landmark/start/nukeop, +/obj/effect/landmark/start/nukeop_base, /turf/open/floor/wood/tile, /area/centcom/syndicate_mothership/control) "Xv" = ( @@ -4729,6 +4748,12 @@ dir = 1 }, /area/centcom/syndicate_mothership/control) +"XZ" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 9 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/centcom/syndicate_mothership/control) "Yd" = ( /obj/machinery/camera/autoname/directional/south{ network = list("nukie") @@ -6730,7 +6755,7 @@ sk DW RD EM -RD +EM RD Ox sU @@ -9572,10 +9597,10 @@ ZZ Me wc wG -Qe +wG DZ -Ev -Ev +Ja +Ov DZ DZ nS @@ -9676,9 +9701,9 @@ zH wG wG ru -Ev -Ev -Ev +XZ +TH +Ov DZ Ox Vm @@ -9778,9 +9803,9 @@ zH wG wG ru -Ev -Ev -Ev +we +rw +Ov DZ Ox To @@ -9880,8 +9905,8 @@ wc wG lE DZ -Ev -Ev +Ja +Ov DZ DZ Ox @@ -9981,7 +10006,7 @@ go as wG wG -DZ +wS DZ DZ DZ diff --git a/_maps/templates/lazy_templates/nukie_elevator.dmm b/_maps/templates/lazy_templates/nukie_elevator.dmm new file mode 100644 index 00000000000..6993eedc19c --- /dev/null +++ b/_maps/templates/lazy_templates/nukie_elevator.dmm @@ -0,0 +1,100 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/closed/indestructible/syndicate, +/area/centcom/syndicate_mothership/control) +"j" = ( +/obj/effect/landmark/start/nukeop_elevator, +/obj/machinery/light/small/red/directional/north{ + allow_break_on_init = 0 + }, +/turf/open/floor/mineral/plastitanium, +/area/centcom/syndicate_mothership/control) +"l" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 6 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/centcom/syndicate_mothership/control) +"s" = ( +/turf/open/floor/plating, +/area/centcom/syndicate_mothership/control) +"u" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 5 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/centcom/syndicate_mothership/control) +"w" = ( +/obj/effect/landmark/start/nukeop_elevator, +/turf/open/floor/mineral/plastitanium, +/area/centcom/syndicate_mothership/control) +"F" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 10 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/centcom/syndicate_mothership/control) +"I" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 9 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/centcom/syndicate_mothership/control) +"T" = ( +/obj/effect/landmark/nukeop_elevator/interior, +/turf/closed/indestructible/syndicate, +/area/centcom/syndicate_mothership/control) +"W" = ( +/obj/effect/turf_decal/siding/wideplating{ + dir = 1 + }, +/obj/effect/turf_decal/siding/wideplating, +/obj/machinery/door/poddoor/shutters/syndicate/indestructible{ + name = "Base Lift"; + dir = 1 + }, +/turf/open/floor/iron/dark/textured_half, +/area/centcom/syndicate_mothership/control) + +(1,1,1) = {" +a +a +a +a +s +"} +(2,1,1) = {" +a +j +w +a +a +"} +(3,1,1) = {" +W +I +F +w +a +"} +(4,1,1) = {" +W +u +l +w +a +"} +(5,1,1) = {" +a +j +w +a +a +"} +(6,1,1) = {" +T +a +a +a +s +"} diff --git a/_maps/virtual_domains/fredingtonfastingbear.dmm b/_maps/virtual_domains/fredingtonfastingbear.dmm index 24174de946b..c792d2443fa 100644 --- a/_maps/virtual_domains/fredingtonfastingbear.dmm +++ b/_maps/virtual_domains/fredingtonfastingbear.dmm @@ -250,7 +250,7 @@ /obj/structure/closet/gmcloset, /obj/effect/turf_decal/tile/blue/opposingcorners, /obj/effect/turf_decal/tile/blue/opposingcorners, -/obj/item/clothing/mask/animal/small/bear/cursed, +/obj/item/clothing/mask/animal/small/bear, /turf/open/floor/iron/kitchen, /area/virtual_domain) "nX" = ( diff --git a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm index 718fbcd49f5..2df4cfe03d0 100644 --- a/code/__DEFINES/DNA.dm +++ b/code/__DEFINES/DNA.dm @@ -21,8 +21,6 @@ #define MUTATION_SOURCE_ACTIVATED "activated" ///Source for mutations that have been added via mutators #define MUTATION_SOURCE_MUTATOR "mutator" -///From timed dna injectors. -#define MUTATION_SOURCE_TIMED_INJECTOR "timed_injector" ///From mob/living/carbon/human/proc/crewlike_monkify() #define MUTATION_SOURCE_CREW_MONKEY "crew_monkey" #define MUTATION_SOURCE_MEDIEVAL_CTF "medieval_ctf" @@ -31,7 +29,6 @@ #define MUTATION_SOURCE_SPELL "spell" ///From the heart eater component #define MUTATION_SOURCE_HEART_EATER "heart_eater" -#define MUTATION_SOURCE_RAT_HEART "rat_heart" #define MUTATION_SOURCE_CLOWN_CLUMSINESS "clown_clumsiness" #define MUTATION_SOURCE_CHANGELING "changeling" #define MUTATION_SOURCE_GHOST_ROLE "ghost_role" @@ -79,14 +76,14 @@ #define FEATURE_TAILSPINES "tailspines" // Different from regular spines, these appear on tails #define FEATURE_LEGS "legs" -///flag for the transfer_flag argument from dna/proc/copy_dna(). This one makes it so the SE is copied too. +// flag for the transfer_flag argument from dna/proc/copy_dna(). +/// Copies SE (mob's innate mutations) #define COPY_DNA_SE (1<<0) -///flag for the transfer_flag argument from dna/proc/copy_dna(). This one copies the species. +/// Copies the species. #define COPY_DNA_SPECIES (1<<1) -///flag for the transfer_flag argument from dna/proc/copy_dna(). This one copies the mutations. +/// Copies active mutations and anything mutated from other means #define COPY_DNA_MUTATIONS (1<<2) - //organ slots #define ORGAN_SLOT_ADAMANTINE_RESONATOR "adamantine_resonator" #define ORGAN_SLOT_APPENDIX "appendix" diff --git a/code/__DEFINES/_flags.dm b/code/__DEFINES/_flags.dm index 92f24181fbb..9bea96417fe 100644 --- a/code/__DEFINES/_flags.dm +++ b/code/__DEFINES/_flags.dm @@ -13,6 +13,8 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204 #define DF_ISPROCESSING (1<<2) /// Placed on datums that have a static, constant reference. Primarily only used for turfs. #define DF_STATIC_OBJECT (1<<3) +/// Set on datums that should be tracked by the event logger. +#define DF_EVLOGGING (1<<4) //FLAGS BITMASK // scroll down before changing the numbers on these @@ -239,6 +241,7 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204 #define ZAP_DEFAULT_FLAGS ZAP_MOB_STUN | ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE #define ZAP_FUSION_FLAGS ZAP_OBJ_DAMAGE | ZAP_MOB_DAMAGE | ZAP_MOB_STUN #define ZAP_SUPERMATTER_FLAGS ZAP_GENERATES_POWER +#define ZAP_GIZMO_FLAGS ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE ///Object will protect itself. #define EMP_PROTECT_SELF (1<<0) diff --git a/code/__DEFINES/access.dm b/code/__DEFINES/access.dm index b6c00d6cfa0..6df974d87a2 100644 --- a/code/__DEFINES/access.dm +++ b/code/__DEFINES/access.dm @@ -199,6 +199,8 @@ #define ACCESS_BLOODCULT "bloodcult" /// HUNTERS #define ACCESS_HUNTER "hunter" +/// HERETIC +#define ACCESS_HERETIC "heretic" /// - - - MISC - - - // These don't really fit anywhere else diff --git a/code/__DEFINES/ai/ai.dm b/code/__DEFINES/ai/ai.dm index aafd3feb203..f8285b075e4 100644 --- a/code/__DEFINES/ai/ai.dm +++ b/code/__DEFINES/ai/ai.dm @@ -1,5 +1,6 @@ #define GET_AI_BEHAVIOR(behavior_type) SSai_behaviors.ai_behaviors[behavior_type] #define GET_TARGETING_STRATEGY(targeting_type) SSai_behaviors.targeting_strategies[targeting_type] +#define GET_TARGET_PRIORITY_STRATEGY(targeting_type) SSai_behaviors.target_priority_strategies[targeting_type] #define HAS_AI_CONTROLLER_TYPE(thing, type) istype(thing?.ai_controller, type) //AI controller flags diff --git a/code/__DEFINES/ai/ai_blackboard.dm b/code/__DEFINES/ai/ai_blackboard.dm index 3e9a65027af..660a4e3c82c 100644 --- a/code/__DEFINES/ai/ai_blackboard.dm +++ b/code/__DEFINES/ai/ai_blackboard.dm @@ -83,6 +83,7 @@ #define BB_BASIC_MOB_CURRENT_TARGET "BB_basic_current_target" #define BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION "BB_basic_current_target_hiding_location" #define BB_TARGETING_STRATEGY "targeting_strategy" +#define BB_TARGET_PRIORITY_STRATEGY "target_priority_strategy" #define BB_HUNT_TARGETING_STRATEGY "hunt_targeting_strategy" ///some behaviors that check current_target also set this on deep crit mobs #define BB_BASIC_MOB_EXECUTION_TARGET "BB_basic_execution_target" @@ -96,6 +97,7 @@ #define BB_TARGET_HELD_ITEM "BB_target_held_item" /// How likely is this mob to move when idle per tick? #define BB_BASIC_MOB_IDLE_WALK_CHANCE "BB_basic_idle_walk_chance" +#define BB_BASIC_MOB_TARGET_REFRESH_COOLDOWN "BB_basic_mob_target_refresh_cooldown" /// Minimum range to keep target within #define BB_RANGED_SKIRMISH_MIN_DISTANCE "BB_ranged_skirmish_min_distance" @@ -140,7 +142,7 @@ /// How often can we get spooked by a target? #define BB_STATIONARY_COOLDOWN "BB_stationary_cooldown" -///List of mobs who have damaged us +/// Assoc list of mobs who have damaged us -> Moment at which they damaged us #define BB_BASIC_MOB_RETALIATE_LIST "BB_basic_mob_shitlist" /// Chance to randomly acquire a new target @@ -197,6 +199,8 @@ #define BB_BASIC_MOB_REINFORCEMENT_TARGET "BB_basic_mob_reinforcement_target" /// The next time at which this mob can call for reinforcements #define BB_BASIC_MOB_REINFORCEMENTS_COOLDOWN "BB_basic_mob_reinforcements_cooldown" +/// Soft-reinforcements requests which will cause the mob to prioritize the attacker +#define BB_MINING_MOB_REINFORCEMENTS_REQUESTS "BB_mining_mob_reinforcements_requests" /// the direction we started when executing stare at things #define BB_STARTING_DIRECTION "BB_startdir" diff --git a/code/__DEFINES/ai/bot_keys.dm b/code/__DEFINES/ai/bot_keys.dm index c12f48273ee..0c7758f6134 100644 --- a/code/__DEFINES/ai/bot_keys.dm +++ b/code/__DEFINES/ai/bot_keys.dm @@ -1,40 +1,3 @@ -//bitfield defines - -///can honkbots slip people? -#define HONKBOT_MODE_SLIP (1<<0) -///can honkbots check IDs? -#define HONKBOT_CHECK_IDS (1<<1) -///can honkbots check records? -#define HONKBOT_CHECK_RECORDS (1<<2) -///can honkbots handcuff people? -#define HONKBOT_HANDCUFF_TARGET (1<<3) - -DEFINE_BITFIELD(honkbot_flags, list( - "CAN_SLIP" = HONKBOT_MODE_SLIP, - "CHECK_IDS" = HONKBOT_CHECK_IDS, - "CHECK_RECORDS" = HONKBOT_CHECK_RECORDS, - "CAN_FAKE_CUFF" = HONKBOT_HANDCUFF_TARGET, -)) - -///can we fix breaches -#define REPAIRBOT_FIX_BREACHES (1<<0) -///can we fix grilles -#define REPAIRBOT_REPLACE_WINDOWS (1<<1) -///can we replace tiles -#define REPAIRBOT_REPLACE_TILES (1<<2) -///can we fix girders -#define REPAIRBOT_FIX_GIRDERS (1<<3) -///can we build girders -#define REPAIRBOT_BUILD_GIRDERS (1<<4) - -DEFINE_BITFIELD(repairbot_flags, list( - "FIX_BREACHES" = REPAIRBOT_FIX_BREACHES, - "REPLACE_WINDOWS" = REPAIRBOT_REPLACE_WINDOWS, - "REPLACE_TILES" = REPAIRBOT_REPLACE_TILES, - "FIX_GIRDERS" = REPAIRBOT_FIX_GIRDERS, - "BUILD_GIRDERS" = REPAIRBOT_BUILD_GIRDERS, -)) - // bot keys ///The first beacon we find #define BB_BEACON_TARGET "beacon_target" @@ -113,6 +76,10 @@ DEFINE_BITFIELD(repairbot_flags, list( ///key that holds cooldown after we finish cleaning something, so we dont immediately run off to patrol #define BB_POST_CLEAN_COOLDOWN "post_clean_cooldown" +//secbots +///threat of our current target +#define BB_CURRENT_CRIMINAL_ASSESSMENT "current_criminal_assessment" + //Honkbots ///key that holds all possible clown friends #define BB_CLOWNS_LIST "clowns_list" diff --git a/code/__DEFINES/ai/monsters.dm b/code/__DEFINES/ai/monsters.dm index 9a10d411fdc..8a4e9d56aa5 100644 --- a/code/__DEFINES/ai/monsters.dm +++ b/code/__DEFINES/ai/monsters.dm @@ -3,6 +3,8 @@ #define BB_BILEWORM_SPEW_BILE "BB_bileworm_spew_bile" #define BB_BILEWORM_RESURFACE "BB_bileworm_resurface" #define BB_BILEWORM_DEVOUR "BB_bileworm_devour" +#define BB_BILEWORM_SCARED "BB_bileworm_scared" +#define BB_BILEWORM_FLEE_DISTANCE "BB_bileworm_flee_distance" // Meteor Heart AI keys /// Key where we keep the spike trail ability @@ -50,6 +52,11 @@ /// Key where goliath stores a hole it wants to get into #define BB_GOLIATH_HOLE_TARGET "BB_goliath_hole" +// Tendril AI keys +#define BB_TENDRIL_LASH "tendril_lash" +#define BB_TENDRIL_CHASER "tendril_chaser" +#define BB_TENDRIL_SPIKES "tendril_spikes" + // bee keys ///the bee hive we live inside #define BB_CURRENT_HOME "BB_current_home" diff --git a/code/__DEFINES/atom_hud.dm b/code/__DEFINES/atom_hud.dm index 5468e85ddee..d3e4d7e594d 100644 --- a/code/__DEFINES/atom_hud.dm +++ b/code/__DEFINES/atom_hud.dm @@ -48,8 +48,6 @@ #define MALF_APC_HUD "22" /// Blood volume bar, visible to blood worms #define BLOOD_HUD "23" -/// Big Manipulator interaction point HUDs -#define BIG_MANIP_HUD "24" // SKYRAT EDIT ADDITION BEGIN - gun permits and DNR /// ammo of guns diff --git a/code/__DEFINES/basic_mobs.dm b/code/__DEFINES/basic_mobs.dm index 32360a21260..1a97163a871 100644 --- a/code/__DEFINES/basic_mobs.dm +++ b/code/__DEFINES/basic_mobs.dm @@ -119,3 +119,11 @@ GLOBAL_LIST_EMPTY(customized_pets) #define BB_RAPTOR_FLEE_THRESHOLD "raptor_flee_threshold" #define MAX_RAPTOR_POP 64 + + +///Return value for [/mob/living/basic/proc/early_melee_attack]. Using this value will make the attack continue as normal. +#define BASIC_MOB_CONTINUE_ATTACK_CHAIN 0 +///Return value for [/mob/living/basic/proc/early_melee_attack]. Using this value will make the attack end, but not set a cooldown. This is the default. +#define BASIC_MOB_END_ATTACK_CHAIN 1 +///Return value for [/mob/living/basic/proc/early_melee_attack]. Using this value will make the attack end, and sets a cooldown. Useful if you add behavior to early_melee_attack +#define BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN 2 diff --git a/code/__DEFINES/botany.dm b/code/__DEFINES/botany.dm index 8afca99300b..2a9fc2021c9 100644 --- a/code/__DEFINES/botany.dm +++ b/code/__DEFINES/botany.dm @@ -56,6 +56,8 @@ /// -- Flags for seeds. -- /// Allows a plant to wild mutate (mutate on haravest) at a certain instability. #define MUTATE_EARLY (1<<0) +/// Prevents seeds from being planted in hydroponics or soil +#define NO_PLANTING (1<<1) /// -- Flags for traits. -- /// Caps the plant's yield at 5 instead of 10. diff --git a/code/__DEFINES/cameranets.dm b/code/__DEFINES/cameranets.dm index 20add763b12..1201705d627 100644 --- a/code/__DEFINES/cameranets.dm +++ b/code/__DEFINES/cameranets.dm @@ -44,3 +44,4 @@ #define CAMERANET_NETWORK_UGO45_RESEARCH "uo45r" #define CAMERANET_NETWORK_FSCI "fsci" #define CAMERA_NETWORK_BUNKER "bunker1" +#define CAMERA_NETWORK_HERETIC_GATEWAY "heretic_gate" diff --git a/code/__DEFINES/colors.dm b/code/__DEFINES/colors.dm index 280d302f7d7..710a08b4a1b 100644 --- a/code/__DEFINES/colors.dm +++ b/code/__DEFINES/colors.dm @@ -377,6 +377,7 @@ #define COLOR_CARP_PURPLE "#aba2ff" +#define COLOR_CARP_DARK_PURPLE "#4c486e" #define COLOR_CARP_PINK "#da77a8" #define COLOR_CARP_GREEN "#70ff25" #define COLOR_CARP_GRAPE "#df0afb" diff --git a/code/__DEFINES/construction/material.dm b/code/__DEFINES/construction/material.dm index 7e5c6d6263a..59a7b1b74ec 100644 --- a/code/__DEFINES/construction/material.dm +++ b/code/__DEFINES/construction/material.dm @@ -141,6 +141,9 @@ GLOBAL_LIST_INIT(material_flags_to_string, alist( /// Prevents material items from displaying their descriptors in examine_more with sci glasses #define MATERIAL_NO_DESCRIPTORS (1 << 8) +/// Flags for metalgen imprinting +#define MATERIAL_METALGEN MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS + //Special return values of [/datum/material_container/insert_item] /// No material was found inside them item #define MATERIAL_INSERT_ITEM_NO_MATS -1 diff --git a/code/__DEFINES/dcs/signals/signals_action.dm b/code/__DEFINES/dcs/signals/signals_action.dm index 8933490dc66..66a4ffc894b 100644 --- a/code/__DEFINES/dcs/signals/signals_action.dm +++ b/code/__DEFINES/dcs/signals/signals_action.dm @@ -57,3 +57,8 @@ /// From /datum/action/cooldown/spell/touch/lay_on_hands/proc/determine_if_this_hurts_instead(), sent to the /mob/living/carbon/hurtguy: (/mob/living/carbon/mendicant) #define COMSIG_ON_LAY_ON_HANDS "mob_ability_lay_on_hands" + +/// From /datum/action/innate/dash/proc/teleport when teleport is successful +#define COMSIG_DASH_ACTION_DASHED "dash_action_dashed" +/// From /datum/action/innate/dash/proc/charge when charges are replenished +#define COMSIG_DASH_ACTION_CHARGED "dash_action_charged" diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_attack.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_attack.dm index 16c3fb9eb12..ee93fa28b39 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_attack.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_attack.dm @@ -55,7 +55,7 @@ #define COMSIG_ATOM_ATTACK_AI "atom_attack_ai" /// from base of atom/attack_larva(): (mob/user, list/modifiers) #define COMSIG_ATOM_ATTACK_LARVA "atom_attack_larva" -///from relay_attackers element: (atom/attacker, attack_flags) +///from relay_attackers element: (atom/attacker, attack_flags, direction) #define COMSIG_ATOM_WAS_ATTACKED "atom_was_attacked" ///Called before a atom gets something tilted on them. If [COMPONENT_IMMUNE_TO_TILT_AND_CRUSH] is returned in a signal, the atom will be unaffected: (atom/target, atom/source) #define COMSIG_PRE_TILT_AND_CRUSH "atom_pre_tilt_and_crush" @@ -64,13 +64,14 @@ #define COMSIG_POST_TILT_AND_CRUSH "atom_post_tilt_and_crush" /// Called when an atom is splashed with something: (atom/source) #define COMSIG_ATOM_SPLASHED "atom_splashed" - ///The damage type of the weapon projectile is non-lethal stamina #define ATTACKER_STAMINA_ATTACK (1<<0) ///the attacker is shoving the source #define ATTACKER_SHOVING (1<<1) /// The attack is a damaging-type attack #define ATTACKER_DAMAGING_ATTACK (1<<2) + /// The attack was ranged + #define ATTACK_RANGED (1<<3) /// Called on the atom being hit, from /datum/component/anti_magic/on_attack() : (obj/item/weapon, mob/user, antimagic_flags) #define COMSIG_ATOM_HOLYATTACK "atom_holyattacked" diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm index b6cc94584be..6e70a9b36b9 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm @@ -151,6 +151,10 @@ #define COMSIG_ATOM_FINALIZE_MATERIAL_EFFECTS "atom_finalize_material_effects" /// From /atom/finalize_remove_material_effects(): (list/materials, datum/material/main_material) #define COMSIG_ATOM_FINALIZE_REMOVE_MATERIAL_EFFECTS "atom_finalize_remove_material_effects" +/// /atom/proc/apply_single_mat_effect(): (datum/material/material, amount, multiplier) +#define COMSIG_ATOM_SINGLE_MATERIAL_EFFECT_APPLY "atom_single_material_effect_apply" +/// /atom/proc/remove_single_mat_effect(): (datum/material/material, amount, multiplier) +#define COMSIG_ATOM_SINGLE_MATERIAL_EFFECT_REMOVE "atom_single_material_effect_remove" /// From /atom/proc/update_atom_colour() : (color_changed) #define COMSIG_ATOM_COLOR_UPDATED "atom_color_updated" diff --git a/code/__DEFINES/dcs/signals/signals_bitrunning.dm b/code/__DEFINES/dcs/signals/signals_bitrunning.dm index ccf47c22604..5e49840d344 100644 --- a/code/__DEFINES/dcs/signals/signals_bitrunning.dm +++ b/code/__DEFINES/dcs/signals/signals_bitrunning.dm @@ -1,9 +1,6 @@ /// from /atom/movable/screen/alert/bitrunning/qserver_domain_complete #define COMSIG_BITRUNNER_ALERT_SEVER "bitrunner_alert_sever" -/// from /obj/effect/bitrunning/loot_signal: (points) -#define COMSIG_BITRUNNER_GOAL_POINT "bitrunner_goal_point" - // Netpods /// from /obj/machinery/netpod/sever_connection() diff --git a/code/__DEFINES/dcs/signals/signals_datum.dm b/code/__DEFINES/dcs/signals/signals_datum.dm index 3668d202a7f..e381979907d 100644 --- a/code/__DEFINES/dcs/signals/signals_datum.dm +++ b/code/__DEFINES/dcs/signals/signals_datum.dm @@ -26,6 +26,14 @@ /// from datum/tgui/get_payload(user, list/data) #define COMSIG_UI_DATA "ui_data" +/// fired on a datum when event-logger tracking is enabled on it [/datum/proc/enable_evlogging]: () +#define COMSIG_EVLOGGING_ENABLED "evlogging_enabled" +/// fired on a datum when event-logger tracking is disabled on it [/datum/proc/disable_evlogging]: () +#define COMSIG_EVLOGGING_DISABLED "evlogging_disabled" + +/// fired on the source datum whenever an event is added for it in the event logger: (/datum/event_logger_track/track, list/event_data) +#define COMSIG_EVLOG_EVENT_ADDED "evlog_event_added" + /// fires on the target datum when an element is attached to it (/datum/element) #define COMSIG_ELEMENT_ATTACH "element_attach" /// fires on the target datum when an element is detached from it (/datum/element) diff --git a/code/__DEFINES/dcs/signals/signals_food.dm b/code/__DEFINES/dcs/signals/signals_food.dm index 9dca9d304d0..ba3b9415080 100644 --- a/code/__DEFINES/dcs/signals/signals_food.dm +++ b/code/__DEFINES/dcs/signals/signals_food.dm @@ -20,6 +20,8 @@ #define COMSIG_ITEM_USED_AS_INGREDIENT "item_used_as_ingredient" /// called when an edible ingredient is added: (datum/component/edible/ingredient) #define COMSIG_FOOD_INGREDIENT_ADDED "edible_ingredient_added" +/// called when a pizza slice is picked up: (mob/user, obj/item/food/pizzaslice/slice) +#define COMSIG_PIZZA_SLICE_TAKEN "pizza_slice_taken" /// from base of /datum/component/edible/get_recipe_complexity(): (list/extra_complexity) #define COMSIG_FOOD_GET_EXTRA_COMPLEXITY "food_get_extra_complexity" diff --git a/code/__DEFINES/dcs/signals/signals_mining.dm b/code/__DEFINES/dcs/signals/signals_mining.dm index 3ef84b1f7b6..494068f3707 100644 --- a/code/__DEFINES/dcs/signals/signals_mining.dm +++ b/code/__DEFINES/dcs/signals/signals_mining.dm @@ -3,6 +3,10 @@ /// Fired by a mob which has been grabbed by a goliath #define COMSIG_GOLIATH_TENTACLED_GRABBED "comsig_goliath_tentacle_grabbed" + #define COMPONENT_GOLIATH_CANCEL_TENTACLE_GRAB (1<<0) +/// Fired by a mob which has been grabbed by a tendril +#define COMSIG_TENDRIL_TENTACLED_GRABBED "comsig_tendril_tentacle_grabbed" + #define COMPONENT_TENDRIL_CANCEL_TENTACLE_GRAB (1<<0) /// Fired by a goliath tentacle which is returning to the earth #define COMSIG_GOLIATH_TENTACLE_RETRACTING "comsig_goliath_tentacle_retracting" /// Fired by a mob which has triggered a brimdust explosion from itself (not the mobs that get hit) diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_basic.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_basic.dm index 83084005dd5..b1f2431ccbb 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_basic.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_basic.dm @@ -33,3 +33,5 @@ #define COMSIG_RAPTOR_GROWTH_STAGE_CHANGE "raptor_growth_stage_change" /// Cancel raptor growth #define COMPONENT_CANCEL_RAPTOR_GROWTH (1<<0) +// Called when the revenant is to be released from its prison : (cause) +#define COMSIG_REVENANT_RELEASE "revenant_release" 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 b23710935a7..a8af2cc5c66 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm @@ -60,10 +60,15 @@ /// Called from bodypart being removed /obj/item/bodypart/proc/drop_limb(mob/living/carbon/old_owner, special, dismembered) #define COMSIG_BODYPART_REMOVED "bodypart_removed" +/// From /obj/item/bodypart/proc/update_limb(): (dropping_limb, is_creating) +#define COMSIG_BODYPART_UPDATED "bodypart_updated" +/// From /datum/component/butchering/create_replacement_limb(): (replacement limb) +#define COMSIG_BODYPART_BUTCHERED "bodypart_butchered" + /// Sent to a limb when something *attempts* to change its surgery state (old_state, new_state, changed_states) #define COMSIG_BODYPART_UPDATING_SURGERY_STATE "bodypart_updating_surgery_state" -/// Called from /obj/item/bodypart/proc/get_limb_icon(dropped, mob/living/carbon/update_on) : (list/limb_icons, dropped, mob/living/carbon/update_on) +/// Called from /obj/item/bodypart/proc/get_limb_icon(dropped) : (list/limb_icons, dropped, mob/living/carbon/update_on) #define COMSIG_BODYPART_GET_LIMB_ICON "bodypart_get_limb_icon" /// Called from /obj/item/bodypart/proc/generate_icon_key() : (list/icon_keys) @@ -205,3 +210,12 @@ #define COMSIG_HUMAN_NON_STORAGE_HOTKEY "human_storage_hotkey" /// Return to prevent the storage fail message #define COMPONENT_STORAGE_HOTKEY_HANDLED (1<<0) + +/// Before a mob starts dreaming - you can add dream datums to the dream pool to override the selection: (list/dream_pool) +#define COMSIG_PRE_DREAMING "pre_dreaming" +/// A mob has started dreaming: (datum/dream/current_dream) +#define COMSIG_START_DREAMING "start_dreaming" +/// A mob has finished dreaming: (datum/dream/finished_dream) +#define COMSIG_END_DREAMING "end_dreaming" +/// From /mob/living/carbon/item_coverage_changed: (added_slots, removed_slots) +#define COMSIG_CARBON_ITEM_COVERAGE_CHANGED "carbon_item_coverage_changed" 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 4c7df9de234..b44d42ceede 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm @@ -61,22 +61,17 @@ ///from base of mob/living/set_usable_legs() #define COMSIG_LIVING_LIMBLESS_SLOWDOWN "living_limbless_slowdown" ///From living/Life(). (deltatime) -#define COMSIG_LIVING_LIFE "living_life" +#define COMSIG_LIVING_PRE_LIFE "living_pre_life" /// Block the Life() proc from proceeding... this should really only be done in some really wacky situations. #define COMPONENT_LIVING_CANCEL_LIFE_PROCESSING (1<<0) +///From living/Life(). (deltatime) +#define COMSIG_LIVING_LIFE "living_life" ///From living/set_resting(): (new_resting, silent, instant) #define COMSIG_LIVING_RESTING "living_resting" ///from base of element/bane/activate(): (item/weapon, mob/user) #define COMSIG_LIVING_BANED "living_baned" -///from base of element/bane/activate(): (item/weapon, mob/user) -#define COMSIG_OBJECT_PRE_BANING "obj_pre_baning" - #define COMPONENT_CANCEL_BANING (1<<0) - -///from base of element/bane/activate(): (item/weapon, mob/user) -#define COMSIG_OBJECT_ON_BANING "obj_on_baning" - // adjust_x_loss messages sent from /mob/living/proc/adjust[x]Loss /// Returned from all the following messages if you actually aren't going to apply any change #define COMPONENT_IGNORE_CHANGE (1<<0) @@ -390,3 +385,6 @@ /// From /mob/living/on_looking_z_level_change() : (turf/old_turf, turf/new_turf) #define COMSIG_LIVING_LOOK_Z_CHANGE "living_look_z_change" + +/// From /mob/living/proc/refresh_gravity() : (new_gravity, old_gravity) +#define COMSIG_LIVING_GRAVITY_CHANGED "living_gravity_changed" diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm index b3b6acefd23..cf26bbbad24 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm @@ -105,6 +105,7 @@ #define COMSIG_MOB_SIGHT_CHANGE "mob_sight_changed" ///from base of mob/set_invis_see(): (new_invis, old_invis) #define COMSIG_MOB_SEE_INVIS_CHANGE "mob_see_invis_change" + #define COMPONENT_BLOCK_INVIS_CHANGE (1<<0) /// from /mob/living/proc/apply_damage(): (list/damage_mods, damage, damagetype, def_zone, sharpness, attack_direction, attacking_item) /// allows you to add multiplicative damage modifiers to the damage mods argument to adjust incoming damage diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_silicon.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_silicon.dm index f68b0840205..86381d4ec22 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_silicon.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_silicon.dm @@ -15,3 +15,5 @@ #define COMSIG_SILICON_AI_VACATE_APC "AI_vacate_apc" ///called when an AI's control is toggled #define COMSIG_SILICON_AI_SET_CONTROL_DISABLED "AI_set_control_disabled" +///called when borg module is activated/deactivated +#define COMSIG_SILICON_MODULE_ACTIVATION "borg_module_select" diff --git a/code/__DEFINES/dcs/signals/signals_object.dm b/code/__DEFINES/dcs/signals/signals_object.dm index dd75bf32ba1..b3dbc04a26e 100644 --- a/code/__DEFINES/dcs/signals/signals_object.dm +++ b/code/__DEFINES/dcs/signals/signals_object.dm @@ -90,6 +90,12 @@ /// from /obj/machinery/atmospherics/set_on(active): (on) #define COMSIG_ATMOS_MACHINE_SET_ON "atmos_machine_set_on" +/// from /obj/machinery/power/emitter/interact(mob/user): (on) +#define COMSIG_EMITTER_MACHINE_SET_ON "emitter_machine_set_on" + +/// from /obj/machinery/power/emitter/fire_beam(mob/user): (fired) +#define COMSIG_EMITTER_MACHINE_ON_FIRE "emitter_machine_fire" + /// from /obj/machinery/light_switch/set_lights(), sent to every switch in the area: (status) #define COMSIG_LIGHT_SWITCH_SET "light_switch_set" @@ -151,6 +157,10 @@ #define COMSIG_ITEM_STORED "item_stored" ///from base of datum/storage/handle_exit(): (datum/storage/storage) #define COMSIG_ITEM_UNSTORED "item_unstored" +/// From datum/storage/attempt_insert() +#define COMSIG_ITEM_PRE_STORAGE_INSERTION "item_pre_storage_insertion" + // return BLOCK_STORAGE_INSERT + ///from base of obj/item/do_pickup_animation(): () #define COMSIG_ITEM_BEFORE_PICKUP_ANIMATION "item_before_pickup_animation" ///from base of obj/item/do_drop_animation(): () @@ -195,9 +205,11 @@ #define COMPONENT_BLOCK_SHARPEN_BLOCKED (1<<1) #define COMPONENT_BLOCK_SHARPEN_ALREADY (1<<2) #define COMPONENT_BLOCK_SHARPEN_MAXED (1<<3) + #define COMPONENT_BLOCK_SHARPEN_SHARPNESS (1<<4) ///Called when an armor plate is successfully applied to an object #define COMSIG_ARMOR_PLATED "armor_plated" + ///Called when an item gets recharged by the ammo powerup #define COMSIG_ITEM_RECHARGED "item_recharged" ///Called when an item is being offered, from [/obj/item/proc/on_offered(mob/living/offerer)] @@ -377,6 +389,8 @@ ///called in /obj/item/firing_pin/proc/gun_remove(mob/living/user): (obj/item/firing_pin/pin, mob/living/user) #define COMSIG_GUN_PIN_REMOVED "gun_pin_removed" +///called when an empty rechargeable gun gives itself more ammo +#define COMSIG_GUN_REPLENISHED_CHARGE "gun_replenished_charge" // Jetpack things // Please kill me @@ -671,3 +685,14 @@ /// Sent from /datum/component/reflection when the reflection is updated to the mob reflecting: (atom/movable/reflecting_in, obj/effect/abstract/reflection) #define COMSIG_REFLECTION_UPDATED "reflection_updated" + +/// Sent from /datum/component/reflection when the reflection is updated to the component parent: (obj/effect/abstract/reflection) +#define COMSIG_REFLECTED_IMAGE_UPDATED "reflected_image_updated" + +/// From /datum/element/weapon_description: (list/readout) +#define COMSIG_ITEM_WEAPON_LABEL_READOUT "item_weapon_label_readout" + +/// Send from /datum/element/cuffable_item(): (mob/cuffer, obj/item/cuffs) +#define COMSIG_ITEM_PRE_CUFFED_TO_MOB "item_cuffed_to_mob" + /// Return to stop the cuffing from happening. + #define BLOCK_ITEM_CUFF (1<<0) diff --git a/code/__DEFINES/diseases.dm b/code/__DEFINES/diseases.dm index c9daeef827b..deb5e4339a1 100644 --- a/code/__DEFINES/diseases.dm +++ b/code/__DEFINES/diseases.dm @@ -97,6 +97,9 @@ DEFINE_BITFIELD(spread_flags, list( /// Satiety Recovery Multiplier - added chance to recover based on positive satiety //// Multiplier of satiety/max_satiety if satiety is positive or zero. Increase to make satiety more valuable, decrease for less. #define DISEASE_SATIETY_RECOVERY_MULTIPLIER 3 +/// Disease Satiety Threshold - how much junk food we have to eat to start curing positive viruses. +//// About -150 is good. May need to change if satiety/junkiness var is changed up much. +#define DISEASE_SATIETY_THRESHOLD -150 /// Good Sleeping Recovery Bonus - additive benefits for various types of good sleep (blanket, bed, darkness, pillows.) //// Raise to make each factor add this much chance to recover. #define DISEASE_GOOD_SLEEPING_RECOVERY_BONUS 0.6 diff --git a/code/__DEFINES/do_afters.dm b/code/__DEFINES/do_afters.dm index 5c21dd8cc8a..9c9897753bd 100644 --- a/code/__DEFINES/do_afters.dm +++ b/code/__DEFINES/do_afters.dm @@ -9,3 +9,4 @@ #define DOAFTER_SOURCE_CHARGE_CRANKRECHARGE "doafter_charge_crank_recharge" #define DOAFTER_SOURCE_REMOVING_HOOK "doafter_removing_hook" #define DOAFTER_SOURCE_CHARGING_ESWORD "doafter_charging_esword" +#define DOAFTER_SOURCE_RIP_HEART "doafter_rip_heart" diff --git a/code/__DEFINES/event_logger.dm b/code/__DEFINES/event_logger.dm new file mode 100644 index 00000000000..42cd0a21271 --- /dev/null +++ b/code/__DEFINES/event_logger.dm @@ -0,0 +1,61 @@ +// Event Logger macros. The logging functions only run if the logger is active and the datum being logged has the DF_EVLOGGING flag set. This makes logging itself relatively cheap when not in use. +/// Log a plain text event. +#define EVLOG_TEXT(DATUM, CATEGORY, INFO) \ + if(GLOB.event_logger.running && (DATUM.datum_flags & DF_EVLOGGING)) \ + { GLOB.event_logger.log_event_text(DATUM, CATEGORY, INFO) } + +/// Log a location event that highlights a single tile when selected. +/// TURF is a /turf. DATUM must have DF_EVLOGGING set. +#define EVLOG_LOCATION(DATUM, CATEGORY, INFO, TURF) \ + if(GLOB.event_logger.running && (DATUM.datum_flags & DF_EVLOGGING)) \ + { GLOB.event_logger.log_event_location(DATUM, CATEGORY, INFO, TURF) } + +/// Log a turfs event that highlights a set of tiles when selected. +/// TURFS is a list of /turf. DATUM must have DF_EVLOGGING set. +#define EVLOG_TURFS(DATUM, CATEGORY, INFO, TURFS) \ + if(GLOB.event_logger.running && (DATUM.datum_flags & DF_EVLOGGING)) \ + { GLOB.event_logger.log_event_turfs(DATUM, CATEGORY, INFO, TURFS) } + +/// Log a line event that highlights a path from one tile to another when selected. +/// TURF_A and TURF_B are /turf. DATUM must have DF_EVLOGGING set. +#define EVLOG_LINES(DATUM, CATEGORY, INFO, TURF_A, TURF_B) \ + if(GLOB.event_logger.running && (DATUM.datum_flags & DF_EVLOGGING)) \ + { GLOB.event_logger.log_event_lines(DATUM, CATEGORY, INFO, TURF_A, TURF_B) } + +/// Log a path event that renders directional arrows + start/end markers when selected. +/// TURFS is an ordered list of /turf. DATUM must have DF_EVLOGGING set. +#define EVLOG_PATH(DATUM, CATEGORY, INFO, TURFS) \ + if(GLOB.event_logger.running && (DATUM.datum_flags & DF_EVLOGGING)) \ + { GLOB.event_logger.log_event_path(DATUM, CATEGORY, INFO, TURFS) } + +/// Log a maptext event that renders a floating text string at a turf when selected. +/// TURF is a /turf. TEXT is the string to display. DATUM must have DF_EVLOGGING set. +#define EVLOG_MAPTEXT(DATUM, CATEGORY, INFO, TURF, TEXT) \ + if(GLOB.event_logger.running && (DATUM.datum_flags & DF_EVLOGGING)) \ + { GLOB.event_logger.log_event_maptext(DATUM, CATEGORY, INFO, TURF, TEXT) } + + +/// Append a categorized title and entry to a track_info snapshot list. +#define EVLOG_TRACK_INFO_ENTRY(LIST, CATEGORY, KEY, VALUE) \ + LIST += list(list("category" = CATEGORY, "title" = KEY, "entry" = VALUE)) + +#define IS_EVLOGGING GLOB.event_logger.running + + +///All the types of log entries we have. + +#define EVLOG_TYPE_TEXT "text" +#define EVLOG_TYPE_LOCATION "location" +#define EVLOG_TYPE_TURFS "turfs" +#define EVLOG_TYPE_LINES "lines" +#define EVLOG_TYPE_PATH "path" +#define EVLOG_TYPE_MAPTEXT "maptext" + + + +///Categories go here. Put sane names in the string since they get displayed. +#define EVLOG_CATEGORY_MOVELOOPS "Moveloops" +#define EVLOG_CATEGORY_JPS "JPS" +#define EVLOG_CATEGORY_AI_DECISIONMAKING "AI Decisionmaking" +#define EVLOG_CATEGORY_AI_BEHAVIORS "AI Behaviors" +#define EVLOG_CATEGORY_AI_TARGETING "AI Targeting" diff --git a/code/__DEFINES/food.dm b/code/__DEFINES/food.dm index 2b0ef2dd8e9..eefdec7712d 100644 --- a/code/__DEFINES/food.dm +++ b/code/__DEFINES/food.dm @@ -137,7 +137,7 @@ GLOBAL_ALIST_INIT(food_quality_description, alist( FOOD_QUALITY_VERYGOOD = "very good", FOOD_QUALITY_FANTASTIC = "fantastic", FOOD_QUALITY_AMAZING = "amazing", - FOOD_QUALITY_TOP = "godlike", + FOOD_QUALITY_TOP = "divine", )) /// Weighted lists of crafted food buffs randomly given according to crafting_complexity unless the food has a specific buff diff --git a/code/__DEFINES/gizmo.dm b/code/__DEFINES/gizmo.dm new file mode 100644 index 00000000000..e48b14e21c2 --- /dev/null +++ b/code/__DEFINES/gizmo.dm @@ -0,0 +1,40 @@ +// Cryptic gizmo pulses for Interface Science +#define GIZMO_PULSE_1 "Gizmo Pulse 1" +#define GIZMO_PULSE_2 "Gizmo Pulse 2" +#define GIZMO_PULSE_3 "Gizmo Pulse 3" +#define GIZMO_PULSE_4 "Gizmo Pulse 4" +#define GIZMO_PULSE_5 "Gizmo Pulse 5" +#define GIZMO_PULSE_6 "Gizmo Pulse 6" +#define GIZMO_PULSE_7 "Gizmo Pulse 7" +#define GIZMO_PULSE_8 "Gizmo Pulse 8" + +/// From base of /datum/gizactive/start_moving/activate(): () +#define COMSIG_GIZMO_START_MOVING "gizmo_start_moving" +/// From base of /datum/gizactive/stop_moving/activate(): () +#define COMSIG_GIZMO_STOP_MOVING "gizmo_stop_moving" + +/// From base of /datum/gizactive/lights_on/activate(): () +#define COMSIG_GIZMO_ON_STATE "gizmo_on_state" +/// From base of /datum/gizactive/lights_off/activate(): () +#define COMSIG_GIZMO_OFF_STATE "gizmo_off_state" + +#define GIZMO_PUZZLE_WRONG 1 +#define GIZMO_PUZZLE_CORRECT 2 +#define GIZMO_PUZZLE_SOLVED 3 + +#define GIZMO_INTERFACE_WIRES "gizmo_interface_wires" +#define GIZMO_INTERFACE_VOICE "gizmo_interface_voices" + +#define GIZMO_PICK_ONE "gizmo_pick_one" + +/// Common gizmo modes to pick from. They are also weighted so you have even more probability control isnt that cool +#define GIZMO_COMMON_MODES list(\ + /datum/gizmodes/mood_pulser = 1,\ + /datum/gizmodes/mopper = 1,\ + /datum/gizmodes/teleporter = 1,\ + /datum/gizmodes/electric = 1,\ + /datum/gizmodes/dispenser/food = 1,\ + /datum/gizmodes/sputter = 1,\ + /datum/gizmodes/copier = 1,\ + /datum/gizmodes/bad = 1,\ +) diff --git a/code/__DEFINES/hud.dm b/code/__DEFINES/hud.dm index d890beb8540..6e7f384e04a 100644 --- a/code/__DEFINES/hud.dm +++ b/code/__DEFINES/hud.dm @@ -87,7 +87,6 @@ #define HUD_CYBORG_HANDS "cyborg_module" #define HUD_CYBORG_RADIO "cyborg_radio" #define HUD_CYBORG_DEATH "cyborg_death" -#define HUD_KEY_CYBORG_MODULE(slot) "cyborg_module:[slot]" #define HUD_AI_FLOOR_INDICATOR "ai_floor_indicator" #define HUD_AI_GO_UP "ai_go_up" diff --git a/code/__DEFINES/icon_smoothing.dm b/code/__DEFINES/icon_smoothing.dm index 3e877bf7271..30a1f6ef181 100644 --- a/code/__DEFINES/icon_smoothing.dm +++ b/code/__DEFINES/icon_smoothing.dm @@ -128,17 +128,22 @@ DEFINE_BITFIELD(smoothing_junction, list( #define SMOOTH_GROUP_CARPET_SIMPLE_NEON_VIOLET_NODOTS S_TURF(50) //![turf/open/floor/carpet/neon/simple/violet/nodots] #define SMOOTH_GROUP_CARPET_SIMPLE_NEON_PINK_NODOTS S_TURF(51) //![turf/open/floor/carpet/neon/simple/pink/nodots] #define SMOOTH_GROUP_BAMBOO_FLOOR S_TURF(52) //![/turf/open/floor/bamboo] +#define SMOOTH_GROUP_FLOOR_WATER_LAVALAND S_TURF(53) //![/turf/open/water/lavaland_atmos/basalt] +#define SMOOTH_GROUP_FLOOR_SIDERITE S_TURF(54) ///turf/open/misc/grass +#define SMOOTH_GROUP_FLOOR_SHALE S_TURF(55) ///turf/open/misc/grass -#define SMOOTH_GROUP_CLOSED_TURFS S_TURF(53) ///turf/closed -#define SMOOTH_GROUP_MATERIAL_WALLS S_TURF(54) ///turf/closed/wall/material -#define SMOOTH_GROUP_SYNDICATE_WALLS S_TURF(55) ///turf/closed/wall/r_wall/plastitanium/syndicate, /turf/closed/indestructible/syndicate -#define SMOOTH_GROUP_HOTEL_WALLS S_TURF(56) ///turf/closed/indestructible/hotelwall -#define SMOOTH_GROUP_MINERAL_WALLS S_TURF(57) ///turf/closed/mineral, /turf/closed/indestructible -#define SMOOTH_GROUP_BOSS_WALLS S_TURF(58) ///turf/closed/indestructible/riveted/boss -#define SMOOTH_GROUP_SURVIVAL_TITANIUM_WALLS S_TURF(59) ///turf/closed/wall/mineral/titanium/survival -#define SMOOTH_GROUP_TURF_OPEN_CLIFF S_TURF(60) ///turf/open/cliff -#define SMOOTH_GROUP_HIEROPHANT S_TURF(61) ///turf/closed/indestructible/riveted/hierophant -#define SMOOTH_GROUP_PLASTINUM_WALLS S_TURF(62) ///turf/closed/indestructible/riveted/plastinum +#define SMOOTH_GROUP_CLOSED_TURFS S_TURF(56) ///turf/closed +#define SMOOTH_GROUP_MATERIAL_WALLS S_TURF(57) ///turf/closed/wall/material +#define SMOOTH_GROUP_SYNDICATE_WALLS S_TURF(58) ///turf/closed/wall/r_wall/plastitanium/syndicate, /turf/closed/indestructible/syndicate +#define SMOOTH_GROUP_HOTEL_WALLS S_TURF(59) ///turf/closed/indestructible/hotelwall +#define SMOOTH_GROUP_MINERAL_WALLS S_TURF(60) ///turf/closed/mineral, /turf/closed/indestructible +#define SMOOTH_GROUP_RED_ROCK_WALLS S_TURF(61) ///turf/closed/mineral/asteroid, /turf/closed/mineral/random/stationside/asteroid +#define SMOOTH_GROUP_SHALE_WALLS S_TURF(62) ///turf/closed/mineral/random/volcanic/shale +#define SMOOTH_GROUP_BOSS_WALLS S_TURF(63) ///turf/closed/indestructible/riveted/boss +#define SMOOTH_GROUP_SURVIVAL_TITANIUM_WALLS S_TURF(64) ///turf/closed/wall/mineral/titanium/survival +#define SMOOTH_GROUP_TURF_OPEN_CLIFF S_TURF(65) ///turf/open/cliff +#define SMOOTH_GROUP_HIEROPHANT S_TURF(66) ///turf/closed/indestructible/riveted/hierophant +#define SMOOTH_GROUP_PLASTINUM_WALLS S_TURF(67) ///turf/closed/indestructible/riveted/plastinum // BUBBER EDIT ADDITION #define SMOOTH_GROUP_ELEVATED_PLASTEEL S_TURF(63) @@ -153,7 +158,6 @@ DEFINE_BITFIELD(smoothing_junction, list( #define MAX_S_TURF 67 //Always match this value with the one above it. //BUBBER EDIT END - #define S_OBJ(num) ("-" + #num + ",") /* /obj included */ diff --git a/code/__DEFINES/inventory.dm b/code/__DEFINES/inventory.dm index 047c59330cf..4cdf845eb78 100644 --- a/code/__DEFINES/inventory.dm +++ b/code/__DEFINES/inventory.dm @@ -213,6 +213,7 @@ DEFINE_BITFIELD(no_equip_flags, list( #define HEADCOVERSMOUTH (1<<4) #define PEPPERPROOF (1<<5) //protects against pepperspray #define EARS_COVERED (1<<6) +#define ALLOW_SURGERY_THROUGH (1<<7) //item will not obstruct body part access, such as for surgery, despite covering the body part #define TINT_MILD 1.5 //Threshold of tint level to apply mild tint overlay #define TINT_DARKENED 2 //Threshold of tint level to apply weld mask overlay @@ -243,7 +244,7 @@ GLOBAL_LIST_INIT(any_suit_storage, typecacheof(list( /obj/item/lighter, /obj/item/pen, /obj/item/modular_computer/pda, - /obj/item/toy, + /obj/item/toy/plush, /obj/item/radio, /obj/item/storage/bag/books, /obj/item/storage/fancy/cigarettes, diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index f7dd0654d20..19349fa2768 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -117,7 +117,7 @@ GLOBAL_LIST_INIT(turfs_pass_meteor, typecacheof(list( //Human sub-species #define isabductor(A) (is_species(A, /datum/species/abductor)) -#define isghostspecies(A) (is_species(A, /datum/species/ghost)) +#define isspirit(A) (is_species(A, /datum/species/spirit)) #define isgolem(A) (is_species(A, /datum/species/golem)) #define islizard(A) (is_species(A, /datum/species/lizard)) #define isashwalker(A) (is_species(A, /datum/species/lizard/ashwalker)) diff --git a/code/__DEFINES/keybinding.dm b/code/__DEFINES/keybinding.dm index 1e88e16d5d7..73da7d1924c 100644 --- a/code/__DEFINES/keybinding.dm +++ b/code/__DEFINES/keybinding.dm @@ -39,6 +39,7 @@ #define COMSIG_KB_CLIENT_RADIO_DOWN "keybinding_client_radio_down" #define COMSIG_KB_CLIENT_ME_DOWN "keybinding_client_me_down" #define COMSIG_KB_CLIENT_OOC_DOWN "keybinding_client_ooc_down" +#define COMSIG_KB_CLIENT_PRAY_DOWN "keybinding_client_pray_down" //Human #define COMSIG_KB_HUMAN_QUICKEQUIP_DOWN "keybinding_human_quickequip_down" diff --git a/code/__DEFINES/lag_switch.dm b/code/__DEFINES/lag_switch.dm index 2152d0d9a55..d6349266ea0 100644 --- a/code/__DEFINES/lag_switch.dm +++ b/code/__DEFINES/lag_switch.dm @@ -20,4 +20,7 @@ /// Stops people from changing things in the character creator. Entirely. #define DISABLE_CREATOR 9 // SKYRAT EDIT END -#define MEASURES_AMOUNT 9 // The total number of switches defined above // SKYRAT EDIT ADDITION +/// Disables runechat for ghosts +#define DISABLE_DEAD_RUNECHAT 10 + +#define MEASURES_AMOUNT 10 // The total number of switches defined above // SKYRAT EDIT ADDITION diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index 5a5df852f0b..4c735489e08 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -40,12 +40,11 @@ #define POINT_PLANE 5 //---------- LIGHTING ------------- -/// Normal 1 per turf dynamic lighting underlays +/// Normal 1 per turf dynamic lighting objects #define LIGHTING_PLANE 10 /// Lighting objects that are "free floating" #define O_LIGHTING_VISUAL_PLANE 11 -#define O_LIGHTING_VISUAL_RENDER_TARGET "*O_LIGHT_VISUAL_PLANE" // Render plate used by overlay lighting to mask turf lights #define RENDER_PLANE_TURF_LIGHTING 12 @@ -70,7 +69,9 @@ /// Main game plane to which everything renders, which then is multiplied by light /// Should not be lit directly as it is sourced for emissive bloom -#define RENDER_PLANE_UNLIT_GAME 19 +#define RENDER_PLANE_UNLIT_GAME 18 + +#define RENDER_PLANE_O_LIGHTING 19 #define RENDER_PLANE_LIGHTING 20 @@ -257,6 +258,7 @@ #define ABOVE_MOB_LAYER 4.1 #define WALL_OBJ_LAYER 4.25 #define TRAM_SIGNAL_LAYER 4.26 +#define EDGED_TURF_LOWER_LAYER 4.28 #define EDGED_TURF_LAYER 4.3 #define ON_EDGED_TURF_LAYER 4.35 #define SPACEVINE_LAYER 4.4 diff --git a/code/__DEFINES/lazy_templates.dm b/code/__DEFINES/lazy_templates.dm index bc1e99e594c..24789d5ba00 100644 --- a/code/__DEFINES/lazy_templates.dm +++ b/code/__DEFINES/lazy_templates.dm @@ -1,3 +1,4 @@ +#define LAZY_TEMPLATE_KEY_NUKIEELEVATOR "LT_NUKIEELEVATOR" #define LAZY_TEMPLATE_KEY_NUKIEBASE "LT_NUKIEBASE" #define LAZY_TEMPLATE_KEY_WIZARDDEN "LT_WIZARDDEN" #define LAZY_TEMPLATE_KEY_NINJA_HOLDING_FACILITY "LT_NINJAHOLDING" @@ -6,6 +7,7 @@ #define LAZY_TEMPLATE_KEY_VOIDWALKER_VOID "LT_VOIDWALKERVOID" #define LAZY_TEMPLATE_KEY_LIST_ALL(...) list( \ + "Nukie Elevator" = LAZY_TEMPLATE_KEY_NUKIEELEVATOR, \ "Nukie Base" = LAZY_TEMPLATE_KEY_NUKIEBASE, \ "Wizard Den" = LAZY_TEMPLATE_KEY_WIZARDDEN, \ "Ninja Holding" = LAZY_TEMPLATE_KEY_NINJA_HOLDING_FACILITY, \ diff --git a/code/__DEFINES/mining.dm b/code/__DEFINES/mining.dm index cb78f461fee..2c0b0e63e35 100644 --- a/code/__DEFINES/mining.dm +++ b/code/__DEFINES/mining.dm @@ -36,39 +36,6 @@ /// Duration for wave defense for the tarkon emergency engines. #define WAVE_DURATION_TARKON 120 SECONDS -/// Proximity to a vent that a wall ore needs to be for 5 ore to be mined. -#define VENT_PROX_VERY_HIGH 3 -/// Proximity to a vent that a wall ore needs to be for 4 ore to be mined. -#define VENT_PROX_HIGH 6 -/// Proximity to a vent that a wall ore needs to be for 3 ore to be mined. -#define VENT_PROX_MEDIUM 15 -/// Proximity to a vent that a wall ore needs to be for 2 ore to be mined. -#define VENT_PROX_LOW 32 -/// Proximity to a vent that a wall ore needs to be for 1 ore to be mined. -#define VENT_PROX_FAR 64 - -/// The chance of ore spawning in a wall that is VENT_PROX_VERY_HIGH tiles to a vent. -#define VENT_CHANCE_VERY_HIGH 75 -/// The chance of ore spawning in a wall that is VENT_PROX_HIGH tiles to a vent. -#define VENT_CHANCE_HIGH 18 -/// The chance of ore spawning in a wall that is VENT_PROX_MEDIUM tiles to a vent. -#define VENT_CHANCE_MEDIUM 9 -/// The chance of ore spawning in a wall that is VENT_PROX_LOW tiles to a vent. -#define VENT_CHANCE_LOW 5 -/// The chance of ore spawning in a wall that is VENT_PROX_FAR tiles to a vent. -#define VENT_CHANCE_FAR 1 - -/// The amount of ore that is mined from a wall that is VENT_PROX_VERY_HIGH tiles to a vent. -#define ORE_WALL_VERY_HIGH 5 -/// The amount of ore that is mined from a wall that is VENT_PROX_HIGH tiles to a vent. -#define ORE_WALL_HIGH 4 -/// The amount of ore that is mined from a wall that is VENT_PROX_MEDIUM tiles to a vent. -#define ORE_WALL_MEDIUM 3 -/// The amount of ore that is mined from a wall that is VENT_PROX_LOW tiles to a vent. -#define ORE_WALL_LOW 2 -/// The amount of ore that is mined from a wall that is VENT_PROX_FAR tiles to a vent. -#define ORE_WALL_FAR 1 - /// Lifetime of a boulder platform in seconds when spawned in lava/plasma. #define PLATFORM_LIFE_DEFAULT 10 SECONDS @@ -79,9 +46,25 @@ /// The number of points a miner gets for discovering a vent, multiplied by BOULDER_SIZE when completing a wave defense minus the discovery bonus. #define MINER_POINT_MULTIPLIER 100 -/// The multiplier that gets applied for automatically generated mining points. -#define MINING_POINT_MACHINE_MULTIPLIER 0.8 -//String defines to use with CaveGenerator presets for what ore breakdown to use. +// String defines to use with CaveGenerator presets for what ore breakdown to use. #define OREGEN_PRESET_LAVALAND "lavaland" #define OREGEN_PRESET_TRIPLE_Z "triple_z" + +// Ore vein types +/// Round ore cluster +#define ORE_VEIN_CLUSTER "cluster" +/// Randomly scattered ore +#define ORE_VEIN_SCATTER "scatter" +/// A straight or slightly bent uneven line +#define ORE_VEIN_PLAIN "plain" +/// A branching tree-like vein +#define ORE_VEIN_BRANCH "branch" + +/// Maximum precision for ore spawn probabilities +#define ORE_CHANCE_PRECISION 5 + +/// Permanent style multiplier modifier earned from tapping vents, modified by vent size. +#define ACTION_MULTIPLIER_PER_VENT_VALUE 0.1 +/// Permanent style multiplier modifier earned from killing a megafauna. +#define ACTION_MULTIPLIER_MAJOR_KILL 0.1 diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 0571bccc61f..e1fc285b9c8 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -132,6 +132,26 @@ // BUBBER EDIT END +/// Readable biotypes, keep this in the same order as the flags are +#define MOB_BIOTYPES_READABLE list(\ + "organic", \ + "mineral", \ + "robotic", \ + "undead", \ + "humanoid", \ + "insectoid", \ + "beast", \ + "monstrous", \ + "reptile", \ + "spirit", \ + "plant", \ + "slime", \ + "aquatic", \ + "mining", \ + "crustacean", \ + "skeletal", \ +) + //Lung respiration type flags #define RESPIRATION_OXYGEN (1 << 0) #define RESPIRATION_N2 (1 << 1) @@ -178,6 +198,8 @@ // SKYRAT EDIT END +/// Analagous to BODYSHAPE_DIGITIGRADE, though this one is not removed if the mob's shape changed +#define BODYTYPE_DIGITIGRADE (1<<9) // Bodyshape defines for how things can be worn, i.e., what "shape" the mob sprite is ///The limb fits the human mold. This is not meant to be literal, if the sprite "fits" on a human, it is "humanoid", regardless of origin. @@ -191,8 +213,10 @@ /// Golem's wacky rocky limbs #define BODYSHAPE_GOLEM (1<<4) +/// List of body part flags that can not be bioscrambled #define BODYTYPE_BIOSCRAMBLE_INCOMPATIBLE (BODYTYPE_ROBOTIC | BODYTYPE_LARVA_PLACEHOLDER | BODYTYPE_GOLEM | BODYTYPE_PEG) -#define BODYTYPE_CAN_BE_BIOSCRAMBLED(bodytype) (!(bodytype & BODYTYPE_BIOSCRAMBLE_INCOMPATIBLE)) +/// Check to see if a bodypart limb can be bioscrambled +#define BODYPART_CAN_BE_BIOSCRAMBLED(bodypart) (!(bodypart.bodytype & BODYTYPE_BIOSCRAMBLE_INCOMPATIBLE) && !(bodypart.flags_1 & HOLOGRAM_1)) // Defines for Species IDs. Used to refer to the name of a species, for things like bodypart names or species preferences. #define SPECIES_ABDUCTOR "abductor" @@ -207,6 +231,7 @@ #define SPECIES_HUMAN "human" #define SPECIES_JELLYPERSON "jelly" #define SPECIES_SLIMEPERSON "slime" +#define SPECIES_SPIRIT "spirit" #define SPECIES_LUMINESCENT "luminescent" #define SPECIES_STARGAZER "stargazer" #define SPECIES_LIZARD "lizard" @@ -878,7 +903,8 @@ GLOBAL_LIST_INIT(layers_to_offset, list( "[HEAD_LAYER]" = UPPER_BODY, // Hair will get cut off by filter "[HAIR_LAYER]" = UPPER_BODY, - "[BENEATH_HAIR_LAYER]" = UPPER_BODY, + // Doesn't do much + "[EYES_LAYER]" = UPPER_BODY, // Long belts (sabre sheathe) will get cut off by filter "[BELT_LAYER]" = LOWER_BODY, // Everything below looks fine with or without a filter, so we can skip it and just offset @@ -895,6 +921,7 @@ GLOBAL_LIST_INIT(layers_to_offset, list( "[ID_LAYER]" = UPPER_BODY, "[FACEMASK_LAYER]" = UPPER_BODY, "[LOW_FACEMASK_LAYER]" = UPPER_BODY, + "[BENEATH_HAIR_LAYER]" = UPPER_BODY, // alt mask layer // These two are cached, and have their appearance shared(?), so it's safer to just not touch it "[MUTATIONS_LAYER]" = NO_MODIFY, "[FRONT_MUTATIONS_LAYER]" = NO_MODIFY, @@ -903,7 +930,6 @@ GLOBAL_LIST_INIT(layers_to_offset, list( // BACK_LAYER (backpacks are big) // BODYPARTS_HIGH_LAYER (arms) // BODY_LAYER (body markings (full body), underwear (full body)) - // EYES_LAYER, // BODY_ADJ_LAYER (external organs like wings) // BODY_BEHIND_LAYER (external organs like wings) // BODY_FRONT_LAYER (external organs like wings) @@ -1019,6 +1045,14 @@ GLOBAL_LIST_INIT(layers_to_offset, list( /// Possible value of [/atom/movable/buckle_dir]. If set to a different (positive-or-zero) value than this, the buckling thing will force a dir on the buckled. #define BUCKLE_MATCH_DIR -1 +// Defines for [/datum/component/riding/var/other_unbuckle] +/// Other mobs cannot force riders to unbuckle in any means +#define CANNOT_FORCE_UNBUCKLE 0 +/// Other mobs can force riders to unbuckle by simply clicking on the parent +#define CAN_FORCE_UNBUCKLE 1 +/// Other mobs can force riders to unbuckle by disarming the parent or the rider minimum twice +#define CAN_DISARM_UNBUCKLE 2 + // Flags for fully_heal(). /// Special flag that means this heal is an admin heal and goes above and beyond diff --git a/code/__DEFINES/obj_flags.dm b/code/__DEFINES/obj_flags.dm index b01406bf631..0193a5b7c00 100644 --- a/code/__DEFINES/obj_flags.dm +++ b/code/__DEFINES/obj_flags.dm @@ -68,6 +68,8 @@ #define SKIP_FANTASY_ON_SPAWN (1<<20) /// If an item has had its /datum/element/weapon_description initialized or not. #define WEAPON_DESCRIPTION_INITIALIZED (1<<21) +/// If an item causes bluespace interference when teleported with. +#define BLUESPACE_INTERFERENCE (1<<22) // Flags for the clothing_flags var on /obj/item/clothing diff --git a/code/__DEFINES/paper.dm b/code/__DEFINES/paper.dm index 4eea9e7c2f6..ff4c4a50856 100644 --- a/code/__DEFINES/paper.dm +++ b/code/__DEFINES/paper.dm @@ -1,5 +1,7 @@ /// Maximimum number of characters that we allow on paper. #define MAX_PAPER_LENGTH 5000 +/// Maximimum number of characters that we allow in a book, after unfolding and encoding html. +#define MAX_BOOK_LENGTH (MAX_PAPER_LENGTH * 2) /// Max number of stamps that can be applied to the paper in tgui. #define MAX_PAPER_STAMPS 30 /// Max number of stamp overlays that we'll add to a piece of paper's icon. @@ -41,3 +43,7 @@ #define LIST_PAPER_STAMP_X "x" #define LIST_PAPER_STAMP_Y "y" #define LIST_PAPER_ROTATION "rotation" + +///Use in conjunction with `advanced_html` to have underlined text that, when hovered over, will let you see additional text. +///Would be appreciated if you avoided dotted underlined (and underlined in general) text elsewhere so players don't get confused. +#define UNDERLINED_HTML_TEXT(text_displayed, revealed_text) "[text_displayed]" diff --git a/code/__DEFINES/projectiles.dm b/code/__DEFINES/projectiles.dm index 48252009855..ef451f039bc 100644 --- a/code/__DEFINES/projectiles.dm +++ b/code/__DEFINES/projectiles.dm @@ -64,6 +64,8 @@ #define CALIBER_JUNK "junk" /// The caliber used by the (gatfruit) peashooter #define CALIBER_PEA "pea" +/// The caliber used in the naval cannon +#define CALIBER_40MM_SHELL "40MM_shell" /// For gunpoints, how many tiles around the target the shooter can roam without losing their shot #define GUNPOINT_SHOOTER_STRAY_RANGE 2 diff --git a/code/__DEFINES/reagents.dm b/code/__DEFINES/reagents.dm index 4009d2f3cba..1e3b65dc760 100644 --- a/code/__DEFINES/reagents.dm +++ b/code/__DEFINES/reagents.dm @@ -248,7 +248,7 @@ /// Reaction tags for medication #define MEDICATION_REACTION_TAGS (REACTION_TAG_HEALING | REACTION_TAG_DAMAGING | REACTION_TAG_ORGAN | REACTION_TAG_DRUG) /// Reaction tags for things the chemist would make -#define CHEMIST_REACTION_TAGS (REACTION_TAG_EXPLOSIVE | REACTION_TAG_CHEMICAL | REACTION_TAG_COMPETITIVE | REACTION_TAG_EXPLOSIVE | REACTION_TAG_COMPONENT) +#define CHEMIST_REACTION_TAGS (REACTION_TAG_EXPLOSIVE | REACTION_TAG_CHEMICAL | REACTION_TAG_COMPETITIVE | REACTION_TAG_COMPONENT) /// Reaction tags for botanist stuff #define BOTANIST_REACTION_TAGS (REACTION_TAG_PLANT | REACTION_TAG_COMPONENT) /// Reaction tags for food and drink mainly @@ -318,3 +318,5 @@ #define SPARK_ACT_ENCLOSED (1 << 0) /// We're in a large container or something, so decrease the power of bootleg explosives like welding fuel #define SPARK_ACT_WEAKEN_COMMON (1 << 1) +/// Chemical threshold that industrial waste needs to start eating floors. +#define WASTE_REACTION_THRESHOLD 10 diff --git a/code/__DEFINES/robots.dm b/code/__DEFINES/robots.dm index 98d8e69b64e..d14f2656a81 100644 --- a/code/__DEFINES/robots.dm +++ b/code/__DEFINES/robots.dm @@ -228,6 +228,30 @@ DEFINE_BITFIELD(security_mode_flags, list( "SECBOT_SABOTEUR_AFFECTED" = SECBOT_SABOTEUR_AFFECTED, )) +///can honkbots slip people? +#define HONKBOT_MODE_SLIP (1<<6) + +//repairbots +///can we fix breaches +#define REPAIRBOT_FIX_BREACHES (1<<0) +///can we fix grilles +#define REPAIRBOT_REPLACE_WINDOWS (1<<1) +///can we replace tiles +#define REPAIRBOT_REPLACE_TILES (1<<2) +///can we fix girders +#define REPAIRBOT_FIX_GIRDERS (1<<3) +///can we build girders +#define REPAIRBOT_BUILD_GIRDERS (1<<4) + +DEFINE_BITFIELD(repairbot_flags, list( + "FIX_BREACHES" = REPAIRBOT_FIX_BREACHES, + "REPLACE_WINDOWS" = REPAIRBOT_REPLACE_WINDOWS, + "REPLACE_TILES" = REPAIRBOT_REPLACE_TILES, + "FIX_GIRDERS" = REPAIRBOT_FIX_GIRDERS, + "BUILD_GIRDERS" = REPAIRBOT_BUILD_GIRDERS, +)) + + //MedBOT defines ///Whether to declare if someone (we are healing) is in critical condition #define MEDBOT_DECLARE_CRIT (1<<0) diff --git a/code/__DEFINES/say.dm b/code/__DEFINES/say.dm index af71e852552..88e31e597d2 100644 --- a/code/__DEFINES/say.dm +++ b/code/__DEFINES/say.dm @@ -93,6 +93,8 @@ #define SPAN_TAPE_RECORDER "tape_recorder" #define SPAN_SMALL_VOICE "small" #define SPAN_SOAPBOX "soapbox" +#define SPAN_COLOSSUS "colossus" +#define SPAN_DANGER "danger" //bitflag #defines for return value of the radio() proc. /// Makes the message use italics #define ITALICS (1<<0) @@ -150,3 +152,11 @@ ///Defines for priorities for the bubble_icon_override comp #define BUBBLE_ICON_PRIORITY_ACCESSORY 2 #define BUBBLE_ICON_PRIORITY_ORGAN 1 + +//These are the names of the commands, what you'd need to type to do the command (also used in winset) +#define VERB_SAY "Say" +#define VERB_WHISPER "Whisper" +#define VERB_ME "Me" +//Gave this shit a shorter name so you only have to time out "ooc" rather than "ooc message" to use it --NeoFite +#define VERB_OOC "OOC" +#define VERB_PRAY "Pray" diff --git a/code/__DEFINES/sight.dm b/code/__DEFINES/sight.dm index ab88e6e2c30..610a03a9e46 100644 --- a/code/__DEFINES/sight.dm +++ b/code/__DEFINES/sight.dm @@ -17,6 +17,9 @@ #define INVISIBILITY_OBSERVER 60 #define SEE_INVISIBLE_OBSERVER 60 +#define INVISIBILITY_ADMIN 61 +#define SEE_INVISIBLE_ADMIN 61 + #define INVISIBILITY_MAXIMUM 100 //the maximum allowed for "real" objects #define INVISIBILITY_ABSTRACT 101 //only used for abstract objects (e.g. spacevine_controller), things that are not really there. diff --git a/code/__DEFINES/skin.dm b/code/__DEFINES/skin.dm new file mode 100644 index 00000000000..45702762a97 --- /dev/null +++ b/code/__DEFINES/skin.dm @@ -0,0 +1,24 @@ +//These defines are used in skin.dmf, if one is to be renamed/edited, this file must match it. +//IMPORTANT: TGUI & especially `PANE_SPLITTERS` does not use defines, if you rename something make sure you keep name parity! +//Ex: tgui-panel/index.tsx uses `browseroutput` & `output_selector` +//`setClientTheme` has a list of nearly every skin.dmf element in it. +#define SKIN_MAINWINDOW "mainwindow" +#define SKIN_MAINWINDOW_SPLIT "[SKIN_MAINWINDOW].split" +#define SKIN_MAINWINDOW_TOOLTIP "mainwindow.tooltip" + +#define SKIN_MAPWINDOW "mapwindow" +#define SKIN_MAPWINDOW_MAP "[SKIN_MAPWINDOW].map" +#define SKIN_MAPWINDOW_STATUS_BAR "[SKIN_MAPWINDOW].status_bar" + +#define SKIN_INFOWINDOW "info" +#define SKIN_INFOWINDOW_CHILD "[SKIN_INFOWINDOW].info_child" + +#define SKIN_TGUISAY "tgui_say" +#define SKIN_TGUISAY_BROWSER "[SKIN_TGUISAY].browser" + +#define SKIN_DEFAULT "default" +#define SKIN_DEFAULT_SHIFT "[SKIN_DEFAULT].Shift" +#define SKIN_DEFAULT_SHIFTUP "[SKIN_DEFAULT].ShiftUp" + +#define OUTPUT_SELECTOR "output_selector" +#define OUTPUT_SELECTOR_LEGACY_OUTPUT_SELECTOR "[OUTPUT_SELECTOR].legacy_output_selector" diff --git a/code/__DEFINES/span.dm b/code/__DEFINES/span.dm index 06d2fbd0bfb..99a54aa4ba4 100644 --- a/code/__DEFINES/span.dm +++ b/code/__DEFINES/span.dm @@ -49,6 +49,7 @@ #define span_cult_bold_italic(str) ("" + str + "") #define span_cult_italic(str) ("" + str + "") #define span_cult_large(str) ("" + str + "") +#define span_cyan(str) ("" + str + "") #define span_danger(str) ("" + str + "") #define span_deadsay(str) ("" + str + "") #define span_deconversion_message(str) ("" + str + "") diff --git a/code/__DEFINES/speech_channels.dm b/code/__DEFINES/speech_channels.dm index 9f1526ebd56..3cd5b40374e 100644 --- a/code/__DEFINES/speech_channels.dm +++ b/code/__DEFINES/speech_channels.dm @@ -4,3 +4,4 @@ #define ME_CHANNEL "Me" #define OOC_CHANNEL "OOC" #define ADMIN_CHANNEL "Admin" +#define PRAY_CHANNEL "Pray" diff --git a/code/__DEFINES/surgery.dm b/code/__DEFINES/surgery.dm index 76a52ae2c58..d4949e88ad6 100644 --- a/code/__DEFINES/surgery.dm +++ b/code/__DEFINES/surgery.dm @@ -3,6 +3,11 @@ /// Helper to figure out if an organ is robotic #define IS_ROBOTIC_ORGAN(organ) (organ.organ_flags & ORGAN_ROBOTIC) +/// List of organ flags that can not be bioscrambled +#define ORGAN_BIOSCRAMBLE_INCOMPATIBLE (ORGAN_ROBOTIC | ORGAN_MINERAL) +/// Check to see if an organ can be bioscrambled +#define ORGAN_CAN_BE_BIOSCRAMBLED(organ) (!(organ.organ_flags & ORGAN_BIOSCRAMBLE_INCOMPATIBLE) && !(organ.flags_1 & HOLOGRAM_1)) + // Flags for the organ_flags var on /obj/item/organ /// Organic organs, the default. Don't get affected by EMPs. #define ORGAN_ORGANIC (1<<0) diff --git a/code/__DEFINES/time.dm b/code/__DEFINES/time.dm index e3d857c891f..fb17dd1ac21 100644 --- a/code/__DEFINES/time.dm +++ b/code/__DEFINES/time.dm @@ -1,8 +1,8 @@ ///number of deciseconds in a day #define MIDNIGHT_ROLLOVER 864000 -///displays the current time into the round, with a lot of extra code just there for ensuring it looks okay after an entire day passes -#define ROUND_TIME(...) ( "[STATION_TIME_PASSED() > MIDNIGHT_ROLLOVER ? "[round(STATION_TIME_PASSED()/MIDNIGHT_ROLLOVER)]:[gameTimestamp(wtime = STATION_TIME_PASSED())]" : gameTimestamp(wtime = STATION_TIME_PASSED())]" ) +/// In-universe, SS13 is set 540 years in the future from the real-world day, hence this number for determining the year-offset for the in-game year. +#define STATION_YEAR_OFFSET 540 ///Returns the time that has passed since the game started #define STATION_TIME_PASSED(...) (world.time - SSticker.round_start_time) @@ -10,12 +10,6 @@ /// Define that just has the current in-universe year for use in whatever context you might want to display that in. (For example, 2022 -> 2562 given a 540 year offset) #define CURRENT_STATION_YEAR (GLOB.year_integer + STATION_YEAR_OFFSET) -/// Used in the GLOB year and tgui PreInit -#define UTC_YEAR time2text(world.realtime,"YYYY",NO_TIMEZONE) - -/// In-universe, SS13 is set 540 years in the future from the real-world day, hence this number for determining the year-offset for the in-game year. -#define STATION_YEAR_OFFSET 540 - #define JANUARY 1 #define FEBRUARY 2 #define MARCH 3 @@ -44,6 +38,7 @@ #define IAN_HOLIDAY "Ian's Birthday" #define HOTDOG_DAY "National Hot Dog Day" #define ICE_CREAM_DAY "National Ice Cream Day" +#define CHERNOBYL_ANNIVERSARY "Chernobyl Disaster Remembrance Day" /* Days of the week to make it easier to reference them. diff --git a/code/__DEFINES/tools.dm b/code/__DEFINES/tools.dm index 9f6b8783e00..1c8db160225 100644 --- a/code/__DEFINES/tools.dm +++ b/code/__DEFINES/tools.dm @@ -22,6 +22,14 @@ /// Can be used to scrape rust off an any atom; which will result in the Rust Component being qdel'd #define TOOL_RUSTSCRAPER "rustscraper" +// Used by the tool_blocker element, to block the primary or secondary tool action (or both) +/// e.g. crowbar_act() +#define TOOL_ACT_PRIMARY (1<<0) +/// e.g. crowbar_act_secondary() +#define TOOL_ACT_SECONDARY (1<<1) +/// e.g. both crowbar_act() and crowbar_act_secondary() +#define TOOL_ACT_ALL TOOL_ACT_PRIMARY | TOOL_ACT_SECONDARY + // If delay between the start and the end of tool operation is less than MIN_TOOL_SOUND_DELAY, // tool sound is only played when op is started. If not, it's played twice. #define MIN_TOOL_SOUND_DELAY 20 diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index c63ef9eaaf4..b1d43469fa1 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -220,8 +220,6 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_NO_BLOOD_OVERLAY "no_blood_overlay" /// Humans with this trait cannot have underwear #define TRAIT_NO_UNDERWEAR "no_underwear" -/// This carbon doesn't show an overlay when they have no brain -#define TRAIT_NO_DEBRAIN_OVERLAY "no_debrain_overlay" /// Humans with this trait cannot get augmentation surgery #define TRAIT_NO_AUGMENTS "no_augments" /// This carbon doesn't get hungry @@ -1224,9 +1222,6 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// Trait given to a dreaming carbon when they are currently doing dreaming stuff #define TRAIT_DREAMING "currently_dreaming" -/// Trait that allows non-heretics to have heretical dreams -#define TRAIT_HERETICAL_DREAMS "heretical_dreams" - /// Trait for if you've recently had a Last Word cocktail #define TRAIT_HAD_LAST_WORD "had_last_word" @@ -1387,8 +1382,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai ///Trait given to limb by /mob/living/basic/living_limb_flesh #define TRAIT_IGNORED_BY_LIVING_FLESH "livingflesh_ignored" -///Trait given to organs that have been inside a living being previously -#define TRAIT_USED_ORGAN "used_organ" +///Trait given to organs that have previously been inside a being with a mind +#define TRAIT_ORGAN_USED_BY_PLAYER "organ_used_by_player" ///Trait given to organs that have started inside a being with a client #define TRAIT_CLIENT_STARTING_ORGAN "client_starting_organ" @@ -1431,6 +1426,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// Trait given when a mob is currently in invisimin mode #define TRAIT_INVISIMIN "invisimin" +/// Trait given when a mob has admin esp turned on +#define TRAIT_ADMIN_ESP "admin_esp" + ///Trait given when a mob has been tipped #define TRAIT_MOB_TIPPED "mob_tipped" @@ -1595,6 +1593,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// Demolition modifier when hitting this object is inverted (ie, 1 / demolition) #define TRAIT_INVERTED_DEMOLITION "demolition_inverted" +/// Ignores demolition modifiers +#define TRAIT_IGNORE_DEMOLITION "ignore_demolition" + /// Makes the mob immune to carpotoxin #define TRAIT_CARPOTOXIN_IMMUNE "carpotoxin_immune" @@ -1658,4 +1659,19 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// Makes the owner desensetized to death, but happy whenever someone gets blown to pieces (as a sacrifice to the necropolis) unless its another worshipper #define TRAIT_NECROPOLIS_WORSHIP "necropolis_worship" +/// Applied to an area, stops random power failures from affecting it +#define TRAIT_AREA_BLOCK_POWER_FAIL "area_block_power_fail" + +/// Sunlight on this turf is blocked and thus you can't get solar power or whatever +#define TRAIT_TURF_SUN_BLOCKED "turf_sun_blocked" + +/// Cannot be backstabbed with a crusher +#define TRAIT_BACKSTAB_IMMUNE "backstab_immune" + +/// Makes the owner immune from the pacification from synthpax +#define TRAIT_SYNTHPAX_IMMUNE "synthpax_immune" + +/// Mobs with this trait will always have be a priority target for mining mobs +#define TRAIT_MINING_AGGRO "mining_aggro" + // END TRAIT DEFINES diff --git a/code/__DEFINES/traits/sources.dm b/code/__DEFINES/traits/sources.dm index e0cd34d8065..63d1d59b731 100644 --- a/code/__DEFINES/traits/sources.dm +++ b/code/__DEFINES/traits/sources.dm @@ -111,9 +111,6 @@ /// Trait given to you by shapeshifting #define SHAPESHIFT_TRAIT "shapeshift_trait" -///From the cuffed_item status effect -#define CUFFED_ITEM_TRAIT "cuffed_item_trait" - // unique trait sources, still defines #define EMP_TRAIT "emp_trait" #define STATUE_MUTE "statue" @@ -348,3 +345,6 @@ /// Trait granted as a result of a mob being husked #define HUSK_TRAIT "husk" + +/// Trait granted from the metabolization of a reagent +#define METABOLIZATION_TRAIT(type) "metabolize:[type]" diff --git a/code/__DEFINES/vv.dm b/code/__DEFINES/vv.dm index eae9769003f..1cbb45a235a 100644 --- a/code/__DEFINES/vv.dm +++ b/code/__DEFINES/vv.dm @@ -84,6 +84,7 @@ #define VV_HK_REMOVECOMPONENT "removecomponent" #define VV_HK_MASS_REMOVECOMPONENT "massremovecomponent" #define VV_HK_MODIFY_TRAITS "modtraits" +#define VV_HK_DEBUG_APPEARANCE "debugappearance" // /atom #define VV_HK_MODIFY_TRANSFORM "atom_transform" diff --git a/code/__DEFINES/wires.dm b/code/__DEFINES/wires.dm index 51990b007b5..9b0883173a9 100644 --- a/code/__DEFINES/wires.dm +++ b/code/__DEFINES/wires.dm @@ -108,3 +108,13 @@ #define AI_WIRE_DISABLED_HACKED -1 #define MAX_WIRE_COUNT 17 + +// Cryptic wires for Interface Science +#define CRYPTIC_WIRE_1 "Cryptic Wire 1" +#define CRYPTIC_WIRE_2 "Cryptic Wire 2" +#define CRYPTIC_WIRE_3 "Cryptic Wire 3" +#define CRYPTIC_WIRE_4 "Cryptic Wire 4" +#define CRYPTIC_WIRE_5 "Cryptic Wire 5" +#define CRYPTIC_WIRE_6 "Cryptic Wire 6" +#define CRYPTIC_WIRE_7 "Cryptic Wire 7" +#define CRYPTIC_WIRE_8 "Cryptic Wire 8" diff --git a/code/__HELPERS/areas.dm b/code/__HELPERS/areas.dm index ce482645ef7..5967e44a413 100644 --- a/code/__HELPERS/areas.dm +++ b/code/__HELPERS/areas.dm @@ -2,15 +2,6 @@ #define EXTRA_ROOM_CHECK_SKIP 1 #define EXTRA_ROOM_CHECK_FAIL 2 -GLOBAL_LIST_INIT(typecache_powerfailure_safe_areas, typecacheof(list( - /area/station/engineering/main, - /area/station/engineering/supermatter, - /area/station/engineering/atmospherics_engine, - /area/station/ai/satellite/chamber, - /area/ruin/comms_agent //fixes icemoon comms station being affected - -))) - // Gets an atmos isolated contained space // Returns an associative list of turf|dirs pairs // The dirs are connected turfs in the same space diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index d625dcbf8c1..b37363b5546 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -203,7 +203,7 @@ flashed_client = player_mob.client if(!flashed_client || (!flashed_client.prefs.read_preference(/datum/preference/toggle/window_flashing) && !ignorepref)) return - winset(flashed_client, "mainwindow", "flash=5") + winset(flashed_client, SKIN_MAINWINDOW, "flash=5") /** * Recursively checks if an item is inside a given type/atom, even through layers of storage. @@ -311,17 +311,20 @@ return FALSE -///Disable power in the station APCs +/** + * Disables power in most station APCs temporarily + * + * * duration_min - the minimum duration of the power failure in seconds (not deciseconds) + * * duration_max - the maximum duration of the power failure in seconds (not deciseconds) + */ /proc/power_fail(duration_min, duration_max) for(var/obj/machinery/power/apc/current_apc as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/power/apc)) - if(!current_apc.cell || !SSmapping.level_trait(current_apc.z, ZTRAIT_STATION)) - continue - var/area/apc_area = current_apc.area - if(is_type_in_typecache(apc_area, GLOB.typecache_powerfailure_safe_areas)) + if(!current_apc.cell || !SSmapping.level_trait(current_apc.z, ZTRAIT_STATION) || HAS_TRAIT(current_apc.area, TRAIT_AREA_BLOCK_POWER_FAIL)) continue - var/duration = rand(duration_min,duration_max) + var/duration = rand(duration_min, duration_max) current_apc.energy_fail(duration) + CHECK_TICK /** * Sends a round tip to a target. If selected_tip is null, a random tip will be sent instead (5% chance of it being silly). diff --git a/code/__HELPERS/hallucinations.dm b/code/__HELPERS/hallucinations.dm index 006497b4aa5..c19005e0acc 100644 --- a/code/__HELPERS/hallucinations.dm +++ b/code/__HELPERS/hallucinations.dm @@ -293,9 +293,9 @@ ADMIN_VERB(debug_hallucination_weighted_list_per_type, R_DEBUG, "Show Hallucinat /// Lines the bubblegum hallucinatoin uses when it pops up #define BUBBLEGUM_HALLUCINATION_LINES list( \ - span_colossus("I AM IMMORTAL."), \ - span_colossus("I SHALL TAKE YOUR WORLD."), \ - span_colossus("I SEE YOU."), \ - span_colossus("YOU CANNOT ESCAPE ME FOREVER."), \ - span_colossus("NOTHING CAN HOLD ME."), \ + "I AM IMMORTAL.", \ + "I SHALL TAKE YOUR WORLD.", \ + "I SEE YOU.", \ + "YOU CANNOT ESCAPE ME FOREVER.", \ + "NOTHING CAN HOLD ME.", \ ) diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index 6929f6a73fb..f3ee4be387f 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -1426,7 +1426,7 @@ GLOBAL_LIST_EMPTY(transformation_animation_objects) // Reorder the 2d pixel data of the passed in frames into a data string that can be passed to rustg_dmi_create_png /proc/reorder_pixels(icon_width, icon_height, grid_width, grid_height, list/frames) - var/file_height = icon_height * grid_height + var/file_width = icon_width * grid_width // This little trick right here reduces the total iteration of repeat_string from the product of the arguments to their sum. // Can't be applied to the general case without a complex partitioning algorithm, @@ -1443,7 +1443,7 @@ GLOBAL_LIST_EMPTY(transformation_animation_objects) var/column = (i-1)%grid_width for(var/y in 1 to length(frame)) var/list/row = jointext(frame[y], "") - var/splice_start = (row_index+y-1)*file_height + column*icon_width + 1 + var/splice_start = (row_index*icon_height+y-1)*file_width + column*icon_width + 1 linear_pixels = splicetext(linear_pixels, (splice_start-1)*9+1, (splice_start+icon_width-1)*9+1, row) var/zero_alpha_regex = regex(@@#(?:(?!a0a0a0)([0-9]|[a-f]){6}00)@, "gi") linear_pixels = replacetext(linear_pixels, zero_alpha_regex, COLOR_DMI_MASK) diff --git a/code/__HELPERS/logging/attack.dm b/code/__HELPERS/logging/attack.dm index 04e118bfe93..e9b64bc7bcd 100644 --- a/code/__HELPERS/logging/attack.dm +++ b/code/__HELPERS/logging/attack.dm @@ -75,8 +75,7 @@ if(user) user.log_message(bomb_message, LOG_ATTACK) //let it go to individual logs as well as the game log bomb_message = "[key_name(user)] at [AREACOORD(user)] [bomb_message]." - else - log_game(bomb_message) + log_game(bomb_message) GLOB.bombers += bomb_message var/area/bomb_area = get_area(bomb) diff --git a/code/__HELPERS/logging/mob.dm b/code/__HELPERS/logging/mob.dm index fe09e6783f9..e976a9193a8 100644 --- a/code/__HELPERS/logging/mob.dm +++ b/code/__HELPERS/logging/mob.dm @@ -52,7 +52,7 @@ if(LOG_RADIO_EMOTE) colored_message = "(RADIOEMOTE) [colored_message]" - var/list/timestamped_message = list("\[[time_stamp(format = "YYYY-MM-DD hh:mm:ss")]\] [key_name_and_tag(src)] [loc_name(src)] (Event #[LAZYLEN(logging[smessage_type])])" = colored_message) + var/list/timestamped_message = list("\[[server_timestamp(format = "YYYY-MM-DD hh:mm:ss")]\] [key_name_and_tag(src)] [loc_name(src)] (Event #[LAZYLEN(logging[smessage_type])])" = colored_message) logging[smessage_type] += timestamped_message diff --git a/code/__HELPERS/logging/research.dm b/code/__HELPERS/logging/research.dm index f352123f9a2..704e8cb6c45 100644 --- a/code/__HELPERS/logging/research.dm +++ b/code/__HELPERS/logging/research.dm @@ -3,4 +3,4 @@ if(!text) return var/html_file = file("[GLOB.log_directory]/[INVESTIGATE_RESEARCH].html") - WRITE_FILE(html_file, "[time_stamp(format = "YYYY-MM-DD hh:mm:ss")] [text]
") + WRITE_FILE(html_file, "[server_timestamp(format = "YYYY-MM-DD hh:mm:ss")] [text]
") diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index 86dba9a686e..004d283016d 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -413,9 +413,11 @@ GLOBAL_LIST_INIT(skin_tone_names, list( return spawned_mobs +#define SEE_DEADCHAT_ADMIN (1<<0) +#define SEE_DEADCHAT_NORMAL (1<<1) // Displays a message in deadchat, sent by source. source is not linkified, message is, to avoid stuff like character names to be linkified. // Automatically gives the class deadsay to the whole message (message + source) -/proc/deadchat_broadcast(message, source=null, mob/follow_target=null, turf/turf_target=null, speaker_key=null, message_type=DEADCHAT_REGULAR, admin_only=FALSE) +/proc/deadchat_broadcast(message, source=null, mob/follow_target=null, turf/turf_target=null, speaker_key=null, message_type=DEADCHAT_REGULAR, admin_only=FALSE, original_message) message = span_deadsay("[source][span_linkify(message)]") if(admin_only) @@ -433,13 +435,13 @@ GLOBAL_LIST_INIT(skin_tone_names, list( if(admin_only) if(!M.client?.holder) continue - var/override = FALSE + var/override = NONE if(M.client?.holder && (chat_toggles & CHAT_DEAD)) - override = TRUE + override = SEE_DEADCHAT_ADMIN if(HAS_TRAIT(M, TRAIT_SIXTHSENSE) && message_type == DEADCHAT_REGULAR) - override = TRUE + override = SEE_DEADCHAT_NORMAL if(SSticker.current_state == GAME_STATE_FINISHED) - override = TRUE + override = SEE_DEADCHAT_NORMAL if(isnewplayer(M) && !override) continue if(M.stat != DEAD && !override) @@ -463,6 +465,7 @@ GLOBAL_LIST_INIT(skin_tone_names, list( if(isobserver(M)) var/rendered_message = message + override = SEE_DEADCHAT_NORMAL if(follow_target) var/F @@ -479,6 +482,12 @@ GLOBAL_LIST_INIT(skin_tone_names, list( else to_chat(M, message, avoid_highlighting = speaker_key == M.key) + // Ghost runechat + if(original_message && ((override & SEE_DEADCHAT_NORMAL) || M.see_invisible >= follow_target.invisibility) && (!SSlag_switch.measures[DISABLE_DEAD_RUNECHAT] || HAS_TRAIT(M, TRAIT_BYPASS_MEASURES)) && M.runechat_prefs_check(M)) + M.create_chat_message(follow_target, /datum/language/common, original_message, list(SPAN_ITALICS)) +#undef SEE_DEADCHAT_ADMIN +#undef SEE_DEADCHAT_NORMAL + //Used in chemical_mob_spawn. Generates a random mob based on a given gold_core_spawnable value. /proc/create_random_mob(spawn_location, mob_class = HOSTILE_SPAWN) var/static/list/mob_spawn_meancritters = list() // list of possible hostile mobs diff --git a/code/__HELPERS/reagents.dm b/code/__HELPERS/reagents.dm index f7838b54fce..0d45d6da061 100644 --- a/code/__HELPERS/reagents.dm +++ b/code/__HELPERS/reagents.dm @@ -8,13 +8,7 @@ return FALSE //do the non-list tests first, because they are cheaper - if(r1.required_container != r2.required_container) - return FALSE - if(r1.is_cold_recipe == r2.is_cold_recipe) - if(r1.required_temp != r2.required_temp) - //one reaction requires a more extreme temperature than the other, so there is no conflict - return FALSE - else + if(r1.is_cold_recipe != r2.is_cold_recipe) var/datum/chemical_reaction/cold_one = r1.is_cold_recipe ? r1 : r2 var/datum/chemical_reaction/warm_one = r1.is_cold_recipe ? r2 : r1 if(cold_one.required_temp < warm_one.required_temp) @@ -40,30 +34,53 @@ long_req = r2 short_req = r1 + //if short one has a container requirement and it's not the same as the long one's, there's no conflict + if(short_req.required_container && short_req.required_container != long_req.required_container) + return FALSE + + //if short one has a more extreme temperature requirement, there's no conflict + if(short_req.is_cold_recipe == long_req.is_cold_recipe) + if(short_req.is_cold_recipe && short_req.required_temp < long_req.required_temp) + return FALSE + if(!short_req.is_cold_recipe && short_req.required_temp > long_req.required_temp) + return FALSE //check if the shorter reaction list is a subset of the longer one - var/list/overlap = r1.required_reagents & r2.required_reagents - if(overlap.len != short_req.required_reagents.len) + var/list/reagent_overlap = long_req.required_reagents & short_req.required_reagents + if(reagent_overlap.len != short_req.required_reagents.len) //there is at least one reagent in the short list that is not in the long list, so there is no conflict return FALSE //check to see if the shorter reaction's catalyst list is also a subset of the longer reaction's catalyst list //if the longer reaction's catalyst list is a subset of the shorter ones, that is fine //if the reaction lists are the same, the short reaction will have the shorter required_catalysts list, so it will register as a conflict - var/list/short_minus_long_catalysts = short_req.required_catalysts - long_req.required_catalysts - if(short_minus_long_catalysts.len) + var/list/catalyst_overlap = long_req.required_catalysts & short_req.required_catalysts + if(catalyst_overlap.len != short_req.required_catalysts.len) //there is at least one unique catalyst for the short reaction, so there is no conflict return FALSE + //if the list of reagents&catalysts is exactly the same, don't bother comparing the amounts, just call it an overlap + if(reagent_overlap.len == long_req.required_reagents.len && catalyst_overlap.len == long_req.required_catalysts.len) + return TRUE + + for(var/datum/reagent/ingredient as anything in reagent_overlap) + //if longer reaction requires lower reagent quantity, there's no conflict + if(reagent_overlap[ingredient] < short_req.required_reagents[ingredient]) + return FALSE + for(var/datum/reagent/catalyst as anything in catalyst_overlap) + //if longer reaction requires lower catalys quantity, there's no conflict + if(catalyst_overlap[catalyst] < short_req.required_catalysts[catalyst]) + return FALSE + //if we got this far, the longer reaction will be impossible to create if the shorter one is earlier in GLOB.chemical_reactions_list_reactant_index, and will require the reagents to be added in a particular order otherwise return TRUE //Creates foam from the reagent. Metaltype is for metal foam, notification is what to show people in textbox -/datum/reagents/proc/create_foam(foamtype, foam_volume, result_type = null, notification = null, log = FALSE) +/datum/reagents/proc/create_foam(foamtype, foam_volume, result_type = null, notification = null, log = FALSE, lifetime, slippery) var/location = get_turf(my_atom) var/datum/effect_system/fluid_spread/foam/foam = new foamtype(location, null, foam_volume, my_atom, carry = src, result_type = result_type) - foam.start(log = log) + foam.start(log = log, lifetime = lifetime, slippery = slippery) clear_reagents() if(!notification) diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index f771ffd8c12..6305904b2ee 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -286,6 +286,16 @@ return TRUE +/proc/filter_illegal_filename_chars(name) + var/regex/illegal_chars = new("\[\\/:*?\"<>|]", "g") + return !findtext(name, illegal_chars) + +/proc/filter_filename_pda(name) + if(is_ic_filtered_for_pdas(name) || is_soft_ic_filtered_for_pdas(name)) + return FALSE + if(!filter_illegal_filename_chars(name)) + return FALSE + return TRUE //html_encode helper proc that returns the smallest non null of two numbers //or 0 if they're both null (needed because of findtext returning 0 when a value is not present) diff --git a/code/__HELPERS/time.dm b/code/__HELPERS/time.dm index 59e95ad8e85..eab1103fc81 100644 --- a/code/__HELPERS/time.dm +++ b/code/__HELPERS/time.dm @@ -1,30 +1,14 @@ -/// Returns UTC timestamp with the specifified format and optionally deciseconds -/proc/time_stamp(format = "hh:mm:ss", show_ds) - var/time_string = time2text(world.timeofday, format, TIMEZONE_UTC) +/// Returns UTC timestamp with the specifified format, with optionally deciseconds or optional IC time (year offset), AKA Nanotrasen Standard Time (NST) +/proc/server_timestamp(format = "hh:mm:ss", show_ds, ic_time, twelve_hour_clock) + var/time_string = twelve_hour_clock ? time_to_twelve_hour(format, world.timeofday, world.timezone) : time2text(world.timeofday, format, world.timezone) + if(ic_time && findtext(format, "YYYY")) //if we have a year, replace the year + time_string = replacetext_char(time_string, "[GLOB.year_integer]", CURRENT_STATION_YEAR) return show_ds ? "[time_string]:[world.timeofday % 10]" : time_string -/// Returns timestamp since the server started, for use with world.time -/proc/gameTimestamp(format = "hh:mm:ss", wtime=world.time) +/// Returns timestamp since the round started, AKA Pay Time (PT) +/proc/round_timestamp(format = "hh:mm:ss", wtime = STATION_TIME_PASSED()) return time2text(wtime, format, NO_TIMEZONE) -///returns the current IC station time in a world.time format -/proc/station_time(wtime = world.time) - return (((wtime - SSticker.round_start_time) * SSticker.station_time_rate_multiplier) + SSticker.gametime_offset) % (24 HOURS) - -///returns the current IC station time in a human readable format -/proc/station_time_timestamp(format = "hh:mm:ss", wtime) - return time2text(station_time(wtime), format, NO_TIMEZONE) - -/proc/station_time_debug(force_set) - if(isnum(force_set)) - SSticker.gametime_offset = force_set - return - SSticker.gametime_offset = rand(0, 24 HOURS) //hours in day * minutes in hour * seconds in minute * deciseconds in second - if(prob(50)) - SSticker.gametime_offset = FLOOR(SSticker.gametime_offset, 1 HOURS) - else - SSticker.gametime_offset = CEILING(SSticker.gametime_offset, 1 HOURS) - ///returns timestamp in a sql and a not-quite-compliant ISO 8601 friendly format. Do not use for SQL, use NOW() instead /proc/ISOtime(timevar) return time2text(timevar || world.timeofday, "YYYY-MM-DD hh:mm:ss", world.timezone) @@ -128,7 +112,7 @@ GLOBAL_VAR_INIT(rollovercheck_last_timeofday, 0) * the format arg is the format passed down to time2text() (e.g. "hh:mm" is hours and minutes but not seconds). * the timezone is the time value offset from the local time. It's to be applied outside time2text() to get the AM/PM right. */ -/proc/time_to_twelve_hour(time, format = "hh:mm:ss", timezone = TIMEZONE_UTC) +/proc/time_to_twelve_hour(format = "hh:mm:ss", time = STATION_TIME_PASSED(), timezone = NO_TIMEZONE) time = MODULUS(time + (timezone * (1 HOURS)), 24 HOURS) var/am_pm = "AM" if(time > 12 HOURS) @@ -137,4 +121,5 @@ GLOBAL_VAR_INIT(rollovercheck_last_timeofday, 0) time -= 12 HOURS // e.g. 4:16 PM but not 00:42 PM else if (time < 1 HOURS) time += 12 HOURS // e.g. 12.23 AM - return "[time2text(time, format)] [am_pm]" + //set NO_TIMEZONE because we've already applied the timezone above. + return "[time2text(time, format, NO_TIMEZONE)] [am_pm]" diff --git a/code/__HELPERS/turfs.dm b/code/__HELPERS/turfs.dm index 764fc79621a..e7853ea5b32 100644 --- a/code/__HELPERS/turfs.dm +++ b/code/__HELPERS/turfs.dm @@ -551,3 +551,31 @@ Turf and target are separate in case you want to teleport some distance from a t if(turf_adjacent.planetary_atmos) return TRUE return FALSE + +/** + * Check if the turf has access to the sun, by checking for opaque turfs in the direction of the sun. + * + * occlusion_distance - determines how far away we check to see if the sun is blocked + * + * Returns TRUE if the sun is blocked + * Returns FALSE otherwise + */ +/turf/proc/is_sunlight_blocked(occlusion_distance = 20) + if(HAS_TRAIT(src, TRAIT_TURF_SUN_BLOCKED)) + return TRUE + + var/target_x = round(sin(SSsun.azimuth), 0.01) + var/target_y = round(cos(SSsun.azimuth), 0.01) + var/x_hit = x + var/y_hit = y + var/turf/hit + for(var/run in 1 to occlusion_distance) + x_hit += target_x + y_hit += target_y + hit = locate(round(x_hit, 1), round(y_hit, 1), z) + if(IS_OPAQUE_TURF(hit)) + return TRUE + if(hit.x == 1 || hit.x == world.maxx || hit.y == 1 || hit.y == world.maxy) // edge of the map + break + + return FALSE diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index 4b8e02699f8..ccb1945a924 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -342,27 +342,12 @@ GLOBAL_LIST_INIT(modulo_angle_to_dir, list(NORTH,NORTHEAST,EAST,SOUTHEAST,SOUTH, return "#ffffffff" return rgb(the_matrix[1]*255, the_matrix[6]*255, the_matrix[11]*255, the_matrix[16]*255) -/proc/type2parent(child) - var/string_type = "[child]" - var/last_slash = findlasttext(string_type, "/") - if(last_slash == 1) - switch(child) - if(/datum) - return null - if(/obj, /mob) - return /atom/movable - if(/area, /turf) - return /atom - else - return /datum - return text2path(copytext(string_type, 1, last_slash)) - //returns a string the last bit of a type, without the preceeding '/' -/proc/type2top(the_type) +/proc/type2top(datum/typepath) //handle the builtins manually - if(!ispath(the_type)) + if(!ispath(typepath)) return - switch(the_type) + switch(typepath) if(/datum) return "datum" if(/atom) @@ -376,7 +361,7 @@ GLOBAL_LIST_INIT(modulo_angle_to_dir, list(NORTH,NORTHEAST,EAST,SOUTHEAST,SOUTH, if(/turf) return "turf" else //regex everything else (works for /proc too) - return LOWER_TEXT(replacetext("[the_type]", "[type2parent(the_type)]/", "")) + return LOWER_TEXT(replacetext("[typepath]", "[typepath::parent_type]/", "")) /// Return html to load a url. /// for use inside of browse() calls to html assets that might be loaded on a cdn. diff --git a/code/__HELPERS/visual_effects.dm b/code/__HELPERS/visual_effects.dm index c8720ba46ee..76bc1c9f066 100644 --- a/code/__HELPERS/visual_effects.dm +++ b/code/__HELPERS/visual_effects.dm @@ -93,9 +93,24 @@ /// So transparent, blue, with a scanline and an emissive glow /// This is acomplished using a combination of filters and render steps/overlays /// The degree of the opacity is optional, based off the opacity arg (0 -> 1) -/atom/proc/makeHologram(opacity = 0.5) +/// An optional color_override replaces the default blue tint — either a hex string (opacity applied on top) or a color matrix/list (passed through as-is; caller owns its own alpha) +/// Returns the glow mutable_appearance so callers can cut the overlay later +/atom/proc/makeHologram(opacity = 0.5, color_override) // First, we'll make things blue (roughly) and sorta transparent - add_filter("HOLO: Color and Transparent", 1, color_matrix_filter(rgb(125,180,225, opacity * 255))) + var/color_value + if(islist(color_override)) + color_value = color_override + else + var/r = 125 + var/g = 180 + var/b = 225 + if(color_override) + var/list/rgb_list = rgb2num(color_override) + r = rgb_list[1] + g = rgb_list[2] + b = rgb_list[3] + color_value = rgb(r, g, b, opacity * 255) + add_filter("HOLO: Color and Transparent", 1, color_matrix_filter(color_value)) // Now we're gonna do a scanline effect // Gonna take this atom and give it a render target, then use it as a source for a filter // (We use an atom because it seems as if setting render_target on an MA is just invalid. I hate this engine) @@ -128,3 +143,4 @@ var/mutable_appearance/glow_appearance = new(glow) add_overlay(glow_appearance) LAZYADD(update_overlays_on_z, glow_appearance) + return glow_appearance diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index d7c681c7e64..c1795d715cd 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -27,6 +27,18 @@ GLOBAL_LIST_INIT(bitfields, generate_bitfields()) var/name = pick(flags) return flags[name] +/// Returns null if no such field exists, a list of all matching flags by name otherwise +/proc/get_matching_bitflags(var_name, value) + var/list/valid_bitflags = get_valid_bitflags(var_name) + if(!length(valid_bitflags)) + return null + + var/list/flags = list() + for (var/bit_name in valid_bitflags) + if (value & valid_bitflags[bit_name]) + flags += bit_name + return flags + DEFINE_BITFIELD(admin_flags, list( "ADMIN" = R_ADMIN, "AUTOLOGIN" = R_AUTOADMIN, @@ -217,6 +229,7 @@ DEFINE_BITFIELD(interaction_flags_item, list( DEFINE_BITFIELD(item_flags, list( "ABSTRACT" = ABSTRACT, "BEING_REMOVED" = BEING_REMOVED, + "BLUESPACE_INTERFERENCE" = BLUESPACE_INTERFERENCE, "CRUEL_IMPLEMENT" = CRUEL_IMPLEMENT, "DROPDEL" = DROPDEL, "FORCE_STRING_OVERRIDE" = FORCE_STRING_OVERRIDE, diff --git a/code/_globalvars/layers.dm b/code/_globalvars/layers.dm new file mode 100644 index 00000000000..e90c38756d5 --- /dev/null +++ b/code/_globalvars/layers.dm @@ -0,0 +1,190 @@ +GLOBAL_LIST_INIT(admin_readable_planes, list( + "FLOAT_PLANE" = FLOAT_PLANE, + "FIELD_OF_VISION_BLOCKER_PLANE" = FIELD_OF_VISION_BLOCKER_PLANE, + "CLICKCATCHER_PLANE" = CLICKCATCHER_PLANE, + "PLANE_SPACE" = PLANE_SPACE, + "PLANE_SPACE_PARALLAX" = PLANE_SPACE_PARALLAX, + "DISPLACEMENT_PLANE" = DISPLACEMENT_PLANE, + "RENDER_PLANE_TRANSPARENT" = RENDER_PLANE_TRANSPARENT, + "TRANSPARENT_FLOOR_PLANE" = TRANSPARENT_FLOOR_PLANE, + "FLOOR_PLANE" = FLOOR_PLANE, + "WALL_PLANE" = WALL_PLANE, + "GAME_PLANE" = GAME_PLANE, + "ABOVE_GAME_PLANE" = ABOVE_GAME_PLANE, + "SEETHROUGH_PLANE" = SEETHROUGH_PLANE, + "RENDER_PLANE_GAME_WORLD" = RENDER_PLANE_GAME_WORLD, + "DEFAULT_PLANE" = DEFAULT_PLANE, + "WEATHER_PLANE" = WEATHER_PLANE, + "AREA_PLANE" = AREA_PLANE, + "MASSIVE_OBJ_PLANE" = MASSIVE_OBJ_PLANE, + "GHOST_PLANE" = GHOST_PLANE, + "POINT_PLANE" = POINT_PLANE, + "LIGHTING_PLANE" = LIGHTING_PLANE, + "O_LIGHTING_VISUAL_PLANE" = O_LIGHTING_VISUAL_PLANE, + "RENDER_PLANE_TURF_LIGHTING" = RENDER_PLANE_TURF_LIGHTING, + "EMISSIVE_PLANE" = EMISSIVE_PLANE, + "RENDER_PLANE_EMISSIVE" = RENDER_PLANE_EMISSIVE, + "RENDER_PLANE_EMISSIVE_BLOOM_MASK" = RENDER_PLANE_EMISSIVE_BLOOM_MASK, + "RENDER_PLANE_EMISSIVE_BLOOM" = RENDER_PLANE_EMISSIVE_BLOOM, + "RENDER_PLANE_SPECULAR_MASK" = RENDER_PLANE_SPECULAR_MASK, + "RENDER_PLANE_UNLIT_GAME" = RENDER_PLANE_UNLIT_GAME, + "RENDER_PLANE_LIGHTING" = RENDER_PLANE_LIGHTING, + "RENDER_PLANE_LIGHT_MASK" = RENDER_PLANE_LIGHT_MASK, + "RENDER_PLANE_SPECULAR" = RENDER_PLANE_SPECULAR, + "ABOVE_LIGHTING_PLANE" = ABOVE_LIGHTING_PLANE, + "WEATHER_GLOW_PLANE" = WEATHER_GLOW_PLANE, + "PIPECRAWL_IMAGES_PLANE" = PIPECRAWL_IMAGES_PLANE, + "CAMERA_STATIC_PLANE" = CAMERA_STATIC_PLANE, + "HIGH_GAME_PLANE" = HIGH_GAME_PLANE, + "FULLSCREEN_PLANE" = FULLSCREEN_PLANE, + "RUNECHAT_PLANE" = RUNECHAT_PLANE, + "BALLOON_CHAT_PLANE" = BALLOON_CHAT_PLANE, + "HUD_PLANE" = HUD_PLANE, + "ABOVE_HUD_PLANE" = ABOVE_HUD_PLANE, + "SPLASHSCREEN_PLANE" = SPLASHSCREEN_PLANE, + "RENDER_PLANE_GAME" = RENDER_PLANE_GAME, + "RENDER_PLANE_GAME_MASKED" = RENDER_PLANE_GAME_MASKED, + "RENDER_PLANE_GAME_UNMASKED" = RENDER_PLANE_GAME_UNMASKED, + "RENDER_PLANE_NON_GAME" = RENDER_PLANE_NON_GAME, + "ESCAPE_MENU_PLANE" = ESCAPE_MENU_PLANE, + "RENDER_PLANE_MASTER" = RENDER_PLANE_MASTER +)) + +GLOBAL_LIST_INIT(admin_readable_layers, list( + "FLOAT_LAYER" = FLOAT_LAYER, + "SPACE_LAYER" = SPACE_LAYER, + // Topdown layers + "TOPDOWN_LAYER" = TOPDOWN_LAYER, + "LOWER_FLOOR_LAYER (Topdown)" = LOWER_FLOOR_LAYER, + "LOW_FLOOR_LAYER (Topdown)" = LOW_FLOOR_LAYER, + "TURF_PLATING_DECAL_LAYER (Topdown)" = TURF_PLATING_DECAL_LAYER, + "TURF_DECAL_LAYER (Topdown)" = TURF_DECAL_LAYER, + "CULT_OVERLAY_LAYER (Topdown)" = CULT_OVERLAY_LAYER, + "MID_TURF_LAYER (Topdown)" = MID_TURF_LAYER, + "HIGH_TURF_LAYER (Topdown)" = HIGH_TURF_LAYER, + "LATTICE_LAYER (Topdown)" = LATTICE_LAYER, + "DISPOSAL_PIPE_LAYER (Topdown)" = DISPOSAL_PIPE_LAYER, + "WIRE_LAYER (Topdown)" = WIRE_LAYER, + "BELOW_CATWALK_LAYER (Topdown)" = BELOW_CATWALK_LAYER, + "GLASS_FLOOR_LAYER (Topdown)" = GLASS_FLOOR_LAYER, + "CATWALK_LAYER (Topdown)" = CATWALK_LAYER, + "TRAM_RAIL_LAYER (Topdown)" = TRAM_RAIL_LAYER, + "ABOVE_OPEN_TURF_LAYER (Topdown)" = ABOVE_OPEN_TURF_LAYER, + "LOWER_RUNE_LAYER (Topdown)" = LOWER_RUNE_LAYER, + "RUNE_LAYER (Topdown)" = RUNE_LAYER, + "CLEANABLE_FLOOR_OBJECT_LAYER (Topdown)" = CLEANABLE_FLOOR_OBJECT_LAYER, + "TOPDOWN_WATER_LEVEL_LAYER (Topdown)" = TOPDOWN_WATER_LEVEL_LAYER, + "TOPDOWN_ABOVE_WATER_LAYER (Topdown)" = TOPDOWN_ABOVE_WATER_LAYER, + // Game layers + "BELOW_CLOSED_TURF_LAYER" = BELOW_CLOSED_TURF_LAYER, + "CLOSED_TURF_LAYER" = CLOSED_TURF_LAYER, + "BULLET_HOLE_LAYER" = BULLET_HOLE_LAYER, + "ABOVE_NORMAL_TURF_LAYER" = ABOVE_NORMAL_TURF_LAYER, + "FLOOR_EMISSIVE_START_LAYER" = FLOOR_EMISSIVE_START_LAYER, + "FLOOR_EMISSIVE_END_LAYER" = FLOOR_EMISSIVE_END_LAYER, + "GAS_PIPE_HIDDEN_LAYER" = GAS_PIPE_HIDDEN_LAYER, + "WIRE_BRIDGE_LAYER" = WIRE_BRIDGE_LAYER, + "WIRE_TERMINAL_LAYER" = WIRE_TERMINAL_LAYER, + "GAS_SCRUBBER_LAYER" = GAS_SCRUBBER_LAYER, + "GAS_PIPE_VISIBLE_LAYER" = GAS_PIPE_VISIBLE_LAYER, + "GAS_FILTER_LAYER" = GAS_FILTER_LAYER, + "GAS_PUMP_LAYER" = GAS_PUMP_LAYER, + "PLUMBING_PIPE_VISIBILE_LAYER" = PLUMBING_PIPE_VISIBILE_LAYER, + "BOT_PATH_LAYER" = BOT_PATH_LAYER, + "LOW_OBJ_LAYER" = LOW_OBJ_LAYER, + "HIGH_PIPE_LAYER" = HIGH_PIPE_LAYER, + "CLEANABLE_OBJECT_LAYER" = CLEANABLE_OBJECT_LAYER, + "TRAM_STRUCTURE_LAYER" = TRAM_STRUCTURE_LAYER, + "TRAM_FLOOR_LAYER" = TRAM_FLOOR_LAYER, + "TRAM_WALL_LAYER" = TRAM_WALL_LAYER, + "BELOW_OPEN_DOOR_LAYER" = BELOW_OPEN_DOOR_LAYER, + "WATER_LEVEL_LAYER" = WATER_LEVEL_LAYER, + "BLASTDOOR_LAYER" = BLASTDOOR_LAYER, + "OPEN_DOOR_LAYER" = OPEN_DOOR_LAYER, + "DOOR_ACCESS_HELPER_LAYER" = DOOR_ACCESS_HELPER_LAYER, + "DOOR_HELPER_LAYER" = DOOR_HELPER_LAYER, + "PROJECTILE_HIT_THRESHHOLD_LAYER" = PROJECTILE_HIT_THRESHHOLD_LAYER, + "TABLE_LAYER" = TABLE_LAYER, + "GIB_LAYER" = GIB_LAYER, + "BELOW_OBJ_LAYER" = BELOW_OBJ_LAYER, + "LOW_ITEM_LAYER" = LOW_ITEM_LAYER, + "OBJ_LAYER" = OBJ_LAYER, + "CLOSED_DOOR_LAYER" = CLOSED_DOOR_LAYER, + "CLOSED_FIREDOOR_LAYER" = CLOSED_FIREDOOR_LAYER, + "ABOVE_OBJ_LAYER" = ABOVE_OBJ_LAYER, + "CLOSED_BLASTDOOR_LAYER" = CLOSED_BLASTDOOR_LAYER, + "SHUTTER_LAYER" = SHUTTER_LAYER, + "ABOVE_WINDOW_LAYER" = ABOVE_WINDOW_LAYER, + "SIGN_LAYER" = SIGN_LAYER, + "CORGI_ASS_PIN_LAYER" = CORGI_ASS_PIN_LAYER, + "NOT_HIGH_OBJ_LAYER" = NOT_HIGH_OBJ_LAYER, + "HIGH_OBJ_LAYER" = HIGH_OBJ_LAYER, + "BELOW_MOB_LAYER" = BELOW_MOB_LAYER, + "LOW_MOB_LAYER" = LOW_MOB_LAYER, + "LYING_MOB_LAYER" = LYING_MOB_LAYER, + "ABOVE_LYING_MOB_LAYER" = ABOVE_LYING_MOB_LAYER, + "VEHICLE_LAYER" = VEHICLE_LAYER, + "MOB_BELOW_PIGGYBACK_LAYER" = MOB_BELOW_PIGGYBACK_LAYER, + "MOB_LAYER" = MOB_LAYER, + "MOB_SHIELD_LAYER" = MOB_SHIELD_LAYER, + "MOB_ABOVE_PIGGYBACK_LAYER" = MOB_ABOVE_PIGGYBACK_LAYER, + "MOB_UPPER_LAYER" = MOB_UPPER_LAYER, + "HITSCAN_PROJECTILE_LAYER" = HITSCAN_PROJECTILE_LAYER, + "ABOVE_MOB_LAYER" = ABOVE_MOB_LAYER, + "WALL_OBJ_LAYER" = WALL_OBJ_LAYER, + "TRAM_SIGNAL_LAYER" = TRAM_SIGNAL_LAYER, + "EDGED_TURF_LAYER" = EDGED_TURF_LAYER, + "ON_EDGED_TURF_LAYER" = ON_EDGED_TURF_LAYER, + "SPACEVINE_LAYER" = SPACEVINE_LAYER, + "LARGE_MOB_LAYER" = LARGE_MOB_LAYER, + "SPACEVINE_MOB_LAYER" = SPACEVINE_MOB_LAYER, + "ABOVE_ALL_MOB_LAYER" = ABOVE_ALL_MOB_LAYER, + "NAVIGATION_EYE_LAYER" = NAVIGATION_EYE_LAYER, + "FLY_LAYER" = FLY_LAYER, + "ABOVE_TREE_LAYER" = ABOVE_TREE_LAYER, + "GASFIRE_LAYER" = GASFIRE_LAYER, + "RIPPLE_LAYER" = RIPPLE_LAYER, + // LIGHTING_PLANE layers + "LIGHTING_MASK_LAYER" = LIGHTING_MASK_LAYER, + "LIGHTING_PRIMARY_LAYER" = LIGHTING_PRIMARY_LAYER, + "LIGHTING_ABOVE_ALL" = LIGHTING_ABOVE_ALL, + "EMISSIVE_LAYER_UNBLOCKABLE" = EMISSIVE_LAYER_UNBLOCKABLE, + // Mob layers + "MUTATIONS_LAYER" = -MUTATIONS_LAYER, + "BODY_BEHIND_LAYER" = -BODY_BEHIND_LAYER, + "BODYPARTS_LOW_LAYER" = -BODYPARTS_LOW_LAYER, + "BODYPARTS_LAYER" = -BODYPARTS_LAYER, + "BODY_ADJ_LAYER" = -BODY_ADJ_LAYER, + "BODY_LAYER" = -BODY_LAYER, + "EYES_LAYER" = -EYES_LAYER, + "FRONT_MUTATIONS_LAYER" = -FRONT_MUTATIONS_LAYER, + "DAMAGE_LAYER" = -DAMAGE_LAYER, + "UNIFORM_LAYER" = -UNIFORM_LAYER, + "ID_LAYER" = -ID_LAYER, + "ID_CARD_LAYER" = -ID_CARD_LAYER, + "BODYPARTS_HIGH_LAYER" = -BODYPARTS_HIGH_LAYER, + "GLOVES_LAYER" = -GLOVES_LAYER, + "SHOES_LAYER" = -SHOES_LAYER, + "LOW_FACEMASK_LAYER" = -LOW_FACEMASK_LAYER, + "EARS_LAYER" = -EARS_LAYER, + "LOW_NECK_LAYER" = -LOW_NECK_LAYER, + "SUIT_LAYER" = -SUIT_LAYER, + "GLASSES_LAYER" = -GLASSES_LAYER, + "BELT_LAYER" = -BELT_LAYER, + "SUIT_STORE_LAYER" = -SUIT_STORE_LAYER, + "NECK_LAYER" = -NECK_LAYER, + "BACK_LAYER" = -BACK_LAYER, + "BENEATH_HAIR_LAYER" = -BENEATH_HAIR_LAYER, + "HAIR_LAYER" = -HAIR_LAYER, + "FACEMASK_LAYER" = -FACEMASK_LAYER, + "HEAD_LAYER" = -HEAD_LAYER, + "OUTER_HAIR_LAYER" = -OUTER_HAIR_LAYER, + "HANDCUFF_LAYER" = -HANDCUFF_LAYER, + "LEGCUFF_LAYER" = -LEGCUFF_LAYER, + "HANDS_LAYER" = -HANDS_LAYER, + "BODY_FRONT_LAYER" = -BODY_FRONT_LAYER, + "ABOVE_BODY_FRONT_GLASSES_LAYER" = -ABOVE_BODY_FRONT_GLASSES_LAYER, + "ABOVE_BODY_FRONT_HEAD_LAYER" = -ABOVE_BODY_FRONT_HEAD_LAYER, + "WOUND_LAYER" = -WOUND_LAYER, + "HALO_LAYER" = -HALO_LAYER, +)) diff --git a/code/_globalvars/lists/maintenance_loot.dm b/code/_globalvars/lists/maintenance_loot.dm index ee9191f6389..397120b9221 100644 --- a/code/_globalvars/lists/maintenance_loot.dm +++ b/code/_globalvars/lists/maintenance_loot.dm @@ -320,7 +320,7 @@ GLOBAL_LIST_INIT(rarity_loot, list(//rare: really good items /obj/item/weldingtool/hugetank = 1, /obj/item/fishing_rod/telescopic/master = 1, /obj/item/spess_knife = 1, - /obj/item/gun/ballistic/automatic/pistol/doorhickey = 1, + /obj/item/gun/ballistic/automatic/pistol/doohickey = 1, ) = 1, list(//equipment @@ -352,11 +352,15 @@ GLOBAL_LIST_INIT(rarity_loot, list(//rare: really good items /obj/item/storage/medkit/emergency = 1, /obj/item/storage/medkit/regular = 1, /obj/item/storage/box/bandages = 1, - ) = 1, + ) = 2, list(//medical chems /obj/item/reagent_containers/hypospray/medipen/oxandrolone = 1, /obj/item/reagent_containers/hypospray/medipen/salacid = 1, /obj/item/reagent_containers/syringe/contraband/methamphetamine = 1, + ) = 2, + list( + /obj/item/paper/secretrecipe/gorgium = 1, + /obj/item/paper/secretrecipe/metalgen = 1, ) = 1, ) = 1, diff --git a/code/_globalvars/lists/mapping.dm b/code/_globalvars/lists/mapping.dm index 0f1eebb3347..7264922bfce 100644 --- a/code/_globalvars/lists/mapping.dm +++ b/code/_globalvars/lists/mapping.dm @@ -126,9 +126,6 @@ GLOBAL_LIST_EMPTY(jobspawn_overrides) GLOBAL_LIST_EMPTY(gorilla_start) GLOBAL_LIST_EMPTY(wizardstart) -GLOBAL_LIST_EMPTY(nukeop_start) -GLOBAL_LIST_EMPTY(nukeop_leader_start) -GLOBAL_LIST_EMPTY(nukeop_overwatch_start) GLOBAL_LIST_EMPTY(newplayer_start) GLOBAL_LIST_EMPTY(prisonwarp) //admin prisoners go to these GLOBAL_LIST_EMPTY(holdingfacility) //captured people go here (ninja energy net) @@ -145,7 +142,9 @@ GLOBAL_LIST_EMPTY(deathsquadspawn) GLOBAL_LIST_EMPTY(emergencyresponseteamspawn) GLOBAL_LIST_EMPTY(ruin_landmarks) GLOBAL_LIST_EMPTY(bar_areas) +GLOBAL_LIST_EMPTY(river_waypoint_list) // Assoc list of river waypoint markers by z-level GLOBAL_LIST_EMPTY(mining_center) // For determining vent size ranked lists, epicenters for comparison goes here. +GLOBAL_LIST_EMPTY(map_generators_by_z) // Assoc list of shared generators by z by type /// List of all the maps that have been cached for /proc/load_map GLOBAL_LIST_EMPTY(cached_maps) @@ -170,22 +169,6 @@ GLOBAL_LIST_INIT(megafauna_spawn_list, list( /mob/living/simple_animal/hostile/megafauna/dragon = 4, )) -/// List of how many minerals spawned based on proximity to an ore vent. -GLOBAL_LIST_INIT(post_ore_random, list( - "[ORE_WALL_FAR]" = 0, - "[ORE_WALL_LOW]" = 0, - "[ORE_WALL_MEDIUM]" = 0, - "[ORE_WALL_HIGH]" = 0, - "[ORE_WALL_VERY_HIGH]" = 0, -)) -/// List of how many minerals spawned randomly off of mining Z-levels, and at what quantity. -GLOBAL_LIST_INIT(post_ore_manual, list( - "[ORE_WALL_FAR]" = 0, - "[ORE_WALL_LOW]" = 0, - "[ORE_WALL_MEDIUM]" = 0, - "[ORE_WALL_HIGH]" = 0, - "[ORE_WALL_VERY_HIGH]" = 0, -)) /// List of how many ore vents spawned, and of what size. GLOBAL_LIST_INIT(ore_vent_sizes, list( LARGE_VENT_TYPE = 0, diff --git a/code/_globalvars/lists/ores_spawned.dm b/code/_globalvars/lists/ores_spawned.dm index 227e06061ad..a6a9654f823 100644 --- a/code/_globalvars/lists/ores_spawned.dm +++ b/code/_globalvars/lists/ores_spawned.dm @@ -9,27 +9,23 @@ */ GLOBAL_LIST_INIT(ore_vent_minerals_lavaland, list( - /datum/material/iron = 13, - /datum/material/glass = 12, - /datum/material/plasma = 9, + /datum/material/iron = 14, + /datum/material/glass = 13, + /datum/material/plasma = 10, + /datum/material/silver = 7, /datum/material/titanium = 6, - /datum/material/silver = 5, /datum/material/gold = 5, - /datum/material/diamond = 3, - /datum/material/uranium = 3, - /datum/material/bluespace = 3, + /datum/material/uranium = 4, /datum/material/plastic = 1, )) GLOBAL_LIST_INIT(ore_vent_minerals_triple_z, list( - /datum/material/iron = 24, - /datum/material/glass = 23, - /datum/material/plasma = 16, + /datum/material/iron = 25, + /datum/material/glass = 24, + /datum/material/plasma = 17, /datum/material/titanium = 10, - /datum/material/silver = 8, - /datum/material/gold = 7, - /datum/material/diamond = 4, - /datum/material/uranium = 4, - /datum/material/bluespace = 3, + /datum/material/silver = 10, + /datum/material/gold = 8, + /datum/material/uranium = 5, /datum/material/plastic = 1, )) diff --git a/code/_globalvars/lists/poll_ignore.dm b/code/_globalvars/lists/poll_ignore.dm index 9cf601e2d66..8f1c3f242e5 100644 --- a/code/_globalvars/lists/poll_ignore.dm +++ b/code/_globalvars/lists/poll_ignore.dm @@ -38,6 +38,7 @@ #define POLL_IGNORE_SPLITPERSONALITY "split_personality" #define POLL_IGNORE_STALKER "stalker" #define POLL_IGNORE_SYNDICATE "syndicate" +#define POLL_IGNORE_SYNDICATE_MONKEY "syndicate_monkey" #define POLL_IGNORE_VENUSHUMANTRAP "venus_human_trap" #define POLL_IGNORE_RECOVERED_CREW "recovered_crew" #define POLL_IGNORE_EXPERIMENTAL_CLONER "experimental_cloner" @@ -81,6 +82,7 @@ GLOBAL_LIST_INIT(poll_ignore_desc, list( POLL_IGNORE_SPLITPERSONALITY = "Split Personality", POLL_IGNORE_STALKER = "Stalker", POLL_IGNORE_SYNDICATE = "Syndicate", + POLL_IGNORE_SYNDICATE_MONKEY = "Syndicate Monkey", POLL_IGNORE_VENUSHUMANTRAP = "Venus Human Traps", POLL_IGNORE_RECOVERED_CREW = "Recovered Crew", POLL_IGNORE_FREE_SPORE = "Free spore", diff --git a/code/_globalvars/lists/reagents.dm b/code/_globalvars/lists/reagents.dm index 203d685c5e3..c53895bfdbe 100644 --- a/code/_globalvars/lists/reagents.dm +++ b/code/_globalvars/lists/reagents.dm @@ -150,7 +150,7 @@ GLOBAL_LIST_INIT(stacked_metabolization_effect, init_chemical_side_effects()) if(ispath(reaction, /datum/chemical_reaction/randomized)) var/target_path = reaction var/index = reactions.Find(reaction) - reaction = new target_path(json) + reaction = new target_path(LAZYACCESS(json, "[target_path]")) //failed to init if(QDELETED(reaction)) diff --git a/code/_globalvars/phobias.dm b/code/_globalvars/phobias.dm index 77b4c497418..1ad6b608acf 100644 --- a/code/_globalvars/phobias.dm +++ b/code/_globalvars/phobias.dm @@ -66,7 +66,7 @@ GLOBAL_LIST_INIT(phobia_mobs, list( )), "authority" = typecacheof(list( /mob/living/basic/trooper/nanotrasen, - /mob/living/simple_animal/bot/secbot, + /mob/living/basic/bot/secbot, )), "birds" = typecacheof(list( /mob/living/basic/chick, @@ -79,7 +79,7 @@ GLOBAL_LIST_INIT(phobia_mobs, list( "conspiracies" = typecacheof(list( /mob/living/basic/drone, /mob/living/basic/pet/penguin, - /mob/living/simple_animal/bot/secbot, + /mob/living/basic/bot/secbot, )), "doctors" = typecacheof(list(/mob/living/basic/bot/medbot)), "fish" = typecacheof(list( @@ -102,7 +102,7 @@ GLOBAL_LIST_INIT(phobia_mobs, list( /mob/living/silicon/robot, /mob/living/simple_animal/bot, )), - "security" = typecacheof(list(/mob/living/simple_animal/bot/secbot)), + "security" = typecacheof(list(/mob/living/basic/bot/secbot)), "spiders" = typecacheof(list( /mob/living/basic/flesh_spider, /mob/living/basic/mega_arachnid, diff --git a/code/_globalvars/tgui.dm b/code/_globalvars/tgui.dm index a81078420f5..8bcd00cdb78 100644 --- a/code/_globalvars/tgui.dm +++ b/code/_globalvars/tgui.dm @@ -2,3 +2,4 @@ GLOBAL_DATUM(crew_manifest_tgui, /datum/crew_manifest) GLOBAL_DATUM(changelog_tgui, /datum/changelog) GLOBAL_DATUM(hotkeys_tgui, /datum/hotkeys_help) GLOBAL_DATUM(record_manifest_tgui, /datum/record_manifest) //SKYRAT EDIT ADDITION -- EXPLOITABLE VERB +GLOBAL_DATUM(emote_panel, /datum/emote_panel) diff --git a/code/_globalvars/time_vars.dm b/code/_globalvars/time_vars.dm index fd9b925e0d4..a006a4bc699 100644 --- a/code/_globalvars/time_vars.dm +++ b/code/_globalvars/time_vars.dm @@ -1,6 +1,3 @@ -/// The difference betwen midnight (of the host computer) and 0 world.ticks. -GLOBAL_VAR_INIT(timezoneOffset, 0) - -GLOBAL_VAR_INIT(year, UTC_YEAR) +GLOBAL_VAR_INIT(year, time2text(world.timeofday, "YYYY", TIMEZONE_UTC)) GLOBAL_VAR_INIT(year_integer, text2num(year)) // = 2013??? diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 4fb12fd9d68..f25740bc9c1 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -58,6 +58,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_HAS_LABEL" = TRAIT_HAS_LABEL, "TRAIT_HEARING_SENSITIVE" = TRAIT_HEARING_SENSITIVE, "TRAIT_HYPERSPACED" = TRAIT_HYPERSPACED, + "TRAIT_IGNORE_DEMOLITION" = TRAIT_IGNORE_DEMOLITION, "TRAIT_IMMERSED" = TRAIT_IMMERSED, "TRAIT_INVERTED_DEMOLITION" = TRAIT_INVERTED_DEMOLITION, "TRAIT_IRRADIATED" = TRAIT_IRRADIATED, @@ -100,6 +101,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_STRONGPULL" = TRAIT_STRONGPULL, ), /area = list( + "TRAIT_AREA_BLOCK_POWER_FAIL" = TRAIT_AREA_BLOCK_POWER_FAIL, "TRAIT_HAS_SHUTTLE_CONSTRUCTION_TURF" = TRAIT_HAS_SHUTTLE_CONSTRUCTION_TURF, ), /datum/controller/global_vars = list( @@ -173,6 +175,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_ACT_AS_HERETIC" = TRAIT_ACT_AS_HERETIC, "TRAIT_ADAMANTINE_EXTRACT_ARMOR" = TRAIT_ADAMANTINE_EXTRACT_ARMOR, "TRAIT_ADDICTIONRESILIENT" = TRAIT_ADDICTIONRESILIENT, + "TRAIT_ADMIN_ESP" = TRAIT_ADMIN_ESP, "TRAIT_ADVANCEDTOOLUSER" = TRAIT_ADVANCEDTOOLUSER, "TRAIT_AGENDER" = TRAIT_AGENDER, "TRAIT_AGEUSIA" = TRAIT_AGEUSIA, @@ -192,6 +195,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_ANXIOUS" = TRAIT_ANXIOUS, "TRAIT_APATHETIC" = TRAIT_APATHETIC, "TRAIT_ATTEMPTING_CHRISTENING" = TRAIT_ATTEMPTING_CHRISTENING, + "TRAIT_BACKSTAB_IMMUNE" = TRAIT_BACKSTAB_IMMUNE, "TRAIT_BADDNA" = TRAIT_BADDNA, "TRAIT_BADTOUCH" = TRAIT_BADTOUCH, "TRAIT_BALD" = TRAIT_BALD, @@ -349,7 +353,6 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_HEAVY_DRINKER" = TRAIT_HEAVY_DRINKER, "TRAIT_HEAVY_SLEEPER" = TRAIT_HEAVY_SLEEPER, "TRAIT_HERETIC_SUMMON" = TRAIT_HERETIC_SUMMON, - "TRAIT_HERETICAL_DREAMS" = TRAIT_HERETICAL_DREAMS, "TRAIT_HIDE_EXTERNAL_ORGANS" = TRAIT_HIDE_EXTERNAL_ORGANS, "TRAIT_HIGH_VALUE_RANSOM" = TRAIT_HIGH_VALUE_RANSOM, "TRAIT_HOLY" = TRAIT_HOLY, @@ -405,6 +408,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_MIND_READER" = TRAIT_MIND_READER, "TRAIT_MINDSHIELD" = TRAIT_MINDSHIELD, "TRAIT_MIND_TEMPORARILY_GONE" = TRAIT_MIND_TEMPORARILY_GONE, + "TRAIT_MINING_AGGRO" = TRAIT_MINING_AGGRO, "TRAIT_MINOR_NIGHT_VISION" = TRAIT_MINOR_NIGHT_VISION, "TRAIT_FAKE_SOULLESS" = TRAIT_FAKE_SOULLESS, "TRAIT_MOB_BREEDER" = TRAIT_MOB_BREEDER, @@ -453,7 +457,6 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_NO_BLOOD_OVERLAY" = TRAIT_NO_BLOOD_OVERLAY, "TRAIT_NO_BREATHLESS_DAMAGE" = TRAIT_NO_BREATHLESS_DAMAGE, "TRAIT_NO_DAMAGE_OVERLAY" = TRAIT_NO_DAMAGE_OVERLAY, - "TRAIT_NO_DEBRAIN_OVERLAY" = TRAIT_NO_DEBRAIN_OVERLAY, "TRAIT_NO_DNA_COPY" = TRAIT_NO_DNA_COPY, "TRAIT_NO_DNA_SCRAMBLE" = TRAIT_NO_DNA_SCRAMBLE, "TRAIT_NO_EXTINGUISH" = TRAIT_NO_EXTINGUISH, @@ -598,6 +601,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_SUPERMATTER_SOOTHER" = TRAIT_SUPERMATTER_SOOTHER, "TRAIT_SURGICALLY_ANALYZED" = TRAIT_SURGICALLY_ANALYZED, "TRAIT_SWIMMER" = TRAIT_SWIMMER, + "TRAIT_SYNTHPAX_IMMUNE" = TRAIT_SYNTHPAX_IMMUNE, "TRAIT_TACKLING_FRAIL_ATTACKER" = TRAIT_TACKLING_FRAIL_ATTACKER, "TRAIT_TACKLING_TAILED_DEFENDER" = TRAIT_TACKLING_TAILED_DEFENDER, "TRAIT_TACKLING_TAILED_POUNCE" = TRAIT_TACKLING_TAILED_POUNCE, @@ -803,8 +807,8 @@ GLOBAL_LIST_INIT(traits_by_type, list( /obj/item/organ = list( "TRAIT_CLIENT_STARTING_ORGAN" = TRAIT_CLIENT_STARTING_ORGAN, "TRAIT_LIVING_HEART" = TRAIT_LIVING_HEART, - "TRAIT_USED_ORGAN" = TRAIT_USED_ORGAN, "TRAIT_ORGAN_OPERATED_ON" = TRAIT_ORGAN_OPERATED_ON, + "TRAIT_ORGAN_USED_BY_PLAYER" = TRAIT_ORGAN_USED_BY_PLAYER, ), /obj/item/organ/brain = list( "TRAIT_BRAIN_DAMAGE_NODEATH" = TRAIT_BRAIN_DAMAGE_NODEATH, @@ -851,6 +855,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_SPINNING_WEB_TURF" = TRAIT_SPINNING_WEB_TURF, "TRAIT_TURF_IGNORE_SLIPPERY" = TRAIT_TURF_IGNORE_SLIPPERY, "TRAIT_TURF_IGNORE_SLOWDOWN" = TRAIT_TURF_IGNORE_SLOWDOWN, + "TRAIT_TURF_SUN_BLOCKED" = TRAIT_TURF_SUN_BLOCKED, "TRAIT_UNCOVERED_TURF" = TRAIT_UNCOVERED_TURF, ), // SKYRAT EDIT ADDITION START - SKYRAT TRAITS diff --git a/code/_globalvars/traits/admin_tooling.dm b/code/_globalvars/traits/admin_tooling.dm index 68624c84d48..702b9716cf5 100644 --- a/code/_globalvars/traits/admin_tooling.dm +++ b/code/_globalvars/traits/admin_tooling.dm @@ -20,6 +20,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_MOVE_PHASING" = TRAIT_MOVE_PHASING, "TRAIT_MOVE_VENTCRAWLING" = TRAIT_MOVE_VENTCRAWLING, "TRAIT_MOVE_UPSIDE_DOWN" = TRAIT_MOVE_UPSIDE_DOWN, + "TRAIT_NO_TELEPORT" = TRAIT_NO_TELEPORT, "TRAIT_RAINSTORM_IMMUNE" = TRAIT_RAINSTORM_IMMUNE, "TRAIT_RUNECHAT_HIDDEN" = TRAIT_RUNECHAT_HIDDEN, "TRAIT_SANDSTORM_IMMUNE" = TRAIT_SANDSTORM_IMMUNE, @@ -39,6 +40,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_ABDUCTOR_TRAINING" = TRAIT_ABDUCTOR_TRAINING, "TRAIT_ACT_AS_CULTIST" = TRAIT_ACT_AS_CULTIST, "TRAIT_ACT_AS_HERETIC" = TRAIT_ACT_AS_HERETIC, + "TRAIT_ADMIN_ESP" = TRAIT_ADMIN_ESP, "TRAIT_ADVANCEDTOOLUSER" = TRAIT_ADVANCEDTOOLUSER, "TRAIT_AGENDER" = TRAIT_AGENDER, "TRAIT_AGEUSIA" = TRAIT_AGEUSIA, @@ -147,7 +149,6 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_HATED_BY_DOGS" = TRAIT_HATED_BY_DOGS, "TRAIT_HEAVY_DRINKER" = TRAIT_HEAVY_DRINKER, "TRAIT_HEAVY_SLEEPER" = TRAIT_HEAVY_SLEEPER, - "TRAIT_HERETICAL_DREAMS" = TRAIT_HERETICAL_DREAMS, "TRAIT_HIDE_EXTERNAL_ORGANS" = TRAIT_HIDE_EXTERNAL_ORGANS, "TRAIT_HIGH_VALUE_RANSOM" = TRAIT_HIGH_VALUE_RANSOM, "TRAIT_HOLY" = TRAIT_HOLY, @@ -369,7 +370,6 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_GERM_SENSITIVE" = TRAIT_GERM_SENSITIVE, "TRAIT_HAUNTED" = TRAIT_HAUNTED, "TRAIT_NO_STORAGE_INSERT" = TRAIT_NO_STORAGE_INSERT, - "TRAIT_NO_TELEPORT" = TRAIT_NO_TELEPORT, "TRAIT_NODROP" = TRAIT_NODROP, "TRAIT_T_RAY_VISIBLE" = TRAIT_T_RAY_VISIBLE, "TRAIT_UNCATCHABLE" = TRAIT_UNCATCHABLE, @@ -416,7 +416,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( /obj/item/organ = list( "TRAIT_CLIENT_STARTING_ORGAN" = TRAIT_CLIENT_STARTING_ORGAN, "TRAIT_LIVING_HEART" = TRAIT_LIVING_HEART, - "TRAIT_USED_ORGAN" = TRAIT_USED_ORGAN, + "TRAIT_ORGAN_USED_BY_PLAYER" = TRAIT_ORGAN_USED_BY_PLAYER, ), /obj/item/organ/brain = list( "TRAIT_SPECIAL_TRAUMA_BOOST" = TRAIT_SPECIAL_TRAUMA_BOOST, diff --git a/code/_onclick/click_ctrl.dm b/code/_onclick/click_ctrl.dm index e80f8fa05cb..19c86970aee 100644 --- a/code/_onclick/click_ctrl.dm +++ b/code/_onclick/click_ctrl.dm @@ -41,7 +41,7 @@ if(grab(target) != GRAB_SKIP) changeNext_move(CLICK_CD_MELEE) return - pulled(target) + start_pulling(target) /** * Ctrl mouse wheel click diff --git a/code/_onclick/hud/alien.dm b/code/_onclick/hud/alien.dm index 50121d853a5..b1bd23a5301 100644 --- a/code/_onclick/hud/alien.dm +++ b/code/_onclick/hud/alien.dm @@ -30,17 +30,4 @@ add_screen_object(/atom/movable/screen/alien/leap, HUD_ALIEN_HUNTER_LEAP, HUD_GROUP_STATIC, ui_style) if(!isalienqueen(mymob)) - add_screen_object(/atom/movable/screen/alien/plasma_display, HUD_ALIEN_QUEEN_FINDER, HUD_GROUP_INFO) - -/datum/hud/alien/persistent_inventory_update() - if(!mymob) - return - var/mob/living/carbon/alien/adult/H = mymob - if(hud_version != HUD_STYLE_NOHUD) - for(var/obj/item/I in H.held_items) - I.screen_loc = ui_hand_position(H.get_held_index_of_item(I)) - H.client.screen += I - else - for(var/obj/item/I in H.held_items) - I.screen_loc = null - H.client.screen -= I + add_screen_object(/atom/movable/screen/alien/alien_queen_finder, HUD_ALIEN_QUEEN_FINDER, HUD_GROUP_INFO) diff --git a/code/_onclick/hud/drones.dm b/code/_onclick/hud/drones.dm index e7694d5d660..98335985040 100644 --- a/code/_onclick/hud/drones.dm +++ b/code/_onclick/hud/drones.dm @@ -1,22 +1,5 @@ /datum/hud/dextrous/drone - inventory_slots = /datum/inventory_slot/drone - -/datum/hud/dextrous/drone/persistent_inventory_update() - if(!mymob) - return - var/mob/living/basic/drone/drone = mymob - - if(hud_shown) - if(!isnull(drone.internal_storage)) - drone.internal_storage.screen_loc = ui_drone_storage - drone.client.screen += drone.internal_storage - if(!isnull(drone.head)) - drone.head.screen_loc = ui_drone_head - drone.client.screen += drone.head - else - drone.internal_storage?.screen_loc = null - drone.head?.screen_loc = null - ..() + default_inventory_slots = /datum/inventory_slot/drone /datum/inventory_slot/drone abstract_type = /datum/inventory_slot/drone diff --git a/code/_onclick/hud/generic_dextrous.dm b/code/_onclick/hud/generic_dextrous.dm index a0faa532533..a8dad62d835 100644 --- a/code/_onclick/hud/generic_dextrous.dm +++ b/code/_onclick/hud/generic_dextrous.dm @@ -28,17 +28,3 @@ if(HAS_TRAIT(mymob, TRAIT_CAN_THROW_ITEMS)) add_screen_object(/atom/movable/screen/throw_catch, HUD_MOB_THROW, HUD_GROUP_HOTKEYS, ui_style, ui_drop_throw) - -/datum/hud/dextrous/persistent_inventory_update() - if(!mymob) - return - var/mob/living/owner = mymob - if(hud_version != HUD_STYLE_NOHUD) - for(var/obj/item/held in owner.held_items) - held.screen_loc = ui_hand_position(owner.get_held_index_of_item(held)) - owner.client.screen += held - return - - for(var/obj/item/held in owner.held_items) - held.screen_loc = null - owner.client.screen -= held diff --git a/code/_onclick/hud/guardian.dm b/code/_onclick/hud/guardian.dm index 18b1b985ccb..883cd5ff8ba 100644 --- a/code/_onclick/hud/guardian.dm +++ b/code/_onclick/hud/guardian.dm @@ -7,33 +7,15 @@ ///Dextrous subtype for only dextrous holoparasites. Can hold things hence the inventory slot. /datum/hud/dextrous/guardian - inventory_slots = list(/datum/inventory_slot/guardian_storage) + default_inventory_slots = list(/datum/inventory_slot/guardian_storage) give_health_doll = FALSE /datum/hud/dextrous/guardian/initialize_screen_objects() . = ..() add_screen_object(/atom/movable/screen/healths/guardian, HUD_MOB_HEALTH, HUD_GROUP_INFO) -/datum/hud/dextrous/guardian/persistent_inventory_update() - if(!mymob) - return - - if(!istype(mymob, /mob/living/basic/guardian/dextrous)) - return ..() - - var/mob/living/basic/guardian/dextrous/dex_guardian = mymob - if(hud_shown) - if(dex_guardian.internal_storage) - dex_guardian.internal_storage.screen_loc = ui_back - dex_guardian.client.screen += dex_guardian.internal_storage - else - if(dex_guardian.internal_storage) - dex_guardian.internal_storage.screen_loc = null - return ..() - /datum/inventory_slot/guardian_storage name = "internal storage" icon_state = "suit_storage" slot_id = ITEM_SLOT_DEX_STORAGE screen_loc = ui_back - diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 39751b386cf..2d4bbb9b484 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -99,16 +99,15 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list( var/list/atom/movable/screen/screen_objects = list() /// List of screen objects by their screen group var/list/screen_groups[SCREEN_GROUP_AMT] - /// List of all inventory slot screen objects by their slot ID. Some slots are fake and will be missing from here! - var/list/inv_slots[SLOTS_AMT] - /// List of hand slot objects, kept separate from the rest of inventory as mobs can have varying amount of hands - var/list/atom/movable/screen/inventory/hand/hand_slots = null /// List of typepaths of /datum/inventory_slot which will be used to automatically create inventory slot UI elements /// If assigned a typepath instead of a list, it will instead use all valid subtypes of said typepath - /// Safe to change in initialize_screen_objects() but not later - var/list/inventory_slots = null var/erp_ui_style //SKYRAT EDIT - ADDITION - ERP ICONS FIX + /// Can be changed in initialize_screen_objects() to add/remove slots + var/list/datum/inventory_slot/default_inventory_slots = null + /// Alist of slot_id -> inventory_slot datum of our slots + /// These are singletons, do not modify individual slots! + var/list/datum/inventory_slot/inventory_slots = alist() /// List of weakrefs to objects that we add to our screen that we don't expect to DO anything /// They typically use * in their render target. They exist solely so we can reuse them, @@ -127,8 +126,6 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list( add_screen_object(/atom/movable/screen/palette_scroll/down, HUD_MOB_PALETTE_DOWN) add_screen_object(/atom/movable/screen/palette_scroll/up, HUD_MOB_PALETTE_UP) - hand_slots = list() - var/datum/plane_master_group/main/main_group = new(PLANE_GROUP_MAIN) main_group.attach_to(src) @@ -173,8 +170,7 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list( QDEL_LIST(floating_actions) screentip_text = null screen_groups = null - inv_slots.Cut() - hand_slots.Cut() + inventory_slots.Cut() QDEL_LIST_ASSOC_VAL(screen_objects) QDEL_LIST_ASSOC_VAL(master_groups) QDEL_LIST_ASSOC_VAL(plane_master_controllers) @@ -392,7 +388,8 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list( screenmob.client.screen += group_hotkeys if (length(group_info)) screenmob.client.screen += group_info - if (length(group_storage)) + // Do not show open storages to viewers, they get their own storage UIs + if (length(group_storage) && viewmob == mymob) screenmob.client.screen += group_storage screenmob.client.screen += palette @@ -407,8 +404,10 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list( screenmob.client.screen += group_info // Hands are apart of the static group but still should be presetn in the reduced mode - for (var/atom/movable/screen/hand in hand_slots) - screenmob.client.screen += hand + for (var/i in 1 to length(mymob.held_items)) + var/atom/movable/screen/hand = screen_objects[HUD_KEY_HAND_SLOT(i)] + if (hand) + screenmob.client.screen += hand if(action_intent) //move this to the alternative position, where zone_select usually is. @@ -418,7 +417,7 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list( hud_shown = FALSE hud_version = display_hud_version - persistent_inventory_update(screenmob) + inventory_update(screenmob) // Gives all of the actions the screenmob owes to their hud screenmob.update_action_buttons(TRUE) // Handles alerts - the things on the right side of the screen @@ -456,7 +455,7 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list( if(!.) return var/mob/screenmob = viewmob || mymob - hidden_inventory_update(screenmob) + inventory_update(screenmob) /* BUBBER EDIT REMOVAL - We use a different lobby hud /datum/hud/new_player/show_hud(version = 0, mob/viewmob) @@ -465,13 +464,23 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list( show_station_trait_buttons() */ -/datum/hud/proc/hidden_inventory_update() - return - -/datum/hud/proc/persistent_inventory_update(mob/viewer) - if(!mymob) +/datum/hud/proc/inventory_update(mob/viewer) + if (isnull(mymob)) return + for (var/slot_id in inventory_slots) + var/datum/inventory_slot/slot = inventory_slots[slot_id] + if (!isnull(slot)) + slot.update_inventory_slot(src, mymob) + +/datum/hud/proc/update_inventory_slot(slot_id, ...) + if(isnull(mymob)) + return + var/datum/inventory_slot/slot = inventory_slots[slot_id] + if (!isnull(slot)) + var/list/slot_args = list(src, mymob) + args.Copy(2) + slot.update_inventory_slot(arglist(slot_args)) + /datum/hud/proc/update_ui_style(new_ui_style) // do nothing if overridden by a subtype or already on that style if (initial(ui_style) || ui_style == new_ui_style) @@ -514,8 +523,6 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list( /// Rebuilds our mob's hand slot screen elements /datum/hud/proc/build_hand_slots(update_hud = FALSE) - QDEL_LIST(hand_slots) - hand_slots = new /list(length(mymob.held_items)) for(var/i in 1 to length(mymob.held_items)) var/atom/movable/screen/inventory/hand/hand_box = add_screen_object(/atom/movable/screen/inventory/hand, HUD_KEY_HAND_SLOT(i), HUD_GROUP_STATIC, ui_style, ui_hand_position(i)) @@ -523,7 +530,6 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list( hand_box.icon_state = "hand_[mymob.held_index_to_dir(i)]" hand_box.held_index = i hand_box.update_appearance() - hand_slots[i] = hand_box var/num_of_swaps = 0 for(var/atom/movable/screen/swap_hand/swap_hands in screen_groups[HUD_GROUP_STATIC]) @@ -553,11 +559,11 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list( /datum/hud/proc/update_locked_slots() return -/// Creates inventory slot screen elements based on our assigned inventory_slots +/// Creates inventory slot screen elements based on our assigned default_inventory_slots /datum/hud/proc/create_inventory_slots() - var/list/created_paths = inventory_slots - if (ispath(inventory_slots)) - created_paths = valid_subtypesof(inventory_slots) + var/list/created_paths = default_inventory_slots + if (ispath(created_paths)) + created_paths = valid_subtypesof(created_paths) for (var/datum/inventory_slot/slot_type as anything in created_paths) var/datum/inventory_slot/inv_slot = GLOB.inventory_slot_datums[slot_type] @@ -565,16 +571,11 @@ GLOBAL_LIST_INIT(available_erp_ui_styles, list( stack_trace("[src] attempted to use an invalid inventory slot: [slot_type]") continue inv_slot.create_element(src) + inventory_slots[inv_slot.slot_id] = inv_slot - update_inventory_slots() - -/// Updates all of our inventory slots -/// Avoid calling directly in favor of specific update procs -/datum/hud/proc/update_inventory_slots() - for(var/atom/movable/screen/inventory/inv in screen_groups[HUD_GROUP_STATIC] + screen_groups[HUD_GROUP_TOGGLEABLE_INVENTORY]) - if(inv.slot_id) - inv_slots[TOBITSHIFT(inv.slot_id) + 1] = inv - inv.update_appearance() + // Lets add an abstract "hands" slot to ourselves for native handling + inventory_slots[ITEM_SLOT_HANDS] = GLOB.inventory_slot_datums[/datum/inventory_slot/hands] + inventory_update() /datum/hud/proc/position_action(atom/movable/screen/movable/action_button/button, position) // This is kinda a hack, I'm sorry. diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 54ff802aa1a..9f8a7b1e69b 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -1,5 +1,5 @@ /datum/hud/human - inventory_slots = /datum/inventory_slot/human + default_inventory_slots = /datum/inventory_slot/human /datum/hud/human/initialize_screen_objects() . = ..() @@ -72,113 +72,6 @@ continue inv.alpha = (blocked_slots & inv.slot_id) ? 128 : initial(inv.alpha) -/datum/hud/human/hidden_inventory_update(mob/viewer) - if(!mymob) - return - var/mob/living/carbon/human/H = mymob - - var/mob/screenmob = viewer || H - - if(screenmob.hud_used.inventory_shown && screenmob.hud_used.hud_shown) - if(H.shoes) - H.shoes.screen_loc = ui_shoes - screenmob.client.screen += H.shoes - if(H.gloves) - H.gloves.screen_loc = ui_gloves - screenmob.client.screen += H.gloves - if(H.ears) - H.ears.screen_loc = ui_ears - screenmob.client.screen += H.ears - if(H.glasses) - H.glasses.screen_loc = ui_glasses - screenmob.client.screen += H.glasses - if(H.w_uniform) - H.w_uniform.screen_loc = ui_iclothing - screenmob.client.screen += H.w_uniform - if(H.wear_suit) - H.wear_suit.screen_loc = ui_oclothing - screenmob.client.screen += H.wear_suit - if(H.wear_mask) - H.wear_mask.screen_loc = ui_mask - screenmob.client.screen += H.wear_mask - if(H.wear_neck) - H.wear_neck.screen_loc = ui_neck - screenmob.client.screen += H.wear_neck - if(H.head) - H.head.screen_loc = ui_head - screenmob.client.screen += H.head - else - if(H.shoes) - screenmob.client.screen -= H.shoes - if(H.gloves) - screenmob.client.screen -= H.gloves - if(H.ears) - screenmob.client.screen -= H.ears - if(H.glasses) - screenmob.client.screen -= H.glasses - if(H.w_uniform) - screenmob.client.screen -= H.w_uniform - if(H.wear_suit) - screenmob.client.screen -= H.wear_suit - if(H.wear_mask) - screenmob.client.screen -= H.wear_mask - if(H.wear_neck) - screenmob.client.screen -= H.wear_neck - if(H.head) - screenmob.client.screen -= H.head - -/datum/hud/human/persistent_inventory_update(mob/viewer) - if(!mymob) - return - ..() - var/mob/living/carbon/human/H = mymob - - var/mob/screenmob = viewer || H - - if(screenmob.hud_used) - if(screenmob.hud_used.hud_shown) - if(H.s_store) - H.s_store.screen_loc = ui_sstore1 - screenmob.client.screen += H.s_store - if(H.wear_id) - H.wear_id.screen_loc = ui_id - screenmob.client.screen += H.wear_id - if(H.belt) - H.belt.screen_loc = ui_belt - screenmob.client.screen += H.belt - if(H.back) - H.back.screen_loc = ui_back - screenmob.client.screen += H.back - if(H.l_store) - H.l_store.screen_loc = ui_storage1 - screenmob.client.screen += H.l_store - if(H.r_store) - H.r_store.screen_loc = ui_storage2 - screenmob.client.screen += H.r_store - - else - if(H.s_store) - screenmob.client.screen -= H.s_store - if(H.wear_id) - screenmob.client.screen -= H.wear_id - if(H.belt) - screenmob.client.screen -= H.belt - if(H.back) - screenmob.client.screen -= H.back - if(H.l_store) - screenmob.client.screen -= H.l_store - if(H.r_store) - screenmob.client.screen -= H.r_store - - if(hud_version != HUD_STYLE_NOHUD) - for(var/obj/item/I in H.held_items) - I.screen_loc = ui_hand_position(H.get_held_index_of_item(I)) - screenmob.client.screen += I - else - for(var/obj/item/I in H.held_items) - I.screen_loc = null - screenmob.client.screen -= I - /mob/living/carbon/human/verb/toggle_hotkey_verbs() set category = "OOC" set name = "Toggle hotkey buttons" diff --git a/code/_onclick/hud/inventory_slot.dm b/code/_onclick/hud/inventory_slot.dm index af3307be551..87efc517b7f 100644 --- a/code/_onclick/hud/inventory_slot.dm +++ b/code/_onclick/hud/inventory_slot.dm @@ -33,3 +33,62 @@ GLOBAL_LIST_INIT(inventory_slot_datums, initialize_inventory_slots()) inv_box.icon_full = icon_full inv_box.slot_id = slot_id return inv_box + +/// Returns the item held in this slot by hud's mymob +/datum/inventory_slot/proc/get_slot_item(mob/owner) + return owner.get_item_by_slot(slot_id) + +/// Returns a screen object for this slot for a particular hud datum +/datum/inventory_slot/proc/get_screen_slot(datum/hud/hud) + return hud.screen_objects[HUD_KEY_ITEM_SLOT(slot_id)] + +/// Update inventory slot visuals +/datum/inventory_slot/proc/update_inventory_slot(datum/hud/hud, mob/owner) + var/atom/movable/screen/inventory/slot = get_screen_slot(hud) + if (!slot) + return + + var/obj/item/slot_item = get_slot_item(owner) + update_slot_icon_contents(slot, slot_item) + +/// Updates the slot icon and its contents +/datum/inventory_slot/proc/update_slot_icon_contents(atom/movable/screen/inventory/slot, obj/item/slot_item) + slot.update_appearance(UPDATE_ICON) + if (!slot_item) + slot.vis_contents.Cut() + return + + if (slot_item in slot.vis_contents) + return + + // Reset pixel offsets in order to make it fit the box + slot_item.pixel_x = slot_item.base_pixel_x + slot_item.pixel_y = slot_item.base_pixel_y + slot.vis_contents += slot_item + +// Not a real inventory slot, but this is used as a generic abstraction for hand slot UI behaviors +/datum/inventory_slot/hands + slot_id = ITEM_SLOT_HANDS + +/datum/inventory_slot/hands/create_element(datum/hud/hud) + CRASH("[hud] attempted to call create_element on a behavior-only hands inventory slot datum!") + +/datum/inventory_slot/hands/get_slot_item(mob/owner, hand_index = 1) + return owner.held_items[hand_index] + +/datum/inventory_slot/hands/get_screen_slot(datum/hud/hud, hand_index = 1) + return hud.screen_objects[HUD_KEY_HAND_SLOT(hand_index)] + +/datum/inventory_slot/hands/update_inventory_slot(datum/hud/hud, mob/owner, hand_index = null) + // If no index was passed, update all hand slots + if (isnull(hand_index)) + for (var/i in 1 to length(owner.held_items)) + update_inventory_slot(hud, owner, i) + return + + var/atom/movable/screen/inventory/slot = get_screen_slot(hud, hand_index) + if (!slot) + return + + var/obj/item/slot_item = get_slot_item(owner, hand_index) + update_slot_icon_contents(slot, slot_item) 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 36fd9f37d2d..6cfafcd6797 100644 --- a/code/_onclick/hud/rendering/plane_masters/plane_master_subtypes.dm +++ b/code/_onclick/hud/rendering/plane_masters/plane_master_subtypes.dm @@ -355,34 +355,14 @@ /atom/movable/screen/plane_master/o_light_visual name = "Overlight light visual" documentation = "Holds overlay lighting objects, or the sort of lighting that's a well, overlay stuck to something.\ -
Exists because lighting updating is really slow, and movement needs to feel smooth.\ -
We draw to the game plane, and mask out space for ourselves on the lighting plane so any color we have has the chance to display." +
Exists because lighting updating is really slow, and movement needs to feel smooth (also being an overlay lets us muck with it easier)." plane = O_LIGHTING_VISUAL_PLANE appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR - render_target = O_LIGHTING_VISUAL_RENDER_TARGET mouse_opacity = MOUSE_OPACITY_TRANSPARENT blend_mode = BLEND_ADD - render_relay_planes = list(RENDER_PLANE_LIGHTING) + render_relay_planes = list(RENDER_PLANE_O_LIGHTING) critical = PLANE_CRITICAL_DISPLAY -/atom/movable/screen/plane_master/o_light_visual/Initialize(mapload, datum/hud/hud_owner, datum/plane_master_group/home, offset) - . = ..() - // I'd love for this to be HSL but filters don't work with blend modes - add_relay_to(GET_NEW_PLANE(RENDER_PLANE_TURF_LIGHTING, offset), BLEND_MULTIPLY, relay_color = list( - -1, -1, -1, 0, - -1, -1, -1, 0, - -1, -1, -1, 0, - 0, 0, 0, OVERLAY_LIGHTING_WEIGHT, - 1, 1, 1, 0, - )) - add_relay_to(GET_NEW_PLANE(RENDER_PLANE_SPECULAR, offset), relay_color = list( - SPECULAR_EMISSIVE_OVERLAY_CONTRAST, 0, 0, 0, - 0, SPECULAR_EMISSIVE_OVERLAY_CONTRAST, 0, 0, - 0, 0, SPECULAR_EMISSIVE_OVERLAY_CONTRAST, 0, - 0, 0, 0, 1, - -SPECULAR_EMISSIVE_CUTOFF, -SPECULAR_EMISSIVE_CUTOFF, -SPECULAR_EMISSIVE_CUTOFF, 0, - )) - /atom/movable/screen/plane_master/above_lighting name = "Above lighting" plane = ABOVE_LIGHTING_PLANE diff --git a/code/_onclick/hud/rendering/render_plate.dm b/code/_onclick/hud/rendering/render_plate.dm index e7f7bf88903..9d42784bb2a 100644 --- a/code/_onclick/hud/rendering/render_plate.dm +++ b/code/_onclick/hud/rendering/render_plate.dm @@ -132,7 +132,7 @@ appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR mouse_opacity = MOUSE_OPACITY_TRANSPARENT blend_mode = BLEND_ADD - render_relay_planes = list(O_LIGHTING_VISUAL_PLANE) + render_relay_planes = list(RENDER_PLANE_O_LIGHTING) critical = PLANE_CRITICAL_DISPLAY /atom/movable/screen/plane_master/rendering_plate/emissive_bloom/Initialize(mapload, datum/hud/hud_owner, datum/plane_master_group/home, offset) @@ -155,6 +155,35 @@ render_relay_planes = list() critical = PLANE_CRITICAL_DISPLAY +/atom/movable/screen/plane_master/rendering_plate/overlay_light + name = "Overlight plate" + documentation = "Combines overlay lights with emissives.\ +
We draw to the generic lighting plate, do some funky stuff with turf lighting to sort of \"cut out\" a bit of space for ourselves there, and do some junk to speculars" + plane = RENDER_PLANE_O_LIGHTING + appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + blend_mode = BLEND_ADD + render_relay_planes = list(RENDER_PLANE_LIGHTING) + critical = PLANE_CRITICAL_DISPLAY + +/atom/movable/screen/plane_master/rendering_plate/overlay_light/Initialize(mapload, datum/hud/hud_owner, datum/plane_master_group/home, offset) + . = ..() + // I'd love for this to be HSL but filters don't work with blend modes + add_relay_to(GET_NEW_PLANE(RENDER_PLANE_TURF_LIGHTING, offset), BLEND_MULTIPLY, relay_color = list( + -1, -1, -1, 0, + -1, -1, -1, 0, + -1, -1, -1, 0, + 0, 0, 0, OVERLAY_LIGHTING_WEIGHT, + 1, 1, 1, 0, + )) + add_relay_to(GET_NEW_PLANE(RENDER_PLANE_SPECULAR, offset), relay_color = list( + SPECULAR_EMISSIVE_OVERLAY_CONTRAST, 0, 0, 0, + 0, SPECULAR_EMISSIVE_OVERLAY_CONTRAST, 0, 0, + 0, 0, SPECULAR_EMISSIVE_OVERLAY_CONTRAST, 0, + 0, 0, 0, 1, + -SPECULAR_EMISSIVE_CUTOFF, -SPECULAR_EMISSIVE_CUTOFF, -SPECULAR_EMISSIVE_CUTOFF, 0, + )) + /atom/movable/screen/plane_master/rendering_plate/specular name = "Specular plate" documentation = "Plate used to artificially increase lighting on certain pixels to poorly mimic shiny surfaces." diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index d1f9c632a97..fe8f1a1a125 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -10,8 +10,10 @@ add_screen_object(/atom/movable/screen/memories, HUD_MOB_MEMORIES, HUD_GROUP_STATIC, ui_style, ui_borg_memories_menu) add_screen_object(/atom/movable/screen/robot/radio, HUD_CYBORG_RADIO) + // Cyborg modules are their "hands", and use hand keys for ease of handling as they behave functionally the same + // Generic code can just typecheck for /atom/movable/screen/inventory/hud if it needs explicitly hands for (var/i in BORG_CHOOSE_MODULE_ONE to BORG_CHOOSE_MODULE_THREE) - var/atom/movable/screen/robot/module_slot/module = add_screen_object(/atom/movable/screen/robot/module_slot, HUD_KEY_CYBORG_MODULE(i)) + var/atom/movable/screen/robot/module_slot/module = add_screen_object(/atom/movable/screen/robot/module_slot, HUD_KEY_HAND_SLOT(i)) module.set_slot(i) add_screen_object(/atom/movable/screen/robot/lamp, HUD_CYBORG_LAMP) @@ -33,25 +35,3 @@ add_screen_object(/atom/movable/screen/healths/robot, HUD_MOB_HEALTH, HUD_GROUP_INFO) add_screen_object(/atom/movable/screen/pull, HUD_MOB_PULL, HUD_GROUP_HOTKEYS, ui_style, ui_borg_pull) - -/datum/hud/robot/persistent_inventory_update(mob/viewer) - if(!mymob) - return - var/mob/living/silicon/robot/R = mymob - - var/mob/screenmob = viewer || R - if(!screenmob.hud_used) - return - - if(!screenmob.hud_used.hud_shown) - for(var/obj/item/I in R.held_items) - screenmob.client.screen -= I - return - - for(var/i in 1 to length(R.held_items)) - var/obj/item/I = R.held_items[i] - if(!I) - continue - var/atom/movable/screen/robot/module_slot/slot = screen_objects[HUD_KEY_CYBORG_MODULE(i)] - I.screen_loc = slot.screen_loc - screenmob.client.screen += I diff --git a/code/_onclick/hud/screen_objects/action_button.dm b/code/_onclick/hud/screen_objects/action_button.dm index 0782aabd5c0..358e0850875 100644 --- a/code/_onclick/hud/screen_objects/action_button.dm +++ b/code/_onclick/hud/screen_objects/action_button.dm @@ -213,7 +213,7 @@ if(!hud_used || !client) return - if(hud_used.hud_shown != HUD_STYLE_STANDARD) + if(hud_used.hud_version != HUD_STYLE_STANDARD) return for(var/datum/action/action as anything in actions) diff --git a/code/_onclick/hud/screen_objects/alert.dm b/code/_onclick/hud/screen_objects/alert.dm index 6a79bf6b0e9..81241a03abb 100644 --- a/code/_onclick/hud/screen_objects/alert.dm +++ b/code/_onclick/hud/screen_objects/alert.dm @@ -1203,10 +1203,11 @@ if(!screenmob.client) return FALSE var/list/alerts = mymob.alerts - if(!hud_shown) + if(hud_version != HUD_STYLE_STANDARD) for(var/i in 1 to alerts.len) screenmob.client.screen -= alerts[alerts[i]] return TRUE + var/user_pref_hud = ui_style2icon(mymob.client?.prefs?.read_preference(/datum/preference/choiced/ui_style)) for(var/i in 1 to length(alerts)) var/atom/movable/screen/alert/alert = alerts[alerts[i]] diff --git a/code/_onclick/hud/screen_objects/human.dm b/code/_onclick/hud/screen_objects/human.dm index b69ceb2143e..c605c4c4ef1 100644 --- a/code/_onclick/hud/screen_objects/human.dm +++ b/code/_onclick/hud/screen_objects/human.dm @@ -23,7 +23,6 @@ usr.hud_used.inventory_shown = TRUE usr.client.screen += targetmob.hud_used.screen_groups[HUD_GROUP_TOGGLEABLE_INVENTORY] - targetmob.hud_used.hidden_inventory_update(usr) update_appearance() /atom/movable/screen/human/toggle/update_icon_state() diff --git a/code/_onclick/hud/screen_objects/new_player.dm b/code/_onclick/hud/screen_objects/new_player.dm index 18d7c05b6f7..dd7136b6f2e 100644 --- a/code/_onclick/hud/screen_objects/new_player.dm +++ b/code/_onclick/hud/screen_objects/new_player.dm @@ -699,7 +699,7 @@ BUBBER REMOVAL END if(round_started) new_maptext = "[SSmapping.current_map.map_name]
\ [LAZYLEN(GLOB.clients)] player\s online
\ - [ROUND_TIME()] in
" + [round_timestamp()] in
" new_maptext += "
" else if(hud.mymob.client?.holder) diff --git a/code/_onclick/hud/screen_objects/radial.dm b/code/_onclick/hud/screen_objects/radial.dm index b1eaa78eb64..fc6e8fb089c 100644 --- a/code/_onclick/hud/screen_objects/radial.dm +++ b/code/_onclick/hud/screen_objects/radial.dm @@ -120,16 +120,34 @@ GLOBAL_LIST_EMPTY(radial_menus) //If we swap to vis_contens inventory these will need a redo /datum/radial_menu/proc/check_screen_border(mob/user) var/atom/movable/AM = anchor - if(!istype(AM) || !AM.screen_loc) + if(!istype(AM)) return - if(AM in user.client.screen) - if(hudfix_method) - anchor = user - else - py_shift = 32 - restrict_to_dir(NORTH) //I was going to parse screen loc here but that's more effort than it's worth. - else if(hudfix_method && AM.loc) - anchor = get_atom_on_turf(anchor) + + var/in_screen = AM.screen_loc && (AM in user.client.screen) + if (!in_screen) + var/list/check_locs = AM.vis_locs.Copy() + var/i = 1 + while (i <= length(check_locs)) + var/atom/movable/other_check = check_locs[i] + i += 1 + if (!istype(other_check)) + continue + if (other_check.screen_loc && (other_check in user.client.screen)) + in_screen = TRUE + break + check_locs |= other_check.vis_locs + + if(!in_screen) + if(hudfix_method && AM.loc) + anchor = get_atom_on_turf(anchor) + return + + if(hudfix_method) + anchor = user + return + + py_shift = 32 + restrict_to_dir(NORTH) //I was going to parse screen loc here but that's more effort than it's worth. //Sets defaults //These assume 45 deg min_angle diff --git a/code/_onclick/hud/screen_objects/screen_objects.dm b/code/_onclick/hud/screen_objects/screen_objects.dm index 219819b2337..3b7d2b97ff1 100644 --- a/code/_onclick/hud/screen_objects/screen_objects.dm +++ b/code/_onclick/hud/screen_objects/screen_objects.dm @@ -219,10 +219,13 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen) // I hate this place /atom/movable/screen/inventory/MouseEntered(location, control, params) . = ..() - add_overlays() + if (usr == hud?.mymob) + add_overlays() /atom/movable/screen/inventory/MouseExited() ..() + if (usr != hud?.mymob) + return cut_overlay(object_overlay) QDEL_NULL(object_overlay) @@ -396,8 +399,11 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen) // I hate this place var/vertical = FALSE /atom/movable/screen/floor_changer/Click(location,control,params) - var/list/modifiers = params2list(params) + var/mob/living/user = get_mob() + if(usr != user) + return + var/list/modifiers = params2list(params) var/mouse_position if(vertical) @@ -406,10 +412,23 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen) // I hate this place mouse_position = text2num(LAZYACCESS(modifiers, ICON_X)) if(mouse_position > 16) - usr.up() + //non-living can't RMB anyway, but just a precaution. + if(LAZYACCESS(modifiers, RIGHT_CLICK) && isliving(user)) + if(user.looking_vertically == UP) + user.end_look() + else + user.look_up() + return + hud.mymob.up() return - usr.down() + if(LAZYACCESS(modifiers, RIGHT_CLICK) && isliving(user)) + if(user.looking_vertically == DOWN) + user.end_look() + else + user.look_down() + return + hud.mymob.down() return /atom/movable/screen/floor_changer/vertical diff --git a/code/_onclick/hud/screen_objects/voidwalker.dm b/code/_onclick/hud/screen_objects/voidwalker.dm index 6d718ac58d7..8d414c9dc21 100644 --- a/code/_onclick/hud/screen_objects/voidwalker.dm +++ b/code/_onclick/hud/screen_objects/voidwalker.dm @@ -56,7 +56,7 @@ for(var/atom/movable/vomit as anything in GLOB.nebula_vomits) if(!is_station_level(vomit.z)) - return + continue valid_vomits += vomit return valid_vomits diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index 1cd89773c55..b934d7417e6 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -188,7 +188,7 @@ /atom/proc/attack_basic_mob(mob/user, list/modifiers) SHOULD_CALL_PARENT(TRUE) if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_BASIC_MOB, user) & COMSIG_BASIC_ATTACK_CANCEL_CHAIN) - return + return FALSE return handle_basic_attack(user, modifiers) //return value of attack animal, this is how much damage was dealt to the attacked thing ///This exists so stuff can override the default call of attack_animal for attack_basic_mob diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm index 0ccde360e3b..cb38d2f9d07 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -396,15 +396,6 @@ /datum/config_entry/flag/enable_night_shifts -/datum/config_entry/flag/randomize_shift_time - -/datum/config_entry/flag/shift_time_realtime - -/datum/config_entry/number/shift_time_start_hour - default = 12 - min_val = 0 - max_val = 23 - /datum/config_entry/number/monkeycap default = 64 min_val = 0 @@ -486,16 +477,31 @@ /// Disables Quirk point balancing for the server and clients. /datum/config_entry/flag/disable_quirk_points +/datum/config_entry/flag/disable_quirk_points/ValidateAndSet(str_val) + . = ..() + if(.) + SSquirks.points_enabled = !config_entry_value + /// The maximum amount of positive quirks one character can have at roundstart. /datum/config_entry/number/max_positive_quirks default = 6 min_val = -1 +/datum/config_entry/number/max_positive_quirks/ValidateAndSet(str_val) + . = ..() + if(.) + SSquirks.max_positive_quirks = config_entry_value + /// Freebie quirk points. Can't go negative because we have no way of enforcing a person has a quirk before they join. /datum/config_entry/number/default_quirk_points default = 2 min_val = 0 +/datum/config_entry/number/default_quirk_points/ValidateAndSet(str_val) + . = ..() + if(.) + SSquirks.default_quirk_points = config_entry_value + /// Max personalities you can have at once /datum/config_entry/number/max_personalities default = 5 diff --git a/code/controllers/subsystem/dynamic/dynamic_ruleset_roundstart.dm b/code/controllers/subsystem/dynamic/dynamic_ruleset_roundstart.dm index c967112f14f..2143b6cbb00 100644 --- a/code/controllers/subsystem/dynamic/dynamic_ruleset_roundstart.dm +++ b/code/controllers/subsystem/dynamic/dynamic_ruleset_roundstart.dm @@ -250,12 +250,76 @@ ) min_pop = 30 min_antag_cap = list("denominator" = 18, "offset" = 1) - ruleset_lazy_templates = list(LAZY_TEMPLATE_KEY_NUKIEBASE) + ruleset_lazy_templates = list(LAZY_TEMPLATE_KEY_NUKIEELEVATOR) repeatable = FALSE /datum/dynamic_ruleset/roundstart/nukies/prepare_for_role(datum/mind/candidate) + // they all get the normal operative job, even the leader. (leader's job is updated when they get the antag datum) + // all this ultimately matters for is 1. ensuring they *don't* get a normal job and 2. spawning them in the elevator LAZYSET(SSjob.forced_occupations, candidate, /datum/job/nuclear_operative) +/datum/dynamic_ruleset/roundstart/nukies/execute() + . = ..() + addtimer(CALLBACK(src, PROC_REF(load_nukie_base)), 3 SECONDS) + +#define ELEVATOR_WIDTH 6 +#define ELEVATOR_HEIGHT 5 + +/datum/dynamic_ruleset/roundstart/nukies/proc/load_nukie_base() + SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_NUKIEBASE) + addtimer(CALLBACK(src, PROC_REF(teleport_elevator_contents)), 2 SECONDS) + addtimer(CALLBACK(src, PROC_REF(open_nukie_elevator)), 3 SECONDS) + addtimer(CALLBACK(src, PROC_REF(call_infiltrator)), 5 SECONDS) + +/datum/dynamic_ruleset/roundstart/nukies/proc/teleport_elevator_contents() + var/obj/effect/landmark/nukeop_elevator/interior/interior = locate() in GLOB.landmarks_list + var/obj/effect/landmark/nukeop_elevator/exterior/exterior = locate() in GLOB.landmarks_list + if(isnull(interior) || isnull(exterior)) + stack_trace("Failed to find nukie elevator landmarks during load!") + message_admins("Failed to find nukie elevator landmarks during load, you might have some stuck nukies that need help.") + return + + var/turf/top_right_interior = get_turf(interior) + var/turf/top_right_exterior = get_turf(exterior) + + var/list/turf/elevator_turfs = block( + top_right_interior.x, + top_right_interior.y, + top_right_interior.z, + top_right_interior.x - ELEVATOR_WIDTH + 1, + top_right_interior.y - ELEVATOR_HEIGHT + 1, + top_right_interior.z, + ) + + for(var/turf/elevator_turf as anything in elevator_turfs) + var/turf/destination_turf = locate( + top_right_exterior.x - (top_right_interior.x - elevator_turf.x), + top_right_exterior.y - (top_right_interior.y - elevator_turf.y), + top_right_exterior.z, + ) + if(isnull(destination_turf)) + stack_trace("Failed to find destination turf for nukie elevator!") + message_admins("Failed to find corresponding elevator turf for nuke ops, you might have some stuck nukies that need help.") + continue + + for(var/atom/movable/thing in elevator_turf) + if(thing.anchored || thing.orbit_target) + continue + thing.forceMove(destination_turf) + +/datum/dynamic_ruleset/roundstart/nukies/proc/open_nukie_elevator() + for(var/obj/machinery/door/poddoor/shutter in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/door/poddoor)) + if(shutter.id_tag == "nukiespawnlift") + shutter.open() + +/datum/dynamic_ruleset/roundstart/nukies/proc/call_infiltrator() + for(var/datum/mind/leader_mind as anything in selected_minds) + var/datum/antagonist/nukeop/leader/nuke_leader = leader_mind.has_antag_datum(/datum/antagonist/nukeop/leader) + nuke_leader?.spawn_infiltrator() + +#undef ELEVATOR_WIDTH +#undef ELEVATOR_HEIGHT + /datum/dynamic_ruleset/roundstart/nukies/create_execute_args() return list( new /datum/team/nuclear(), @@ -264,9 +328,14 @@ /datum/dynamic_ruleset/roundstart/nukies/assign_role(datum/mind/candidate, datum/team/nuke_team, datum/mind/most_experienced) if(most_experienced == candidate) - candidate.add_antag_datum(/datum/antagonist/nukeop/leader, nuke_team) + var/datum/antagonist/nukeop/leader/nuke_leader = new() + nuke_leader.send_to_spawnpoint = FALSE // because they get spawned in the elevator + nuke_leader.spawn_ship = FALSE // spawned manually later + candidate.add_antag_datum(nuke_leader, nuke_team) else - candidate.add_antag_datum(/datum/antagonist/nukeop, nuke_team) + var/datum/antagonist/nukeop/nukie = new() + nukie.send_to_spawnpoint = FALSE // ditto + candidate.add_antag_datum(nukie, nuke_team) /datum/dynamic_ruleset/roundstart/nukies/round_result() var/datum/antagonist/nukeop/nukie = selected_minds[1].has_antag_datum(/datum/antagonist/nukeop) diff --git a/code/controllers/subsystem/economy.dm b/code/controllers/subsystem/economy.dm index 94e0649eedf..36941659f81 100644 --- a/code/controllers/subsystem/economy.dm +++ b/code/controllers/subsystem/economy.dm @@ -221,7 +221,7 @@ SUBSYSTEM_DEF(economy) "account" = "[account.account_holder]", "cost" = price_to_use, "vendor" = "[astype(vendor, /atom)?.name || vendor]", - "stationtime" = station_time_timestamp("hh:mm"), + "stationtime" = round_timestamp("hh:mm"), )) /** diff --git a/code/controllers/subsystem/explosions.dm b/code/controllers/subsystem/explosions.dm index f5c733c0fd6..4e7d0d5fb8a 100644 --- a/code/controllers/subsystem/explosions.dm +++ b/code/controllers/subsystem/explosions.dm @@ -367,7 +367,7 @@ ADMIN_VERB(check_bomb_impacts, R_DEBUG, "Check Bomb Impact", "See what the effec var/y0 = epicenter.y var/z0 = epicenter.z var/area/areatype = get_area(epicenter) - SSblackbox.record_feedback("associative", "explosion", 1, list("dev" = devastation_range, "heavy" = heavy_impact_range, "light" = light_impact_range, "flame" = flame_range, "flash" = flash_range, "orig_dev" = orig_dev_range, "orig_heavy" = orig_heavy_range, "orig_light" = orig_light_range, "x" = x0, "y" = y0, "z" = z0, "area" = areatype.type, "time" = time_stamp("YYYY-MM-DD hh:mm:ss", 1), "possible_cause" = explosion_cause, "possible_suspect" = who_did_it_game_log)) + SSblackbox.record_feedback("associative", "explosion", 1, list("dev" = devastation_range, "heavy" = heavy_impact_range, "light" = light_impact_range, "flame" = flame_range, "flash" = flash_range, "orig_dev" = orig_dev_range, "orig_heavy" = orig_heavy_range, "orig_light" = orig_light_range, "x" = x0, "y" = y0, "z" = z0, "area" = areatype.type, "time" = server_timestamp("YYYY-MM-DD hh:mm:ss", 1), "possible_cause" = explosion_cause, "possible_suspect" = who_did_it_game_log)) // Play sounds; we want sounds to be different depending on distance so we will manually do it ourselves. // Stereo users will also hear the direction of the explosion! diff --git a/code/controllers/subsystem/input.dm b/code/controllers/subsystem/input.dm index dff1edad054..ac6640a76cf 100644 --- a/code/controllers/subsystem/input.dm +++ b/code/controllers/subsystem/input.dm @@ -49,7 +49,7 @@ VERB_MANAGER_SUBSYSTEM_DEF(input) /datum/controller/subsystem/verb_manager/input/can_queue_verb(datum/callback/verb_callback/incoming_callback, control) //make sure the incoming verb is actually something we specifically want to handle - if(control != "mapwindow.map") + if(control != SKIN_MAPWINDOW_MAP) return FALSE if(average_click_delay > MAXIMUM_CLICK_LATENCY || !..()) diff --git a/code/controllers/subsystem/lag_switch.dm b/code/controllers/subsystem/lag_switch.dm index bfb68f43e49..573d4ecf8ca 100644 --- a/code/controllers/subsystem/lag_switch.dm +++ b/code/controllers/subsystem/lag_switch.dm @@ -10,7 +10,7 @@ SUBSYSTEM_DEF(lag_switch) /// List of bools corresponding to code/__DEFINES/lag_switch.dm var/static/list/measures[MEASURES_AMOUNT] /// List of measures that toggle automatically - var/list/auto_measures = list(DISABLE_GHOST_ZOOM_TRAY, DISABLE_RUNECHAT, DISABLE_USR_ICON2HTML, DISABLE_PARALLAX, DISABLE_FOOTSTEPS) + var/list/auto_measures = list(DISABLE_GHOST_ZOOM_TRAY, DISABLE_RUNECHAT, DISABLE_USR_ICON2HTML, DISABLE_PARALLAX, DISABLE_FOOTSTEPS, DISABLE_DEAD_RUNECHAT) /// Timer ID for the automatic veto period var/veto_timer_id /// Cooldown between say verb uses when slowmode is enabled @@ -88,9 +88,11 @@ SUBSYSTEM_DEF(lag_switch) switch(measure_key) if(DISABLE_DEAD_KEYLOOP) if(state) - for(var/mob/user as anything in GLOB.player_list) - if(user.stat == DEAD && !user.client?.holder) - GLOB.keyloop_list -= user + var/list/all_observers = GLOB.dead_player_list + GLOB.current_observers_list + for(var/mob/observer as anything in all_observers) + if(observer.client?.holder) // Don't freeze admins + continue + GLOB.keyloop_list -= observer deadchat_broadcast(span_big("To increase performance Observer freelook is now disabled. Please use Orbit, Teleport, and Jump to look around."), message_type = DEADCHAT_ANNOUNCEMENT) else GLOB.keyloop_list |= GLOB.player_list diff --git a/code/controllers/subsystem/lighting.dm b/code/controllers/subsystem/lighting.dm index 4717e7dcf8c..d35a58b6ab6 100644 --- a/code/controllers/subsystem/lighting.dm +++ b/code/controllers/subsystem/lighting.dm @@ -4,7 +4,7 @@ SUBSYSTEM_DEF(lighting) /datum/controller/subsystem/atoms, /datum/controller/subsystem/mapping, ) - wait = 2 + wait = 1 ss_flags = SS_TICKER var/static/list/sources_queue = list() // List of lighting sources queued for update. var/static/list/corners_queue = list() // List of lighting corners queued for update. @@ -38,7 +38,7 @@ SUBSYSTEM_DEF(lighting) for(var/turf/area_turf as anything in zlevel_turfs) if(area_turf.space_lit) continue - new /datum/lighting_object(area_turf) + new /atom/movable/lighting_object(null, area_turf) CHECK_TICK CHECK_TICK @@ -53,6 +53,7 @@ SUBSYSTEM_DEF(lighting) // UPDATE SOURCE QUEUE var/i = 0 + // something something cache locally for sonic speed var/list/queue = current_sources while(i < length(queue)) //we don't use for loop here because i cannot be changed during an iteration i += 1 @@ -110,7 +111,7 @@ SUBSYSTEM_DEF(lighting) while(i < length(queue)) //we don't use for loop here because i cannot be changed during an iteration i += 1 - var/datum/lighting_object/O = queue[i] + var/atom/movable/lighting_object/O = queue[i] if(QDELETED(O)) continue O.update() @@ -132,3 +133,13 @@ SUBSYSTEM_DEF(lighting) /datum/controller/subsystem/lighting/Recover() initialized = SSlighting.initialized ..() + +/// Takes a list of turfs in, and sets up static lighting for them as needed. +/// Exactly what it says on the tin. +/datum/controller/subsystem/lighting/proc/setup_static_lighting_if_needed(list/turfs) + for(var/turf/unlit as anything in turfs) + if(unlit.space_lit) + continue + var/area/loc_area = unlit.loc + if(loc_area.static_lighting) + unlit.lighting_build_overlay() diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index 92abd898b73..22cb0d4891b 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -156,8 +156,8 @@ SUBSYSTEM_DEF(mapping) loading_ruins = TRUE setup_ruins() loading_ruins = FALSE - #endif + // Run map generation after ruin generation to prevent issues run_map_terrain_generation() // Generate our rivers, we do this here so the map doesn't load on top of them @@ -279,7 +279,7 @@ SUBSYSTEM_DEF(mapping) // Generate mining ruins var/list/lava_ruins = levels_by_trait(ZTRAIT_LAVA_RUINS) for (var/lava_z in lava_ruins) - spawn_rivers(lava_z, 4, /turf/open/lava/smooth/lava_land_surface, /area/lavaland/surface/outdoors/unexplored) + spawn_rivers(lava_z, 3, /turf/open/lava/smooth/lava_land_surface, /area/lavaland/surface/outdoors/unexplored) // +1 from the mapped in waypoint var/list/ice_ruins = levels_by_trait(ZTRAIT_ICE_RUINS) for (var/ice_z in ice_ruins) @@ -752,11 +752,6 @@ ADMIN_VERB(load_away_mission, R_FUN, "Load Away Mission", "Load a specific away if(contain_turfs) build_area_turfs(z_value, filled_with_space) - // And finally, misc global generation - - // We'll have to update this if offsets change, because we load lowest z to highest z - generate_lighting_appearance_by_z(z_value) - /datum/controller/subsystem/mapping/proc/build_area_turfs(z_level, space_guaranteed) // If we know this is filled with default tiles, we can use the default area // Faster @@ -793,11 +788,6 @@ ADMIN_VERB(load_away_mission, R_FUN, "Load Away Mission", "Load a specific away z_level_to_lowest_plane_offset[level_to_update.z_value] = plane_offset z_level_to_stack[level_to_update.z_value] = z_stack - // This can be affected by offsets, so we need to update it - // PAIN - for(var/i in 1 to length(z_list)) - generate_lighting_appearance_by_z(i) - var/old_max = max_plane_offset max_plane_offset = max(max_plane_offset, plane_offset) if(max_plane_offset == old_max) @@ -883,11 +873,6 @@ ADMIN_VERB(load_away_mission, R_FUN, "Load Away Mission", "Load a specific away CRASH("Attempted to lazy load a template key that does not exist: '[template_key]'") return target.lazy_load() -/proc/generate_lighting_appearance_by_z(z_level) - if(length(GLOB.default_lighting_underlays_by_z) < z_level) - GLOB.default_lighting_underlays_by_z.len = z_level - GLOB.default_lighting_underlays_by_z[z_level] = mutable_appearance(LIGHTING_ICON, "transparent", z_level * 0.01, null, LIGHTING_PLANE, 255, RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM, offset_const = GET_Z_PLANE_OFFSET(z_level)) - /// Returns true if the map we're playing on is on a planet /datum/controller/subsystem/mapping/proc/is_planetary() return current_map.planetary diff --git a/code/controllers/subsystem/movement/movement_types.dm b/code/controllers/subsystem/movement/movement_types.dm index 25a2b88e12b..e83f68d22db 100644 --- a/code/controllers/subsystem/movement/movement_types.dm +++ b/code/controllers/subsystem/movement/movement_types.dm @@ -74,6 +74,7 @@ /datum/move_loop/proc/loop_stopped() SHOULD_CALL_PARENT(TRUE) status &= ~MOVELOOP_STATUS_RUNNING + EVLOG_TEXT(moving, EVLOG_CATEGORY_MOVELOOPS, "Moveloop stopped") SEND_SIGNAL(src, COMSIG_MOVELOOP_STOP) /datum/move_loop/proc/info_deleted(datum/source) @@ -127,6 +128,10 @@ owner?.processing_move_loop_flags = flags var/result = move() //Result is an enum value. Enums defined in __DEFINES/movement.dm + + if(result) + EVLOG_PATH(moving, EVLOG_CATEGORY_MOVELOOPS, "Moved using [src]", list(old_loc, moving.loc)) //You might think, this runs a lot; but if not logging, it only does a lookup on the event logger. + if(moving) var/direction = get_dir(old_loc, moving.loc) SEND_SIGNAL(moving, COMSIG_MOVABLE_MOVED_FROM_LOOP, src, old_dir, direction) @@ -414,6 +419,7 @@ . = ..() movement_path = null + /datum/move_loop/has_target/jps/Destroy() avoid = null on_finish_callbacks = null @@ -432,6 +438,7 @@ /datum/move_loop/has_target/jps/proc/on_finish_pathing(list/path) movement_path = path is_pathing = FALSE + EVLOG_PATH(moving, EVLOG_CATEGORY_JPS, "Planned AI path", movement_path) SEND_SIGNAL(src, COMSIG_MOVELOOP_JPS_FINISHED_PATHING, path) /datum/move_loop/has_target/jps/move() @@ -439,6 +446,7 @@ if(is_pathing) return MOVELOOP_NOT_READY else + EVLOG_TEXT(moving, EVLOG_CATEGORY_JPS, "Path recalculating due to lack of path") INVOKE_ASYNC(src, PROC_REF(recalculate_path)) return MOVELOOP_FAILURE @@ -453,6 +461,7 @@ if(length(movement_path)) movement_path.Cut(1,2) else + EVLOG_TEXT(moving, EVLOG_CATEGORY_MOVELOOPS, "Path recalculating due to obstruction") INVOKE_ASYNC(src, PROC_REF(recalculate_path)) return MOVELOOP_FAILURE diff --git a/code/controllers/subsystem/networks/modular_computers.dm b/code/controllers/subsystem/networks/modular_computers.dm index eb25e0c97ae..40ce21c51cd 100644 --- a/code/controllers/subsystem/networks/modular_computers.dm +++ b/code/controllers/subsystem/networks/modular_computers.dm @@ -146,7 +146,7 @@ SUBSYSTEM_DEF(modular_computers) */ /datum/controller/subsystem/modular_computers/proc/add_log(log_string) var/list/log_text = list() - log_text += "\[[station_time_timestamp()]\]" + log_text += "\[[round_timestamp()]\]" log_text += "*SYSTEM* - " log_text += log_string log_string = log_text.Join() diff --git a/code/controllers/subsystem/nightshift.dm b/code/controllers/subsystem/nightshift.dm deleted file mode 100644 index 170f1269614..00000000000 --- a/code/controllers/subsystem/nightshift.dm +++ /dev/null @@ -1,66 +0,0 @@ -SUBSYSTEM_DEF(nightshift) - name = "Night Shift" - wait = 10 MINUTES - - var/nightshift_active = FALSE - var/nightshift_start_time = 702000 //7:30 PM, station time - var/nightshift_end_time = 270000 //7:30 AM, station time - var/nightshift_first_check = 30 SECONDS - - var/high_security_mode = FALSE - var/list/currentrun - -/datum/controller/subsystem/nightshift/Initialize() - if(!CONFIG_GET(flag/enable_night_shifts)) - can_fire = FALSE - return SS_INIT_SUCCESS - -/datum/controller/subsystem/nightshift/fire(resumed = FALSE) - if(resumed) - update_nightshift(resumed = TRUE) - return - if(world.time - SSticker.round_start_time < nightshift_first_check) - return - check_nightshift() - -/datum/controller/subsystem/nightshift/proc/announce(message) - priority_announce( - text = message, - sound = 'sound/announcer/notice/notice2.ogg', - sender_override = "Automated Lighting System Announcement", - color_override = "grey", - ) - -/datum/controller/subsystem/nightshift/proc/check_nightshift() - var/emergency = SSsecurity_level.get_current_level_as_number() >= SEC_LEVEL_RED - var/announcing = TRUE - var/time = station_time() - var/night_time = (time < nightshift_end_time) || (time > nightshift_start_time) - if(high_security_mode != emergency) - high_security_mode = emergency - if(night_time) - announcing = FALSE - if(!emergency) - announce("Restoring night lighting configuration to normal operation.") - else - announce("Disabling night lighting: Station is in a state of emergency.") - if(emergency) - night_time = FALSE - if(nightshift_active != night_time) - update_nightshift(night_time, announcing) - -/datum/controller/subsystem/nightshift/proc/update_nightshift(active, announce = TRUE, resumed = FALSE, forced = FALSE) - if(!resumed) - currentrun = SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/power/apc) - nightshift_active = active - if(announce) - if (active) - announce("Good evening, crew. To reduce power consumption and stimulate the circadian rhythms of some species, all of the lights aboard the station have been dimmed for the night.") - else - announce("Good morning, crew. As it is now day time, all of the lights aboard the station have been restored to their former brightness.") - for(var/obj/machinery/power/apc/APC as anything in currentrun) - currentrun -= APC - if (APC.area && (APC.area.type in GLOB.the_station_areas)) - APC.set_nightshift(nightshift_active) - if(MC_TICK_CHECK && !forced) // subsystem will be in state SS_IDLE if forced by an admin - return diff --git a/code/controllers/subsystem/ore_generation.dm b/code/controllers/subsystem/ore_generation.dm index 7f51c2bcbbe..348a5ec1880 100644 --- a/code/controllers/subsystem/ore_generation.dm +++ b/code/controllers/subsystem/ore_generation.dm @@ -20,6 +20,12 @@ SUBSYSTEM_DEF(ore_generation) * If we call cave_generation more than once, we copy a list from the lists in lists/ores_spawned.dm */ var/list/ore_vent_minerals = list() + /// List of ore turfs that want to be randomized + var/list/turf/closed/mineral/random/ore_turfs = list() + /// Amount of ores by type generated + var/list/ores_generated = list() + /// Probabilities by type and depth to generate ores + var/list/list/list/ore_spread_probabilities = list() /datum/controller/subsystem/ore_generation/Initialize() /// First, lets sort each ore_vent here based on their distance to the landmark, then we'll assign sizes. @@ -64,30 +70,6 @@ SUBSYSTEM_DEF(ore_generation) continue //Ya'll already got your minerals. vent.generate_mineral_breakdown(map_loading = TRUE) - - /// Handles roundstart logging - logger.Log( - LOG_CATEGORY_CAVE_GENERATION, - "Ore Generation spawned the following ores based on vent proximity", - list( - "[ORE_WALL_FAR]" = GLOB.post_ore_random["[ORE_WALL_FAR]"], - "[ORE_WALL_LOW]" = GLOB.post_ore_random["[ORE_WALL_LOW]"], - "[ORE_WALL_MEDIUM]" = GLOB.post_ore_random["[ORE_WALL_MEDIUM]"], - "[ORE_WALL_HIGH]" = GLOB.post_ore_random["[ORE_WALL_HIGH]"], - "[ORE_WALL_VERY_HIGH]" = GLOB.post_ore_random["[ORE_WALL_VERY_HIGH]"], - ), - ) - logger.Log( - LOG_CATEGORY_CAVE_GENERATION, - "Ore Generation spawned the following ores randomly", - list( - "[ORE_WALL_FAR]" = GLOB.post_ore_manual["[ORE_WALL_FAR]"], - "[ORE_WALL_LOW]" = GLOB.post_ore_manual["[ORE_WALL_LOW]"], - "[ORE_WALL_MEDIUM]" = GLOB.post_ore_manual["[ORE_WALL_MEDIUM]"], - "[ORE_WALL_HIGH]" = GLOB.post_ore_manual["[ORE_WALL_HIGH]"], - "[ORE_WALL_VERY_HIGH]" = GLOB.post_ore_manual["[ORE_WALL_VERY_HIGH]"], - ), - ) logger.Log( LOG_CATEGORY_CAVE_GENERATION, "Ore Generation spawned the following vent sizes", @@ -97,8 +79,68 @@ SUBSYSTEM_DEF(ore_generation) "small" = LAZYACCESS(GLOB.ore_vent_sizes, SMALL_VENT_TYPE), ), ) + + calculate_rock_edges() + for (var/turf/closed/mineral/random/rock in ore_turfs) // Typecheck in case they got destroyed + rock.randomize_ore() + + calculate_ore_spread() + return SS_INIT_SUCCESS +/// Generates debug data about ore spread among rock turfs +/datum/controller/subsystem/ore_generation/proc/calculate_ore_spread() + var/list/result = list() + var/list/totals = list("chance" = 0, "raw_sum" = 0) + var/summary_count = 0 + for (var/turf/closed/mineral/random/rock_type as anything in ore_spread_probabilities) + var/list/rock_data = ore_spread_probabilities[rock_type] + var/list/result_rock = list() + var/total_count = 0 + var/total_chance = 0 + for (var/spread_range in rock_data) + var/list/dist_info = rock_data[spread_range] + for (var/ore_type in dist_info - list("chance", "count")) + if (!result_rock[ore_type]) + result_rock[ore_type] = 0 + result_rock[ore_type] += dist_info[ore_type] * dist_info["chance"] / initial(rock_type.mineral_chance) * dist_info["count"] + total_count += dist_info["count"] + total_chance += dist_info["chance"] * dist_info["count"] + + result_rock["chance"] = total_chance / total_count + result_rock["count"] = total_count + totals["chance"] += total_chance + summary_count += total_count + result[rock_type] = result_rock + + for (var/turf/closed/mineral/random/rock_type as anything in result) + var/list/rock_data = result[rock_type] + var/raw_sum = 0 + for (var/ore_type in rock_data) + if (!ispath(ore_type)) + continue + rock_data[ore_type] /= summary_count + raw_sum += rock_data[ore_type] + if (!totals[ore_type]) + totals[ore_type] = 0 + if (ispath(ore_type, /turf/closed/mineral/gibtonite/volcanic)) + totals[/turf/closed/mineral/gibtonite/volcanic] += rock_data[ore_type] + else + totals[ore_type] += rock_data[ore_type] + rock_data["raw_sum"] = raw_sum + totals["raw_sum"] += raw_sum + + for (var/spawn_type in totals) + if (!ispath(spawn_type)) + continue + totals[spawn_type] /= totals["raw_sum"] / 104 + + totals["count"] = summary_count + if (summary_count > 0) + totals["chance"] /= summary_count + result["total"] = totals + ore_spread_probabilities = result + /datum/controller/subsystem/ore_generation/fire(resumed) available_boulders.Cut() // reset upon new fire. for(var/obj/structure/ore_vent/current_vent as anything in processed_vents) diff --git a/code/controllers/subsystem/pathfinder.dm b/code/controllers/subsystem/pathfinder.dm index b67260853ba..bcb9861fbb6 100644 --- a/code/controllers/subsystem/pathfinder.dm +++ b/code/controllers/subsystem/pathfinder.dm @@ -185,6 +185,39 @@ SUBSYSTEM_DEF(pathfinder) return constructing return null +/// Builds a single directional arrow image for a path step visualization +/datum/controller/subsystem/pathfinder/proc/render_path_arrow(turf/draw, direction) + var/image/arrow = image('icons/turf/debug.dmi', draw, "arrow", PATH_ARROW_DEBUG_LAYER, direction) + SET_PLANE_EXPLICIT(arrow, BALLOON_CHAT_PLANE, draw) + return arrow + +///Renders a full path of arrows, showing the direction taken from each tile. +/datum/controller/subsystem/pathfinder/proc/render_path_images(list/turf/draw_list) + if(!length(draw_list)) + return list() + var/list/image/turf_images = list() + for(var/i in 1 to (length(draw_list) - 1)) + var/turf/T = draw_list[i] + var/turf/next = draw_list[i + 1] + turf_images += render_path_arrow(T, get_dir(T, next)) + return turf_images + +/// Renders a full path visualisation: start marker, directional arrows along the path, end marker. +/datum/controller/subsystem/pathfinder/proc/render_path_images_full(list/turf/draw_list) + if(!length(draw_list)) + return list() + var/list/image/turf_images = list() + var/turf/first = draw_list[1] + var/image/start = image('icons/turf/debug.dmi', first, "start", PATH_DEBUG_LAYER) + SET_PLANE_EXPLICIT(start, BALLOON_CHAT_PLANE, first) + turf_images += start + turf_images += render_path_images(draw_list) + var/turf/last = draw_list[length(draw_list)] + var/image/end = image('icons/turf/debug.dmi', last, "end", PATH_DEBUG_LAYER) + SET_PLANE_EXPLICIT(end, BALLOON_CHAT_PLANE, last) + turf_images += end + return turf_images + /// Takes a set of pathfind info, returns all valid pathmaps that would work /// Takes an optional minimum range arg /datum/controller/subsystem/pathfinder/proc/get_valid_maps(datum/can_pass_info/pass_info, turf/target, simulated_only = TRUE, turf/exclude, age = MAP_REUSE_INSTANT, min_range = -INFINITY, include_building = FALSE) diff --git a/code/controllers/subsystem/persistence/recipes.dm b/code/controllers/subsystem/persistence/recipes.dm index c1d72d8d908..828f856b76a 100644 --- a/code/controllers/subsystem/persistence/recipes.dm +++ b/code/controllers/subsystem/persistence/recipes.dm @@ -6,6 +6,8 @@ //asert globchems done for(var/randomized_type in subtypesof(/datum/chemical_reaction/randomized)) var/datum/chemical_reaction/randomized/R = GLOB.chemical_reactions_list[randomized_type] + if(!R) + continue file_data["[R.type]"] = list( timestamp = R.created, required_reagents = R.required_reagents, diff --git a/code/controllers/subsystem/persistence/tattoos.dm b/code/controllers/subsystem/persistence/tattoos.dm index 45dd31c7f5c..d4b7ded137a 100644 --- a/code/controllers/subsystem/persistence/tattoos.dm +++ b/code/controllers/subsystem/persistence/tattoos.dm @@ -35,7 +35,7 @@ entries += prison_tattoos_to_save - saved_data["version"] = ENGRAVING_PERSISTENCE_VERSION + saved_data["version"] = TATTOO_PERSISTENCE_VERSION saved_data["entries"] = entries fdel(json_file) diff --git a/code/controllers/subsystem/processing/ai_behaviors.dm b/code/controllers/subsystem/processing/ai_behaviors.dm index 7304c5ed362..aa5ef4eb55c 100644 --- a/code/controllers/subsystem/processing/ai_behaviors.dm +++ b/code/controllers/subsystem/processing/ai_behaviors.dm @@ -8,24 +8,33 @@ PROCESSING_SUBSYSTEM_DEF(ai_behaviors) /datum/controller/subsystem/movement/ai_movement, ) wait = 1 - ///List of all ai_behavior singletons, key is the typepath while assigned value is a newly created instance of the typepath. See SetupAIBehaviors() + /// List of all ai_behavior singletons, key is the typepath while assigned value is a newly created instance of the typepath. See setup_ai_behaviors() var/list/ai_behaviors - ///List of all targeting_strategy singletons, key is the typepath while assigned value is a newly created instance of the typepath. See SetupAIBehaviors() + /// List of all targeting_strategy singletons, key is the typepath while assigned value is a newly created instance of the typepath. See setup_targeting_strats() var/list/targeting_strategies + /// List of all target_priority_strategy singletons, key is the typepath while assigned value is a newly created instance of the typepath. See setup_target_priority_strats() + var/list/target_priority_strategies /datum/controller/subsystem/processing/ai_behaviors/Initialize() - SetupAIBehaviors() - SetupTargetingStrats() + setup_ai_behaviors() + setup_targeting_strats() + setup_target_priority_strats() return SS_INIT_SUCCESS -/datum/controller/subsystem/processing/ai_behaviors/proc/SetupAIBehaviors() +/datum/controller/subsystem/processing/ai_behaviors/proc/setup_ai_behaviors() ai_behaviors = list() for(var/behavior_type in subtypesof(/datum/ai_behavior)) var/datum/ai_behavior/ai_behavior = new behavior_type ai_behaviors[behavior_type] = ai_behavior -/datum/controller/subsystem/processing/ai_behaviors/proc/SetupTargetingStrats() +/datum/controller/subsystem/processing/ai_behaviors/proc/setup_targeting_strats() targeting_strategies = list() for(var/target_type in subtypesof(/datum/targeting_strategy)) var/datum/targeting_strategy/target_start = new target_type targeting_strategies[target_type] = target_start + +/datum/controller/subsystem/processing/ai_behaviors/proc/setup_target_priority_strats() + target_priority_strategies = list() + for(var/target_type in subtypesof(/datum/target_priority_strategy)) + var/datum/target_priority_strategy/target_start = new target_type + target_priority_strategies[target_type] = target_start diff --git a/code/controllers/subsystem/processing/quirks.dm b/code/controllers/subsystem/processing/quirks.dm index 02e811f2dc4..d6fb787a5cd 100644 --- a/code/controllers/subsystem/processing/quirks.dm +++ b/code/controllers/subsystem/processing/quirks.dm @@ -79,8 +79,17 @@ PROCESSING_SUBSYSTEM_DEF(quirks) var/list/quirk_points = list() //Assoc. list of quirk names and their "point cost"; positive numbers are good traits, and negative ones are bad ///An assoc list of quirks that can be obtained as a hardcore character, and their hardcore value. var/list/hardcore_quirks = list() + /// Whether or not quirk points are enabled, per server config + var/points_enabled + /// The number of max positive quirks that we allow, per server config + var/max_positive_quirks + // The default number of quirk points that you get to spend, per server config + var/default_quirk_points /datum/controller/subsystem/processing/quirks/Initialize() + points_enabled = !CONFIG_GET(flag/disable_quirk_points) + max_positive_quirks = CONFIG_GET(number/max_positive_quirks) + default_quirk_points = CONFIG_GET(number/default_quirk_points) get_quirks() return SS_INIT_SUCCESS @@ -145,7 +154,6 @@ PROCESSING_SUBSYSTEM_DEF(quirks) ///Cached list of possible quirks var/list/possible_quirks = quirks.Copy() - var/max_positive_quirks = CONFIG_GET(number/max_positive_quirks) if(max_positive_quirks < 0) max_positive_quirks = 6 @@ -209,9 +217,7 @@ PROCESSING_SUBSYSTEM_DEF(quirks) /datum/controller/subsystem/processing/quirks/proc/filter_invalid_quirks(list/quirks, list/augments) // SKYRAT EDIT - AUGMENTS+ var/list/new_quirks = list() var/list/positive_quirks = list() - var/points_enabled = !CONFIG_GET(flag/disable_quirk_points) - var/max_positive_quirks = CONFIG_GET(number/max_positive_quirks) - var/balance = -CONFIG_GET(number/default_quirk_points) + var/balance = -default_quirk_points var/list/all_quirks = get_quirks() diff --git a/code/controllers/subsystem/security_level.dm b/code/controllers/subsystem/security_level.dm index 2e48d593fae..c88237ec7ea 100644 --- a/code/controllers/subsystem/security_level.dm +++ b/code/controllers/subsystem/security_level.dm @@ -42,9 +42,6 @@ SUBSYSTEM_DEF(security_level) if(!selected_level) CRASH("set_level was called with an invalid security level([new_level])") - if(SSnightshift.can_fire && (selected_level.number_level >= SEC_LEVEL_RED || current_security_level.number_level >= SEC_LEVEL_RED)) - SSnightshift.next_fire = world.time + 7 SECONDS // Fire nightshift after the security level announcement is complete - if(announce) level_announce(selected_level, current_security_level.number_level) // We want to announce BEFORE updating to the new level diff --git a/code/controllers/subsystem/server_maint.dm b/code/controllers/subsystem/server_maint.dm index 44a13093a7f..e26e142015e 100644 --- a/code/controllers/subsystem/server_maint.dm +++ b/code/controllers/subsystem/server_maint.dm @@ -66,8 +66,7 @@ SUBSYSTEM_DEF(server_maint) var/afk_period if(kick_inactive) afk_period = CONFIG_GET(number/afk_period) - for(var/I in currentrun) - var/client/C = I + for(var/client/C as anything in currentrun) //handle kicking inactive players if(round_started && kick_inactive && !C.holder && C.is_afk(afk_period)) var/cmob = C.mob @@ -77,9 +76,6 @@ SUBSYSTEM_DEF(server_maint) QDEL_IN(C, 1) //to ensure they get our message before getting disconnected continue - if (!(!C || world.time - C.connection_time < PING_BUFFER_TIME || C.inactivity >= (wait-1))) - winset(C, null, "command=.update_ping+[num2text(world.time+world.tick_lag*TICK_USAGE_REAL/100, 32)]") - if (MC_TICK_CHECK) //one day, when ss13 has 1000 people per server, you guys are gonna be glad I added this tick check return diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm index 68efe52087d..ce9fd1f0ce1 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -188,9 +188,6 @@ SUBSYSTEM_DEF(shuttle) supply_packs[pack.id] = pack - for (var/obj/machinery/computer/cargo/express/console as anything in express_consoles) - console.packin_up(TRUE) - setup_shuttles(stationary_docking_ports) has_purchase_shuttle_access = init_has_purchase_shuttle_access() diff --git a/code/controllers/subsystem/statpanel.dm b/code/controllers/subsystem/statpanel.dm index 82bfaa8bb40..996ca7a9243 100644 --- a/code/controllers/subsystem/statpanel.dm +++ b/code/controllers/subsystem/statpanel.dm @@ -46,11 +46,12 @@ SUBSYSTEM_DEF(statpanels) "Round ID: [GLOB.round_id ? GLOB.round_id : "NULL"]", "Connected: [GLOB.clients.len] | Active: [active_players]/[CONFIG_GET(number/hard_popcap)] | Observing: [observing_players]", // BUBBER EDIT ADDITION - Extra stat panel info "OOC: [GLOB.ooc_allowed ? "Enabled" : "Disabled"]", // BUBBER EDIT ADDITION - Extra stat panel info - " ", // BUBBER EDIT ADDITION - Extra stat panel info "Storyteller: [SSgamemode.storyteller ? SSgamemode.storyteller.name : "N/A"]", // BUBBER EDIT ADDITION - Extra stat panel info - "Station Time: [station_time_timestamp(format = "hh:mm")], [current_date]", // BUBBER EDIT CHANGE - Extra stat panel info - ORIGINAL: "Station Time: [station_time_timestamp()]" - "Round Time: [time2text(real_round_time, "hh:mm:ss", 0)]", // BUBBER EDIT CHANGE - Extra stat panel info - ORIGINAL: "Round Time: [ROUND_TIME()]" - "Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss", world.timezone)]", + " ", // BUBBER EDIT ADDITION - Extra stat panel info + "Station Time: [round_timestamp(format = "hh:mm")], [current_date]", // BUBBER EDIT CHANGE - Extra stat panel info - ORIGINAL: "Station Time: [round_timestamp()]" + "Shift Time/PT: [(SSticker.round_start_time == 0) ? "Pre-Game" : round_timestamp()]", + "Server Time/NST: [server_timestamp(format = "YYYY-MM-DD hh:mm:ss")]", + " ", //BUBBER EDIT ADDITION - Line break "Time Dilation: [round(SStime_track.time_dilation_current,1)]% AVG:([round(SStime_track.time_dilation_avg_fast,1)]%, [round(SStime_track.time_dilation_avg,1)]%, [round(SStime_track.time_dilation_avg_slow,1)]%)", ) @@ -110,7 +111,6 @@ SUBSYSTEM_DEF(statpanels) return target.stat_panel.send_message("update_stat", list( "global_data" = global_data, - "ping_str" = "Ping: [round(target.lastping, 1)]ms (Average: [round(target.avgping, 1)]ms)", "other_str" = target.mob?.get_status_tab_items(), )) @@ -221,6 +221,3 @@ SUBSYSTEM_DEF(statpanels) else if(length(GLOB.sdql2_queries) && target.stat_tab == "SDQL2") set_SDQL2_tab(target) - -/// Stat panel window declaration -/client/var/datum/tgui_window/stat_panel diff --git a/code/controllers/subsystem/tgui.dm b/code/controllers/subsystem/tgui.dm index 9f5d518b6c2..df33cf68c8c 100644 --- a/code/controllers/subsystem/tgui.dm +++ b/code/controllers/subsystem/tgui.dm @@ -37,7 +37,7 @@ SUBSYSTEM_DEF(tgui) ntos_error = "" basehtml = replacetextEx(basehtml, "", ntos_error) - basehtml = replacetextEx(basehtml, "", "Nanotrasen (c) 2525-[text2num(UTC_YEAR) + STATION_YEAR_OFFSET]") // This can't use the GLOB as it runs before those are populated + basehtml = replacetextEx(basehtml, "", "Nanotrasen (c) 2525-[CURRENT_STATION_YEAR]") /datum/controller/subsystem/tgui/OnConfigLoad() var/storage_iframe = CONFIG_GET(string/storage_cdn_iframe) diff --git a/code/controllers/subsystem/throwing.dm b/code/controllers/subsystem/throwing.dm index 45dc79f6ac9..dd879a91028 100644 --- a/code/controllers/subsystem/throwing.dm +++ b/code/controllers/subsystem/throwing.dm @@ -5,7 +5,7 @@ SUBSYSTEM_DEF(throwing) name = "Throwing" priority = FIRE_PRIORITY_THROWING wait = 1 - ss_flags = SS_NO_INIT|SS_KEEP_TIMING|SS_TICKER + ss_flags = SS_NO_INIT | SS_TICKER runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME var/list/currentrun diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 7c3db277461..1fda1099c15 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -38,10 +38,6 @@ SUBSYSTEM_DEF(ticker) var/timeLeft //pregame timer var/start_at - var/gametime_offset = 432000 //Deciseconds to add to world.time for station time. - var/station_time_rate_multiplier = 2 //factor of station time progressal vs real time. // BUBBER EDIT CHANGE - SERVER TIME OFFSET - ORIGINAL: 12 - var/server_time_offset // Offset between server time and station time // BUBBER EDIT ADDITION - SERVER TIME OFFSET - /// Num of players, used for pregame stats on statpanel var/totalPlayers = 0 /// Num of ready players, used for pregame stats on statpanel (only viewable by admins) @@ -135,26 +131,13 @@ SUBSYSTEM_DEF(ticker) GLOB.syndicate_code_response_regex = codeword_match start_at = world.time + (CONFIG_GET(number/lobby_countdown) * (1 SECONDS)) - round_start_time = start_at // May be changed later, but prevents the time from jumping back when the round actually starts - server_time_offset = (CONFIG_GET(number/shift_time_clock_offset) * (1 MINUTES)) // BUBBER EDIT ADD: SERVER TIME OFFSET - if(CONFIG_GET(flag/randomize_shift_time)) - gametime_offset = rand(0, 23) * (1 HOURS) - else if(CONFIG_GET(flag/shift_time_realtime)) - gametime_offset = world.timeofday + GLOB.timezoneOffset + server_time_offset // BUBBER EDIT CHANGE - SERVER TIME OFFSET - ORIGINAL: gametime_offset = world.timeofday + GLOB.timezoneOffset - // station_time_rate_multiplier = 1 // BUBBER EDIT REMOVAL - else - gametime_offset = (CONFIG_GET(number/shift_time_start_hour) * (1 HOURS)) - // BUBBER EDIT ADD BEGIN - SERVER TIME OFFSET - message_admins("Station time set to [station_time_timestamp(format = "hh:mm")]. Night shift transitions are [SSnightshift.can_fire ? span_vote_notice("enabled") : span_comradio("disabled")].") - log_dynamic("Station time set to [station_time_timestamp(format = "hh:mm")]. Server time: [time2text(world.timeofday, "hh:mm", world.timezone)]. Server time offset: [server_time_offset / (1 MINUTES)] min. Night shift transitions are [SSnightshift.can_fire ? "enabled" : "disabled"].") - // BUBBER EDIT ADD END - SERVER TIME OFFSET return SS_INIT_SUCCESS /datum/controller/subsystem/ticker/fire() switch(current_state) if(GAME_STATE_STARTUP) if(Master.initializations_finished_with_no_players_logged_in) - start_at = world.time + (CONFIG_GET(number/lobby_countdown) * 10) + start_at = world.time + (CONFIG_GET(number/lobby_countdown) * (1 SECONDS)) 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()]!")) @@ -178,9 +161,9 @@ SUBSYSTEM_DEF(ticker) fire() if(GAME_STATE_PREGAME) - //lobby stats for statpanels + //lobby stats for statpanels if(isnull(timeLeft)) - timeLeft = max(0,start_at - world.time) + timeLeft = max(0, start_at - world.time) totalPlayers = LAZYLEN(GLOB.new_player_list) totalPlayersReady = 0 total_admins_ready = 0 @@ -217,7 +200,7 @@ SUBSYSTEM_DEF(ticker) if(!setup()) //setup failed current_state = GAME_STATE_STARTUP - start_at = world.time + (CONFIG_GET(number/lobby_countdown) * 10) + start_at = world.time + (CONFIG_GET(number/lobby_countdown) * (1 SECONDS)) timeLeft = null Master.SetRunLevel(RUNLEVEL_LOBBY) SEND_SIGNAL(src, COMSIG_TICKER_ERROR_SETTING_UP) @@ -239,6 +222,11 @@ SUBSYSTEM_DEF(ticker) else reboot_hud.maptext = MAPTEXT_PIXELLARI("
Server rebooting in:\n\ [DisplayTimeText(timeleft(SSticker.reboot_timer), 1)]
") +/datum/controller/subsystem/ticker/vv_edit_var(var_name, var_value) + if(var_name == NAMEOF(src, login_music)) + set_lobby_music(var_value, override = TRUE) + return ..() + /// Checks if the round should be ending, called every ticker tick /datum/controller/subsystem/ticker/proc/check_finished() if(!setup_done) @@ -956,6 +944,10 @@ SUBSYSTEM_DEF(ticker) return login_music = new_music + //we just overrode the song, let's update everyone. + if(override) + for(var/mob/dead/new_player/new_player as anything in GLOB.new_player_list) + new_player?.client.playtitlemusic() #undef ROUND_START_MUSIC_LIST #undef SS_TICKER_TRAIT diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index d0ad1bd3d3a..c5d88e60f9f 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -291,6 +291,7 @@ SUBSYSTEM_DEF(vote) log_admin("[key_name(toggle_initiator)] [text_verb] Dead Vote.") message_admins("[key_name_admin(toggle_initiator)] [text_verb] Dead Vote.") SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Dead Vote", text_verb)) + update_static_data_for_all_viewers() /datum/controller/subsystem/vote/ui_state() return GLOB.always_state @@ -319,8 +320,6 @@ SUBSYSTEM_DEF(vote) "multiSelection" = current_vote?.choices_by_ckey, ) - data["voting"]= is_lower_admin ? voting : list() - var/list/all_vote_data = list() for(var/vote_name in possible_votes) var/datum/vote/vote = possible_votes[vote_name] @@ -363,6 +362,7 @@ SUBSYSTEM_DEF(vote) /datum/controller/subsystem/vote/ui_static_data(mob/user) var/list/data = list() data["VoteCD"] = CONFIG_GET(number/vote_delay) + data["deadVoteEnabled"] = CONFIG_GET(flag/no_dead_vote) return data /datum/controller/subsystem/vote/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) @@ -381,7 +381,6 @@ SUBSYSTEM_DEF(vote) voter.log_message("cancelled a vote.", LOG_ADMIN) message_admins("[key_name_admin(voter)] has cancelled the current vote.") - SStgui.close_uis(src) reset() return TRUE diff --git a/code/datums/actions/action.dm b/code/datums/actions/action.dm index 688c82eb5b0..51a163efe21 100644 --- a/code/datums/actions/action.dm +++ b/code/datums/actions/action.dm @@ -181,7 +181,13 @@ return FALSE if((check_flags & AB_CHECK_CONSCIOUS) && owner.stat != CONSCIOUS) if (feedback) - owner.balloon_alert(owner, "[owner.stat == DEAD ? "dead" : "unconscious"]!") + switch(owner.stat) + if(SOFT_CRIT) + owner.balloon_alert(owner, "downed!") + if(DEAD) + owner.balloon_alert(owner, "dead!") + else + owner.balloon_alert(owner, "unconscious!") return FALSE if((check_flags & AB_CHECK_HANDS_BLOCKED) && HAS_TRAIT(owner, TRAIT_HANDS_BLOCKED)) if (feedback) diff --git a/code/datums/actions/items/adjust.dm b/code/datums/actions/items/adjust.dm index be04a0f8dbd..13189c533c0 100644 --- a/code/datums/actions/items/adjust.dm +++ b/code/datums/actions/items/adjust.dm @@ -20,3 +20,11 @@ ..() var/obj/item/item_target = target name = "Adjust [item_target.name]'s Style" + +/datum/action/item_action/adjust_visor + name = "Adjust Visor" + +/datum/action/item_action/adjust_visor/New(Target) + ..() + var/obj/item/item_target = target + name = "Adjust [item_target.name] Visor" diff --git a/code/datums/actions/mobs/projectileattack.dm b/code/datums/actions/mobs/projectileattack.dm index bd7425cc8e7..183df71e03f 100644 --- a/code/datums/actions/mobs/projectileattack.dm +++ b/code/datums/actions/mobs/projectileattack.dm @@ -5,7 +5,7 @@ desc = "Fires a set of projectiles at a selected target." cooldown_time = 1.5 SECONDS /// The type of the projectile to be fired - var/projectile_type + var/obj/projectile/projectile_type /// The sound played when a projectile is fired var/projectile_sound /// If the projectile should home in on its target @@ -58,7 +58,7 @@ our_projectile.set_homing_target(target) if(isnum(set_angle)) our_projectile.fire(set_angle) - return + return our_projectile our_projectile.fire() return our_projectile @@ -331,7 +331,7 @@ var/mob/living/simple_animal/hostile/megafauna/colossus/colossus if(istype(firer, /mob/living/simple_animal/hostile/megafauna/colossus)) colossus = firer - colossus.say("Perish.", spans = list("colossus", "yell")) + colossus.say("Perish.", spans = list(SPAN_COLOSSUS, SPAN_YELL)) SLEEP_CHECK_DEATH(1.5 SECONDS, firer) //gives dumbasses in melee range a slim chance to retreat var/finale_counter = 10 diff --git a/code/datums/ai/_ai_behavior.dm b/code/datums/ai/_ai_behavior.dm index 4a277c0e861..a73ca167214 100644 --- a/code/datums/ai/_ai_behavior.dm +++ b/code/datums/ai/_ai_behavior.dm @@ -33,6 +33,7 @@ return clear_movement_target(controller) controller.ai_movement.stop_moving_towards(controller) + EVLOG_MAPTEXT(controller, EVLOG_CATEGORY_AI_BEHAVIORS, "[controller.pawn] has [succeeded ? "succeeded" : "failed"] at performing [src]", get_turf(controller.pawn), "Behavior finished: [succeeded ? "Success" : "Failure"]") /// Helper proc to ensure consistency in setting the source of the movement target /datum/ai_behavior/proc/set_movement_target(datum/ai_controller/controller, atom/target, datum/ai_movement/new_movement) diff --git a/code/datums/ai/_ai_controller.dm b/code/datums/ai/_ai_controller.dm index a94117c0a74..2bda59b1e7e 100644 --- a/code/datums/ai/_ai_controller.dm +++ b/code/datums/ai/_ai_controller.dm @@ -70,6 +70,7 @@ multiple modular subtrees with behaviors /// are we currently on failed planning timeout? var/on_failed_planning_timeout = FALSE + /datum/ai_controller/New(atom/new_pawn) change_ai_movement_type(ai_movement) init_subtrees() @@ -156,6 +157,8 @@ multiple modular subtrees with behaviors RegisterSignal(pawn, COMSIG_MOB_STATCHANGE, PROC_REF(on_stat_changed)) RegisterSignal(pawn, COMSIG_MOB_LOGIN, PROC_REF(on_sentience_gained)) RegisterSignal(pawn, COMSIG_QDELETING, PROC_REF(on_pawn_qdeleted)) + RegisterSignal(pawn, COMSIG_EVLOGGING_ENABLED, PROC_REF(on_pawn_evlogging_enabled)) + RegisterSignal(pawn, COMSIG_EVLOGGING_DISABLED, PROC_REF(on_pawn_evlogging_disabled)) update_able_to_run() setup_able_to_run() @@ -305,7 +308,7 @@ multiple modular subtrees with behaviors SEND_SIGNAL(src, COMSIG_AI_CONTROLLER_UNPOSSESSED_PAWN) set_ai_status(AI_STATUS_OFF) - UnregisterSignal(pawn, list(COMSIG_MOVABLE_Z_CHANGED, COMSIG_MOB_LOGIN, COMSIG_MOB_LOGOUT, COMSIG_MOB_STATCHANGE, COMSIG_QDELETING)) + UnregisterSignal(pawn, list(COMSIG_MOVABLE_Z_CHANGED, COMSIG_MOB_LOGIN, COMSIG_MOB_LOGOUT, COMSIG_MOB_STATCHANGE, COMSIG_QDELETING, COMSIG_EVLOGGING_ENABLED)) clear_able_to_run() if(ai_movement.moving_controllers[src]) ai_movement.stop_moving_towards(src) @@ -426,6 +429,15 @@ multiple modular subtrees with behaviors arguments += stored_arguments forgotten_behavior.finish_action(arglist(arguments)) + if(IS_EVLOGGING) + var/list/event_text = list() + event_text += "New plan starting!" + + for(var/datum/ai_behavior/behavior in planned_behaviors) + event_text += "Queued behavior [behavior.type]" + + EVLOG_TEXT(src, EVLOG_CATEGORY_AI_DECISIONMAKING, jointext(event_text, "\n")) + ///This proc handles changing ai status, and starts/stops processing if required. /datum/ai_controller/proc/set_ai_status(new_ai_status, additional_flags = NONE) if(ai_status == new_ai_status) @@ -562,6 +574,7 @@ multiple modular subtrees with behaviors return for(var/datum/ai_behavior/current_behavior as anything in current_behaviors) fail_behavior(current_behavior) + EVLOG_TEXT(src, EVLOG_CATEGORY_AI_DECISIONMAKING, "Actions were cancelled!") /datum/ai_controller/proc/fail_behavior(datum/ai_behavior/current_behavior) var/list/arguments = list(src, FALSE) @@ -873,6 +886,8 @@ multiple modular subtrees with behaviors */ /datum/ai_controller/proc/remove_thing_from_blackboard_key(key, thing) var/associated_value = blackboard[key] + if(isnull(associated_value)) + return if(thing == associated_value) stack_trace("remove_thing_from_blackboard_key was called un-necessarily in a situation where clear_blackboard_key would suffice. ") clear_blackboard_key(key) @@ -941,6 +956,55 @@ multiple modular subtrees with behaviors index += 1 +/// When the pawn gets DF_EVLOGGING, propagate it to this controller too. +/datum/ai_controller/proc/on_pawn_evlogging_enabled(datum/source) + SIGNAL_HANDLER + enable_evlogging(pawn) + +/// When the pawn gets DF_EVLOGGING disabled, propagate it to this controller too. +/datum/ai_controller/proc/on_pawn_evlogging_disabled(datum/source) + SIGNAL_HANDLER + disable_evlogging(pawn) + +///Register for an event being added so we can update track info +/datum/ai_controller/enable_evlogging() + . = ..() + RegisterSignal(src, COMSIG_EVLOG_EVENT_ADDED, PROC_REF(on_evlog_event_added)) + +///Unregister the evlog event added event, as we're no longer updating track info +/datum/ai_controller/disable_evlogging() + . = ..() + UnregisterSignal(src, COMSIG_EVLOG_EVENT_ADDED) + +/// Called whenever an event is logged for this controller. Attaches a snapshot of current behaviors and blackboard state to the event via track_info. +/datum/ai_controller/proc/on_evlog_event_added(datum/source, datum/event_logger_track/track, list/event_data) + SIGNAL_HANDLER + var/list/track_info = list() + + var/list/current_behavior_info = list() + for(var/datum/ai_behavior/behavior in planned_behaviors) + if(behavior in current_behaviors) //Not really ideal; we should find a better way to do this. + current_behavior_info += "ACTIVE: [span_bold("[behavior.type]")]" + else + current_behavior_info += "[behavior.type]" + EVLOG_TRACK_INFO_ENTRY(track_info, "Behaviors", "Current Behavior", jointext(current_behavior_info, "\n")) + + for(var/blackboard_key_name, blackboard_value in blackboard) + var/value_string + if(isatom(blackboard_value)) + value_string = "[blackboard_value]" + else if(islist(blackboard_value)) + var/list/blackboard_list = blackboard_value + value_string = length(blackboard_list) ? jointext(blackboard_list, "\n") : "Empty List" + else if(isnull(blackboard_value)) + value_string = "null" + else // I think I covered all cases? + value_string = "[blackboard_value]" + EVLOG_TRACK_INFO_ENTRY(track_info, "Blackboard", blackboard_key_name, value_string) + + event_data["track_info"] = track_info + + #undef TRACK_AI_DATUM_TARGET #undef CLEAR_AI_DATUM_TARGET #undef TRAIT_AI_TRACKING 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 2e145c31ec4..5b41ae5254d 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 @@ -6,6 +6,8 @@ behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_MOVE_AND_PERFORM | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION ///do we finish this action after hitting once? var/terminate_after_action = FALSE + ///do we have any alternate movement behavior? + var/movement_behavior /datum/ai_behavior/basic_melee_attack/setup(datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key) . = ..() @@ -16,23 +18,14 @@ if(QDELETED(target)) return FALSE - set_movement_target(controller, target) + set_movement_target(controller, target, movement_behavior) /datum/ai_behavior/basic_melee_attack/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key) var/atom/target = controller.blackboard[target_key] if (isnull(target)) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED - if (!target.IsReachableBy(controller.pawn)) - controller.clear_blackboard_key(BB_BASIC_MOB_MELEE_COOLDOWN_TIMER) - return AI_BEHAVIOR_INSTANT - var/can_attack_time = controller.blackboard[BB_BASIC_MOB_MELEE_COOLDOWN_TIMER] - if (isnull(can_attack_time)) - var/blackboard_delay = controller.blackboard[BB_BASIC_MOB_MELEE_DELAY] - var/attack_delay = isnull(blackboard_delay) ? DEFAULT_ATTACK_DELAY : blackboard_delay - controller.set_blackboard_key(BB_BASIC_MOB_MELEE_COOLDOWN_TIMER, world.time + attack_delay) - return AI_BEHAVIOR_INSTANT - if (can_attack_time > world.time) + if (!can_attack(controller, target)) return AI_BEHAVIOR_INSTANT if (isliving(controller.pawn)) @@ -54,9 +47,28 @@ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED return AI_BEHAVIOR_DELAY +/datum/ai_behavior/basic_melee_attack/proc/can_attack(datum/ai_controller/controller, atom/target) + if (!target.IsReachableBy(controller.pawn)) + controller.clear_blackboard_key(BB_BASIC_MOB_MELEE_COOLDOWN_TIMER) + return FALSE + + var/can_attack_time = controller.blackboard[BB_BASIC_MOB_MELEE_COOLDOWN_TIMER] + if (isnull(can_attack_time)) + var/blackboard_delay = controller.blackboard[BB_BASIC_MOB_MELEE_DELAY] + var/attack_delay = isnull(blackboard_delay) ? DEFAULT_ATTACK_DELAY : blackboard_delay + controller.set_blackboard_key(BB_BASIC_MOB_MELEE_COOLDOWN_TIMER, world.time + attack_delay) + return FALSE + + if (can_attack_time > world.time) + return FALSE + + return TRUE + /datum/ai_behavior/basic_melee_attack/finish_action(datum/ai_controller/controller, succeeded, target_key, targeting_strategy_key, hiding_location_key) . = ..() controller.clear_blackboard_key(BB_BASIC_MOB_MELEE_COOLDOWN_TIMER) + if(movement_behavior) + controller.change_ai_movement_type(initial(controller.ai_movement)) if(!succeeded) controller.clear_blackboard_key(target_key) @@ -74,7 +86,7 @@ /// range we will try chasing the target before giving up var/chase_range = 9 ///do we care about avoiding friendly fire? - var/avoid_friendly_fire = FALSE + var/avoid_friendly_fire = FALSE /datum/ai_behavior/basic_ranged_attack/setup(datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key) . = ..() diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/clear_key.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/clear_key.dm new file mode 100644 index 00000000000..ae0711789fa --- /dev/null +++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/clear_key.dm @@ -0,0 +1,14 @@ +/// Clears a blackboard key (or keys), simply if you want to do this after an action without making a subtype +/datum/ai_behavior/clear_key + +/datum/ai_behavior/clear_key/perform(seconds_per_tick, datum/ai_controller/controller, list/to_clear) + return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED + +/datum/ai_behavior/clear_key/finish_action(datum/ai_controller/controller, succeeded, list/to_clear) + . = ..() + if (!to_clear) + return + if (!islist(to_clear)) + to_clear = list(to_clear) + for (var/key in to_clear) + controller.clear_blackboard_key(key) diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/targeting.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/targeting.dm index 9305c398611..b2aaaa23578 100644 --- a/code/datums/ai/basic_mobs/basic_ai_behaviors/targeting.dm +++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/targeting.dm @@ -12,6 +12,10 @@ GLOBAL_LIST_INIT(target_interested_atoms, typecacheof(list(/mob, /obj/machinery/ var/vision_range = 9 /// Blackboard key for aggro range, uses vision range if not specified var/aggro_range_key = BB_AGGRO_RANGE + /// Blackboard key for the target priority strategy + var/priority_strategy_key = BB_TARGET_PRIORITY_STRATEGY + /// If we have a priority strategy set, how often do we refresh our target search? + var/priority_refresh_cooldown = 6 SECONDS /datum/ai_behavior/find_potential_targets/get_cooldown(datum/ai_controller/cooldown_for) if(cooldown_for.blackboard[BB_FIND_TARGETS_FIELD(type)]) @@ -26,11 +30,11 @@ GLOBAL_LIST_INIT(target_interested_atoms, typecacheof(list(/mob, /obj/machinery/ CRASH("No target datum was supplied in the blackboard for [controller.pawn]") var/atom/current_target = controller.blackboard[target_key] - if (targeting_strategy.can_attack(living_mob, current_target, vision_range)) + var/datum/target_priority_strategy/priority_strategy = GET_TARGET_PRIORITY_STRATEGY(controller.blackboard[priority_strategy_key]) + if((!priority_strategy || controller.blackboard[BB_BASIC_MOB_TARGET_REFRESH_COOLDOWN] > world.time) && current_target && targeting_strategy.can_attack(living_mob, current_target, vision_range)) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED var/aggro_range = controller.blackboard[aggro_range_key] || vision_range - controller.clear_blackboard_key(target_key) // If we're using a field rn, just don't do anything yeah? @@ -46,22 +50,34 @@ GLOBAL_LIST_INIT(target_interested_atoms, typecacheof(list(/mob, /obj/machinery/ potential_targets += hostile_machine if(!potential_targets.len) - failed_to_find_anyone(controller, target_key, targeting_strategy_key, hiding_location_key) + if(!current_target) + failed_to_find_anyone(controller, target_key, targeting_strategy_key, hiding_location_key) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED var/list/filtered_targets = list() + var/current_priority = 0 + if(priority_strategy) + current_priority = priority_strategy.get_target_priority(controller, current_target) for(var/atom/pot_target in potential_targets) - if(targeting_strategy.can_attack(living_mob, pot_target))//Can we attack it? - filtered_targets += pot_target + if(!targeting_strategy.can_attack(living_mob, pot_target)) continue + if (priority_strategy && priority_strategy.get_target_priority(controller, pot_target) < current_priority) + continue + filtered_targets += pot_target if(!filtered_targets.len) - failed_to_find_anyone(controller, target_key, targeting_strategy_key, hiding_location_key) + if(!current_target) + failed_to_find_anyone(controller, target_key, targeting_strategy_key, hiding_location_key) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED var/atom/target = pick_final_target(controller, filtered_targets) + + EVLOG_MAPTEXT(controller, EVLOG_CATEGORY_AI_TARGETING, "[controller.pawn] has selected [target] as a target for blackboard key [target_key]! Behavior: [src]", get_turf(target), "Target: [target]") + EVLOG_LINES(controller, EVLOG_CATEGORY_AI_TARGETING, "Line to target", get_turf(controller.pawn), get_turf(target)) + controller.set_blackboard_key(target_key, target) + controller.set_blackboard_key(BB_BASIC_MOB_TARGET_REFRESH_COOLDOWN, world.time + priority_refresh_cooldown) var/atom/potential_hiding_location = targeting_strategy.find_hidden_mobs(living_mob, target) @@ -134,6 +150,8 @@ GLOBAL_LIST_INIT(target_interested_atoms, typecacheof(list(/mob, /obj/machinery/ // Alright, we found something acceptable, let's use it yeah? var/atom/target = pick_final_target(controller, accepted_targets) + EVLOG_MAPTEXT(controller, EVLOG_CATEGORY_AI_TARGETING, "[controller.pawn] has selected [target] as a target for blackboard key [target_key]! Behavior: [src]", get_turf(target), "Target: [target]") + EVLOG_LINES(controller, EVLOG_CATEGORY_AI_TARGETING, "Line to target", get_turf(controller.pawn), get_turf(target)) controller.set_blackboard_key(target_key, target) var/atom/potential_hiding_location = strategy.find_hidden_mobs(pawn, target) @@ -153,7 +171,10 @@ GLOBAL_LIST_INIT(target_interested_atoms, typecacheof(list(/mob, /obj/machinery/ /// Returns the desired final target from the filtered list of targets /datum/ai_behavior/find_potential_targets/proc/pick_final_target(datum/ai_controller/controller, list/filtered_targets) - return pick(filtered_targets) + var/datum/target_priority_strategy/priority_strategy = GET_TARGET_PRIORITY_STRATEGY(controller.blackboard[priority_strategy_key]) + if (!priority_strategy) + return pick(filtered_targets) + return priority_strategy.select_target(controller, filtered_targets) /// Targets with the trait specified by the BB_TARGET_PRIORITY_TRAIT blackboard key will be prioritized over the rest. /datum/ai_behavior/find_potential_targets/prioritize_trait @@ -164,7 +185,7 @@ GLOBAL_LIST_INIT(target_interested_atoms, typecacheof(list(/mob, /obj/machinery/ if(HAS_TRAIT(target, controller.blackboard[BB_TARGET_PRIORITY_TRAIT])) priority_targets += target if(length(priority_targets)) - return pick(priority_targets) + return ..(controller, priority_targets) return ..() /datum/ai_behavior/find_potential_targets/bigger_range diff --git a/code/datums/ai/basic_mobs/basic_subtrees/call_reinforcements.dm b/code/datums/ai/basic_mobs/basic_subtrees/call_reinforcements.dm index f78697b2b81..46886680d52 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/call_reinforcements.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/call_reinforcements.dm @@ -1,5 +1,3 @@ -#define REINFORCEMENTS_COOLDOWN (30 SECONDS) - /// Calls all nearby mobs that share a faction to give backup in combat /datum/ai_planning_subtree/call_reinforcements /// Blackboard key containing something to say when calling reinforcements (takes precedence over emotes) @@ -21,8 +19,6 @@ controller.queue_behavior(/datum/ai_behavior/perform_speech, call_say) else if(!isnull(call_emote)) controller.queue_behavior(/datum/ai_behavior/perform_emote, call_emote) - else - controller.queue_behavior(/datum/ai_behavior/perform_emote, "cries for help!") controller.queue_behavior(call_type) @@ -30,20 +26,43 @@ /datum/ai_planning_subtree/call_reinforcements/proc/decide_to_call(datum/ai_controller/controller) return controller.blackboard_key_exists(BB_BASIC_MOB_CURRENT_TARGET) && istype(controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET], /mob) +/datum/ai_planning_subtree/call_reinforcements/mining + call_type = /datum/ai_behavior/call_reinforcements/mining + /// Call out to all mobs in the specified range for help /datum/ai_behavior/call_reinforcements + /// How frequently can we call for reinforcements? + var/cooldown = 30 SECONDS /// Range to call reinforcements from var/reinforcements_range = 15 /datum/ai_behavior/call_reinforcements/perform(seconds_per_tick, datum/ai_controller/controller) var/mob/pawn_mob = controller.pawn for(var/mob/other_mob in oview(reinforcements_range, pawn_mob)) - if(pawn_mob.faction_check_atom(other_mob) && !isnull(other_mob.ai_controller)) - // Add our current target to their retaliate list so that they'll attack our aggressor - other_mob.ai_controller.insert_blackboard_key_lazylist(BB_BASIC_MOB_RETALIATE_LIST, controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]) - other_mob.ai_controller.set_blackboard_key(BB_BASIC_MOB_REINFORCEMENT_TARGET, pawn_mob) + if(!pawn_mob.faction_check_atom(other_mob) || isnull(other_mob.ai_controller)) + continue + // Add our current target to their retaliate list so that they'll attack our aggressor + other_mob.ai_controller.set_blackboard_key_assoc_lazylist(BB_BASIC_MOB_RETALIATE_LIST, controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET], world.time) + other_mob.ai_controller.set_blackboard_key(BB_BASIC_MOB_REINFORCEMENT_TARGET, pawn_mob) - controller.set_blackboard_key(BB_BASIC_MOB_REINFORCEMENTS_COOLDOWN, world.time + REINFORCEMENTS_COOLDOWN) + controller.set_blackboard_key(BB_BASIC_MOB_REINFORCEMENTS_COOLDOWN, world.time + cooldown) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED -#undef REINFORCEMENTS_COOLDOWN +/// Does not force retaliation, but increases targeting priority instead +/datum/ai_behavior/call_reinforcements/mining + cooldown = 1 SECONDS + reinforcements_range = 7 + +/datum/ai_behavior/call_reinforcements/mining/perform(seconds_per_tick, datum/ai_controller/controller) + var/mob/pawn_mob = controller.pawn + var/atom/target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET] + for(var/mob/other_mob in oview(reinforcements_range, pawn_mob)) + if(!pawn_mob.faction_check_atom(other_mob) || isnull(other_mob.ai_controller)) + continue + var/list/existing_requests = other_mob.ai_controller.blackboard[BB_MINING_MOB_REINFORCEMENTS_REQUESTS] + if (!existing_requests || !existing_requests[target]) + other_mob.ai_controller.set_blackboard_key_assoc_lazylist(BB_MINING_MOB_REINFORCEMENTS_REQUESTS, target, list()) + other_mob.ai_controller.add_blackboard_key_assoc(BB_MINING_MOB_REINFORCEMENTS_REQUESTS, target, world.time) + + controller.set_blackboard_key(BB_BASIC_MOB_REINFORCEMENTS_COOLDOWN, world.time + cooldown) + return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED diff --git a/code/datums/ai/basic_mobs/basic_subtrees/capricious_retaliate.dm b/code/datums/ai/basic_mobs/basic_subtrees/capricious_retaliate.dm index 52b19036b9a..211e01be1f2 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/capricious_retaliate.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/capricious_retaliate.dm @@ -49,7 +49,7 @@ failed_targeting(pawn) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED - controller.insert_blackboard_key_lazylist(BB_BASIC_MOB_RETALIATE_LIST, final_target) + controller.set_blackboard_key_assoc_lazylist(BB_BASIC_MOB_RETALIATE_LIST, final_target, world.time) pawn.visible_message(span_warning("[pawn] glares grumpily at [final_target]!")) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED 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 12875f9a3f3..6edc631c7a1 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/mine_walls.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/mine_walls.dm @@ -21,6 +21,7 @@ set_movement_target(controller, target) /datum/ai_behavior/mine_wall/perform(seconds_per_tick, datum/ai_controller/controller, target_key) + . = ..() 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) diff --git a/code/datums/ai/basic_mobs/basic_subtrees/simple_find_target.dm b/code/datums/ai/basic_mobs/basic_subtrees/simple_find_target.dm index 52524852961..9824d41f823 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/simple_find_target.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/simple_find_target.dm @@ -3,10 +3,12 @@ var/target_key = BB_BASIC_MOB_CURRENT_TARGET /// Targeting strategy key to use var/strategy_key = BB_TARGETING_STRATEGY + /// Behavior to use to find targets + var/target_behavior = /datum/ai_behavior/find_potential_targets /datum/ai_planning_subtree/simple_find_target/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) . = ..() - controller.queue_behavior(/datum/ai_behavior/find_potential_targets, target_key, strategy_key, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION) + controller.queue_behavior(target_behavior, target_key, strategy_key, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION) // Prevents finding a target if a human is nearby /datum/ai_planning_subtree/simple_find_target/not_while_observed @@ -21,9 +23,8 @@ target_key = BB_BASIC_MOB_FLEE_TARGET /datum/ai_planning_subtree/simple_find_target/increased_range - -/datum/ai_planning_subtree/simple_find_target/increased_range/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) - controller.queue_behavior(/datum/ai_behavior/find_potential_targets/bigger_range, target_key, strategy_key, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION) + target_behavior = /datum/ai_behavior/find_potential_targets/bigger_range /datum/ai_planning_subtree/simple_find_target/hunt strategy_key = BB_HUNT_TARGETING_STRATEGY + diff --git a/code/datums/ai/basic_mobs/basic_subtrees/target_retaliate.dm b/code/datums/ai/basic_mobs/basic_subtrees/target_retaliate.dm index 6893bad6f6a..c8699405461 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/target_retaliate.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/target_retaliate.dm @@ -9,9 +9,11 @@ var/hiding_place_key = BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION /// do we check for faction? var/check_faction = FALSE + /// Behavior to use to select our target + var/target_behavior = /datum/ai_behavior/target_from_retaliate_list /datum/ai_planning_subtree/target_retaliate/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) - controller.queue_behavior(/datum/ai_behavior/target_from_retaliate_list, BB_BASIC_MOB_RETALIATE_LIST, target_key, targeting_strategy_key, hiding_place_key, check_faction) + controller.queue_behavior(target_behavior, BB_BASIC_MOB_RETALIATE_LIST, target_key, targeting_strategy_key, hiding_place_key, check_faction) /datum/ai_planning_subtree/target_retaliate/check_faction check_faction = TRUE @@ -43,6 +45,12 @@ var/list/shitlist = controller.blackboard[shitlist_key] var/atom/existing_target = controller.blackboard[target_key] + var/datum/target_priority_strategy/priority_strategy = GET_TARGET_PRIORITY_STRATEGY(controller.blackboard[BB_TARGET_PRIORITY_STRATEGY]) + var/existing_priority = 0 + // If we have an existing target and its priority is higher than our new target's, don't switch focus + if (priority_strategy && existing_target) + existing_priority = priority_strategy.get_target_priority(controller, existing_target) + if (!check_faction) controller.set_blackboard_key(BB_TEMPORARILY_IGNORE_FACTION, TRUE) @@ -53,13 +61,12 @@ for(var/mob/living/potential_target as anything in shitlist) if(!targeting_strategy.can_attack(living_mob, potential_target, vision_range)) continue + // Strict comparasion because priority strategies might not care about retaliation, so this makes existing targets not override potential retaliates + if (priority_strategy && priority_strategy.get_target_priority(controller, potential_target) < existing_priority) + continue enemies_list += potential_target if(!length(enemies_list)) - - if(existing_target) - controller.clear_blackboard_key(target_key) - return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED var/atom/new_target = pick_final_target(controller, enemies_list) @@ -74,7 +81,10 @@ /// Returns the desired final target from the filtered list of enemies /datum/ai_behavior/target_from_retaliate_list/proc/pick_final_target(datum/ai_controller/controller, list/enemies_list) - return pick(enemies_list) + var/datum/target_priority_strategy/priority_strategy = GET_TARGET_PRIORITY_STRATEGY(controller.blackboard[BB_TARGET_PRIORITY_STRATEGY]) + if (!priority_strategy) + return pick(enemies_list) + return priority_strategy.select_target(controller, enemies_list) /datum/ai_behavior/target_from_retaliate_list/finish_action(datum/ai_controller/controller, succeeded, shitlist_key, target_key, targeting_strategy_key, hiding_location_key, check_faction) . = ..() diff --git a/code/datums/ai/basic_mobs/target_priority_strategies/_target_priority_strategy.dm b/code/datums/ai/basic_mobs/target_priority_strategies/_target_priority_strategy.dm new file mode 100644 index 00000000000..3cb58ba086c --- /dev/null +++ b/code/datums/ai/basic_mobs/target_priority_strategies/_target_priority_strategy.dm @@ -0,0 +1,13 @@ +/// Target priority datum, exists to allow mobs to have custom targeting priorities. Singleton. +/datum/target_priority_strategy + +/// Returns a number representing the priority of a target, higher -> more likely to attack +/datum/target_priority_strategy/proc/get_target_priority(datum/ai_controller/controller, atom/target) + return 1 + +/// Returns a single atom from the list of passed targets +/datum/target_priority_strategy/proc/select_target(datum/ai_controller/controller, list/atom/targets) + var/list/target_priorities = list() + for (var/atom/target as anything in targets) + target_priorities[target] = get_target_priority(controller, target) + return pick_weight(target_priorities) diff --git a/code/datums/ai/basic_mobs/target_priority_strategies/mining_strategies.dm b/code/datums/ai/basic_mobs/target_priority_strategies/mining_strategies.dm new file mode 100644 index 00000000000..569f23fff18 --- /dev/null +++ b/code/datums/ai/basic_mobs/target_priority_strategies/mining_strategies.dm @@ -0,0 +1,89 @@ +/// Ashies get lower priorities than humans +#define AGGRO_PRIORITY_ASHWALKER 1 +/// Basicmobs have slightly less priority so that miners are targeted over their raptors +#define AGGRO_PRIORITY_BASICMOB 3 +/// Everyone by default +#define AGGRO_PRIORITY_HUMAN 5 +/// Mobs who have attacked someone in our view recently +#define AGGRO_PRIORITY_MINER 8 +/// NODE drone priority +#define AGGRO_PRIORITY_NODE 10 +/// NODE drone priority for legion broods and brimdemons +#define AGGRO_PRIORITY_NODE_LOW_PRIO 3 +/// Priority for mobs we're retaliating against +#define AGGRO_PRIORITY_RETALIATE 15 + +/// Prioritizes NODE drones until attacked, then swaps back onto miners +/datum/target_priority_strategy/mining + /// For how long do we keep aggro on mobs over NODE drones? + var/retaliate_aggro_memory = 25 SECONDS + /// Priority for NODE drones + var/node_priority = AGGRO_PRIORITY_NODE + +/datum/target_priority_strategy/mining/get_target_priority(datum/ai_controller/controller, mob/living/target) + if (!isliving(target)) + return ..() + + // If a mob recently attacked us, it has higher priority than NODE drones, otherwise we care about NODE drones more + var/list/shitlist = controller.blackboard[BB_BASIC_MOB_RETALIATE_LIST] + if (shitlist?[target] && (shitlist[target] + retaliate_aggro_memory > world.time)) + // Does not decay until it passes the retaliate memory threshold to avoid constant target swapping + return AGGRO_PRIORITY_RETALIATE + + if (istype(target, /mob/living/basic/node_drone)) + return node_priority + + // Check if they've recently attacked any of our friends, if so - increase their priority by 1 for each attack in the past [retaliate_aggro_memory] seconds + var/list/allies_shitlist = controller.blackboard[BB_MINING_MOB_REINFORCEMENTS_REQUESTS] + var/list/target_requests = allies_shitlist?[target] + var/aggro_boost = 0 + if (target_requests) + var/total_requests = length(target_requests) + // Goes end-to-start because we do not care about requests older than [retaliate_aggro_memory] + for (var/i in 1 to total_requests) + var/request_time = target_requests[total_requests - i + 1] + if (request_time + retaliate_aggro_memory < world.time) + break + aggro_boost += 1 + + if (aggro_boost || HAS_TRAIT(target, TRAIT_MINING_AGGRO)) + return AGGRO_PRIORITY_MINER + aggro_boost + + if (isbasicmob(target)) + return AGGRO_PRIORITY_BASICMOB + + return target.has_faction(FACTION_ASHWALKER) ? AGGRO_PRIORITY_ASHWALKER : AGGRO_PRIORITY_HUMAN + +/datum/target_priority_strategy/mining/select_target(datum/ai_controller/controller, list/atom/targets) + var/max_priority = 0 + var/min_distance = INFINITY + var/lucky_fella = null + + // Selects highest priority targets, then picks the closest + for (var/atom/target as anything in targets) + var/target_prio = get_target_priority(controller, target) + if (target_prio < max_priority) + continue + + if (target_prio > max_priority) + max_priority = target_prio + min_distance = INFINITY + + var/target_dist = get_dist(controller.pawn, target) + if (target_dist < min_distance) + lucky_fella = target + min_distance = target_dist + + return pick(lucky_fella) + +/datum/target_priority_strategy/mining/low_node_priority + // Higher than normal humans but will instantly pivot towards anyone who attacks or attacked mobs in our vicinity + node_priority = AGGRO_PRIORITY_NODE_LOW_PRIO + +#undef AGGRO_PRIORITY_ASHWALKER +#undef AGGRO_PRIORITY_BASICMOB +#undef AGGRO_PRIORITY_HUMAN +#undef AGGRO_PRIORITY_MINER +#undef AGGRO_PRIORITY_NODE +#undef AGGRO_PRIORITY_NODE_LOW_PRIO +#undef AGGRO_PRIORITY_RETALIATE diff --git a/code/datums/ai/basic_mobs/targeting_strategies/_targeting_strategy.dm b/code/datums/ai/basic_mobs/targeting_strategies/_targeting_strategy.dm index dbd2028081b..5720602c6fc 100644 --- a/code/datums/ai/basic_mobs/targeting_strategies/_targeting_strategy.dm +++ b/code/datums/ai/basic_mobs/targeting_strategies/_targeting_strategy.dm @@ -13,6 +13,12 @@ target_hiding_location = target.loc return target_hiding_location +/// Simply always returns true if you have a target, so only use this if you're pre-checking the targets somewhere else +/datum/targeting_strategy/anything + +/datum/targeting_strategy/anything/can_attack(mob/living/living_mob, atom/target, vision_range) + return !!target + ///A very simple targeting strategy that checks that the target is a valid fishing spot. /datum/targeting_strategy/fishing diff --git a/code/datums/ai/dog/dog_behaviors.dm b/code/datums/ai/dog/dog_behaviors.dm index 6ae1529d470..dc031a1d3f1 100644 --- a/code/datums/ai/dog/dog_behaviors.dm +++ b/code/datums/ai/dog/dog_behaviors.dm @@ -27,16 +27,8 @@ paw_harmlessly(living_pawn, target, seconds_per_tick) return AI_BEHAVIOR_INSTANT - // Give Ian some teeth - var/old_melee_lower = living_pawn.melee_damage_lower - var/old_melee_upper = living_pawn.melee_damage_upper - living_pawn.melee_damage_lower = max(5, old_melee_lower) - living_pawn.melee_damage_upper = max(10, old_melee_upper) - . = ..() // Bite time - living_pawn.melee_damage_lower = old_melee_lower - living_pawn.melee_damage_upper = old_melee_upper return AI_BEHAVIOR_DELAY /// Swat at someone we don't like but won't hurt diff --git a/code/datums/ai/generic/find_and_set.dm b/code/datums/ai/generic/find_and_set.dm index 9ec033e0402..ced56912c91 100644 --- a/code/datums/ai/generic/find_and_set.dm +++ b/code/datums/ai/generic/find_and_set.dm @@ -14,6 +14,9 @@ var/find_this_thing = search_tactic(controller, locate_path, search_range) if(isnull(find_this_thing)) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED + + EVLOG_MAPTEXT(controller, EVLOG_CATEGORY_AI_TARGETING, "[controller.pawn] has selected [find_this_thing] as a target for blackboard key [set_key]! Behavior: [src]", get_turf(find_this_thing), "Target: [find_this_thing]") + EVLOG_LINES(controller, EVLOG_CATEGORY_AI_TARGETING, "Line to target", get_turf(controller.pawn), get_turf(find_this_thing)) controller.set_blackboard_key(set_key, find_this_thing) 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 da338fa45cb..d0e8c25c9d7 100644 --- a/code/datums/ai/generic/generic_behaviors.dm +++ b/code/datums/ai/generic/generic_behaviors.dm @@ -301,6 +301,7 @@ /datum/ai_behavior/perform_emote /datum/ai_behavior/perform_emote/perform(seconds_per_tick, datum/ai_controller/controller, emote, speech_sound) + . = ..() var/mob/living/living_pawn = controller.pawn if(!istype(living_pawn)) return AI_BEHAVIOR_INSTANT diff --git a/code/datums/ai/hunting_behavior/hunting_behaviors.dm b/code/datums/ai/hunting_behavior/hunting_behaviors.dm index db684921281..1095919c058 100644 --- a/code/datums/ai/hunting_behavior/hunting_behaviors.dm +++ b/code/datums/ai/hunting_behavior/hunting_behaviors.dm @@ -55,6 +55,8 @@ if(!valid_dinner(living_mob, possible_dinner, hunt_range, controller, seconds_per_tick)) continue controller.set_blackboard_key(hunting_target_key, possible_dinner) + EVLOG_MAPTEXT(controller, EVLOG_CATEGORY_AI_TARGETING, "[controller.pawn] has selected [possible_dinner] as a target for blackboard key [hunting_target_key]! Behavior: [src]", get_turf(possible_dinner), "Target: [possible_dinner]") + EVLOG_LINES(controller, EVLOG_CATEGORY_AI_TARGETING, "Line to target", get_turf(controller.pawn), get_turf(possible_dinner)) return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED diff --git a/code/datums/ai/monkey/monkey_behaviors.dm b/code/datums/ai/monkey/monkey_behaviors.dm index c21d15e8a19..865f6a069ea 100644 --- a/code/datums/ai/monkey/monkey_behaviors.dm +++ b/code/datums/ai/monkey/monkey_behaviors.dm @@ -296,5 +296,10 @@ if(!length(valids)) return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED - controller.set_blackboard_key(set_key, pick_weight(valids)) + var/mob/living/target = pick_weight(valids) + + EVLOG_MAPTEXT(controller, EVLOG_CATEGORY_AI_TARGETING, "[controller.pawn] has selected [target] as a target for blackboard key [set_key]! Behavior: [src]", get_turf(target), "Target: [target]") + EVLOG_LINES(controller, EVLOG_CATEGORY_AI_TARGETING, "Line to target", get_turf(controller.pawn), get_turf(target)) + + controller.set_blackboard_key(set_key, target) return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED diff --git a/code/datums/ai/telegraph_effects.dm b/code/datums/ai/telegraph_effects.dm index 62bbe9a0397..b658c651988 100644 --- a/code/datums/ai/telegraph_effects.dm +++ b/code/datums/ai/telegraph_effects.dm @@ -6,6 +6,14 @@ light_range = 1 duration = 2 SECONDS +/obj/effect/temp_visual/telegraphing/Initialize(mapload) + . = ..() + update_appearance(UPDATE_OVERLAYS) + +/obj/effect/temp_visual/telegraphing/update_overlays() + . = ..() + . += emissive_appearance(icon, icon_state, src, alpha = 90) + /obj/effect/temp_visual/telegraphing/vending_machine_tilt duration = 1 SECONDS @@ -15,7 +23,18 @@ src.duration = duration return ..() -/obj/effect/temp_visual/telegraphing/thunderbolt +/obj/effect/temp_visual/telegraphing/circle icon = 'icons/mob/telegraphing/telegraph.dmi' icon_state = "target_circle" duration = 2 SECONDS + +/obj/effect/temp_visual/telegraphing/circle/short + duration = 1 SECONDS + +/obj/effect/temp_visual/telegraphing/line + icon = 'icons/mob/telegraphing/telegraph.dmi' + icon_state = "line" + duration = 0.8 SECONDS + +/obj/effect/temp_visual/telegraphing/line/short + duration = 0.5 SECONDS diff --git a/code/datums/bodypart_overlays/bodypart_overlay.dm b/code/datums/bodypart_overlays/bodypart_overlay.dm index e28cd624e96..0a04576865a 100644 --- a/code/datums/bodypart_overlays/bodypart_overlay.dm +++ b/code/datums/bodypart_overlays/bodypart_overlay.dm @@ -106,7 +106,7 @@ CRASH("External organ color set to override with no override proc.") ///Generate a unique identifier to cache with. If you change something about the image, but the icon cache stays the same, it'll simply pull the unchanged image out of the cache -/datum/bodypart_overlay/proc/generate_icon_cache() +/datum/bodypart_overlay/proc/generate_icon_cache(obj/item/bodypart/limb) return list() /// Additionally color or texture the limb diff --git a/code/datums/bodypart_overlays/markings_bodypart_overlay.dm b/code/datums/bodypart_overlays/markings_bodypart_overlay.dm index 0cc780794f1..efa407c57e3 100644 --- a/code/datums/bodypart_overlays/markings_bodypart_overlay.dm +++ b/code/datums/bodypart_overlays/markings_bodypart_overlay.dm @@ -28,9 +28,8 @@ icon_state = accessory.icon_state use_gender = accessory.gender_specific draw_color = accessory.color_src ? set_color : null - cache_key = jointext(generate_icon_cache(), "_") -/datum/bodypart_overlay/simple/body_marking/generate_icon_cache() +/datum/bodypart_overlay/simple/body_marking/generate_icon_cache(obj/item/bodypart/limb) . = ..() . += use_gender . += draw_color diff --git a/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm b/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm index ae8a05aacad..8d2b063b22f 100644 --- a/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm +++ b/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm @@ -75,22 +75,20 @@ /datum/bodypart_overlay/mutant/proc/get_base_icon_state() return sprite_datum.icon_state +///Used to build the final incon state for the sprite +/datum/bodypart_overlay/mutant/proc/build_icon_state(image_layer, obj/item/bodypart/limb) + PROTECTED_PROC(TRUE) + var/gender_key = (sprite_datum.gender_specific && limb?.limb_gender) || "m" // Male is default because sprite accessories are so ancient they predate the concept of not hardcoding gender + var/base_state = get_base_icon_state() + var/layer_key = mutant_bodyparts_layertext(image_layer) + return "[gender_key]_[feature_key]_[base_state]_[layer_key]" + ///Get the image we need to draw on the person. Called from get_overlay() which is called from _bodyparts.dm. Limb can be null /datum/bodypart_overlay/mutant/get_image(image_layer, obj/item/bodypart/limb) if(!sprite_datum) CRASH("Trying to call get_image() on [type] while it didn't have a sprite_datum. This shouldn't happen, report it as soon as possible.") - var/gender = limb?.limb_gender || "m" - var/list/icon_state_builder = list() - icon_state_builder += sprite_datum.gender_specific ? gender : "m" //Male is default because sprite accessories are so ancient they predate the concept of not hardcoding gender - icon_state_builder += feature_key - icon_state_builder += get_base_icon_state() - icon_state_builder += mutant_bodyparts_layertext(image_layer) - - var/finished_icon_state = icon_state_builder.Join("_") - - var/mutable_appearance/appearance = mutable_appearance(sprite_datum.icon, finished_icon_state, layer = image_layer) - + var/mutable_appearance/appearance = mutable_appearance(sprite_datum.icon, build_icon_state(image_layer, limb), layer = image_layer) if(sprite_datum.center) center_image(appearance, sprite_datum.dimension_x, sprite_datum.dimension_y) @@ -105,20 +103,17 @@ ///Change our accessory sprite, using the accesssory type. If you need to change the sprite for something, use simple_change_sprite() /datum/bodypart_overlay/mutant/set_appearance(accessory_type) sprite_datum = fetch_sprite_datum(accessory_type) - cache_key = jointext(generate_icon_cache(), "_") ///In a lot of cases, appearances are stored in DNA as the Name, instead of the path. Use set_appearance instead of possible /datum/bodypart_overlay/mutant/proc/set_appearance_from_name(accessory_name) sprite_datum = fetch_sprite_datum_from_name(accessory_name) - cache_key = jointext(generate_icon_cache(), "_") ///Generate a unique key based on our sprites. So that if we've aleady drawn these sprites, they can be found in the cache and wont have to be drawn again (blessing and curse, but mostly curse) -/datum/bodypart_overlay/mutant/generate_icon_cache() +/datum/bodypart_overlay/mutant/generate_icon_cache(obj/item/bodypart/limb) . = list() . += "[get_base_icon_state()]" . += "[feature_key]" . += "[dye_color || draw_color]" - return . ///Return a dumb glob list for this specific feature (called from parse_sprite) /datum/bodypart_overlay/mutant/proc/get_global_feature_list() diff --git a/code/datums/bodypart_overlays/simple_bodypart_overlay.dm b/code/datums/bodypart_overlays/simple_bodypart_overlay.dm index a8004811b1a..fa5222f5adf 100644 --- a/code/datums/bodypart_overlays/simple_bodypart_overlay.dm +++ b/code/datums/bodypart_overlays/simple_bodypart_overlay.dm @@ -15,10 +15,9 @@ overlay.color = draw_color -/datum/bodypart_overlay/simple/generate_icon_cache() +/datum/bodypart_overlay/simple/generate_icon_cache(obj/item/bodypart/limb) . = ..() - - . += "[icon_state]" + . += icon_state ///A sixpack drawn on the chest /datum/bodypart_overlay/simple/sixpack diff --git a/code/datums/bodypart_overlays/texture_bodypart_overlay.dm b/code/datums/bodypart_overlays/texture_bodypart_overlay.dm index 920c2973ac8..23b8aa6b780 100644 --- a/code/datums/bodypart_overlays/texture_bodypart_overlay.dm +++ b/code/datums/bodypart_overlays/texture_bodypart_overlay.dm @@ -16,9 +16,9 @@ /datum/bodypart_overlay/texture/modify_bodypart_appearance(datum/appearance) appearance.add_filter("bodypart_texture_[texture_icon_state]", 1, layering_filter(icon = cached_texture_icon, blend_mode = BLEND_INSET_OVERLAY)) -/datum/bodypart_overlay/texture/generate_icon_cache() +/datum/bodypart_overlay/texture/generate_icon_cache(obj/item/bodypart/limb) . = ..() - . += "[type]" + . += type /datum/bodypart_overlay/texture/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner, mob/living/carbon/owner, is_husked = FALSE) if (!..()) diff --git a/code/datums/brain_damage/special.dm b/code/datums/brain_damage/special.dm index 469a5b90562..b4792fbd27c 100644 --- a/code/datums/brain_damage/special.dm +++ b/code/datums/brain_damage/special.dm @@ -439,7 +439,7 @@ var/beepskys_cry = "Level 10 infraction alert!" to_chat(victim, "[span_name("[name]")] exclaims, \"[span_robot("[beepskys_cry]")]") if(victim.client?.prefs.read_preference(/datum/preference/toggle/enable_runechat)) - victim.create_chat_message(src, raw_message = beepskys_cry, spans = list("robotic")) + victim.create_chat_message(src, raw_message = beepskys_cry, spans = list(SPAN_ROBOT)) // Used by Veteran Security Advisor job. /datum/brain_trauma/special/ptsd diff --git a/code/datums/browser.dm b/code/datums/browser.dm index b2ea448f783..7ba99b27a7f 100644 --- a/code/datums/browser.dm +++ b/code/datums/browser.dm @@ -260,7 +260,7 @@ if (focused_window) winset(user, focused_window, "focus=true") else - winset(user, "mapwindow", "focus=true") + winset(user, SKIN_MAPWINDOW, "focus=true") break if (timeout) addtimer(CALLBACK(src, PROC_REF(close)), timeout) diff --git a/code/datums/communications.dm b/code/datums/communications.dm index 26a74da7f77..53ce0212d91 100644 --- a/code/datums/communications.dm +++ b/code/datums/communications.dm @@ -28,6 +28,9 @@ GLOBAL_DATUM_INIT(communications_controller, /datum/communciations_controller, n /// What is the higher bound of when the roundstart announcement is sent out? var/waittime_h = 180 SECONDS + /// Tracks if we have announced greenshift at the start of the round or not + var/announced_greenshift = FALSE + /datum/communciations_controller/proc/can_announce(mob/living/user, is_silicon) if(is_silicon && COOLDOWN_FINISHED(src, silicon_message_cooldown)) return TRUE @@ -97,6 +100,7 @@ GLOBAL_DATUM_INIT(communications_controller, /datum/communciations_controller, n if(greenshift) station_goal_strings += "All special orders have been authorized for the shift. \ Feel free to pick one your crew wishes to specialize in - you are not expected to complete them all." + announced_greenshift = TRUE else for(var/datum/station_goal/station_goal as anything in SSstation.get_station_goals()) diff --git a/code/datums/components/_component.dm b/code/datums/components/_component.dm index 5c93b9833f8..ec60916b8ac 100644 --- a/code/datums/components/_component.dm +++ b/code/datums/components/_component.dm @@ -237,11 +237,11 @@ /datum/component/proc/_GetInverseTypeList(our_type = type) //we can do this one simple trick . = list(our_type) - var/current_type = parent_type + var/datum/current_type = parent_type //and since most components are root level + 1, this won't even have to run while (current_type != /datum/component) . += current_type - current_type = type2parent(current_type) + current_type = current_type::parent_type // The type arg is casted so initial works, you shouldn't be passing a real instance into this /** @@ -370,9 +370,12 @@ if((source in old_component.sources) && !old_component.allow_source_update(source)) return old_component // source already registered, no work to do - if(old_component.on_source_add(arglist(list(source) + raw_args.Copy(2))) == COMPONENT_INCOMPATIBLE) + var/source_result = old_component.on_source_add(arglist(list(source) + raw_args.Copy(2))) + if(source_result == COMPONENT_INCOMPATIBLE) stack_trace("incompatible source added to a [old_component.type]. Args: [json_encode(raw_args)]") return null + if(source_result == COMPONENT_REDUNDANT) + return null else if(!new_component) new_component = new component_type(raw_args) // There's a valid dupe mode but there's no old component, act like normal diff --git a/code/datums/components/ai_retaliate_advanced.dm b/code/datums/components/ai_retaliate_advanced.dm index d734fa92b3c..12e22c3d395 100644 --- a/code/datums/components/ai_retaliate_advanced.dm +++ b/code/datums/components/ai_retaliate_advanced.dm @@ -33,5 +33,5 @@ if (!victim.ai_controller) return - victim.ai_controller.insert_blackboard_key_lazylist(BB_BASIC_MOB_RETALIATE_LIST, attacker) + victim.ai_controller.set_blackboard_key_assoc_lazylist(BB_BASIC_MOB_RETALIATE_LIST, attacker, world.time) post_retaliate_callback?.InvokeAsync(attacker) diff --git a/code/datums/components/bane.dm b/code/datums/components/bane.dm new file mode 100644 index 00000000000..08d3feac17b --- /dev/null +++ b/code/datums/components/bane.dm @@ -0,0 +1,199 @@ +/** + * ## Bane component + * + * Applied to items and projectiles that modifies damage dealt to certain things. + * For example a sword that deals 2x damage to specifically skeletons. + * + * For items, you are not limited to only dealing more damage. Supports smaller multipliers or removing flat damage. + * For projectiles, you are limited to only dealing more damage, at least until further refactors are done. + */ +/datum/component/bane + dupe_mode = COMPONENT_DUPE_ALLOWED + /// Callback invoked when checking if a target is valid to be baned (arguments: target) + /// Return a boolean, FALSE to stop the bane effect or TRUE to allow it + VAR_FINAL/datum/callback/should_bane_callback + /// Callback invoked before bane damage is applied, allows for modifying the damage or applying other effects. (arguments: target, attacker, damage_modifiers) + /// Return value doesn't matter, but you can modify the damage_modifiers list to change the attack's values + VAR_FINAL/datum/callback/pre_bane_callback + /// Callback invoked after bane damage is applied, allows for applying other effects. (arguments: target, attacker) + /// Return value doesn't matter + VAR_FINAL/datum/callback/on_bane_callback + /// A bitfield of mob biotypes that this bane component applies to. + ///If NONE, applies to all biotypes. Defaults to NONE. + VAR_FINAL/affected_biotypes = NONE + /// Multiplier applied to damage when the bane effect applies. Defaults to 1 (no change). + VAR_FINAL/damage_multiplier = 1 + /// Flat damage added when the bane effect applies. Defaults to 0 (no change). + VAR_FINAL/added_damage = 0 + /// Optional text to show in the weapon label readout, if not set it will generate a generic one based on the biotypes + VAR_FINAL/label_text = "" + +/datum/component/bane/Initialize( + damage_multiplier = 1, + added_damage = 0, + affected_biotypes = NONE, + datum/callback/should_bane_callback, + datum/callback/pre_bane_callback, + datum/callback/on_bane_callback, + label_text = "", +) + if(!isitem(parent) && !isprojectile(parent)) + return COMPONENT_INCOMPATIBLE + + src.damage_multiplier = damage_multiplier + src.added_damage = added_damage + src.affected_biotypes = affected_biotypes + src.should_bane_callback = should_bane_callback + src.pre_bane_callback = pre_bane_callback + src.on_bane_callback = on_bane_callback + src.label_text = label_text + +/datum/component/bane/RegisterWithParent() + if(isitem(parent)) + RegisterSignal(parent, COMSIG_ITEM_WEAPON_LABEL_READOUT, PROC_REF(label_readout)) + RegisterSignal(parent, COMSIG_ITEM_PRE_ATTACK, PROC_REF(pre_attack)) + RegisterSignal(parent, COMSIG_ITEM_AFTERATTACK, PROC_REF(after_attack)) + RegisterSignal(parent, COMSIG_MOVABLE_IMPACT_ZONE, PROC_REF(on_thrown_hit)) + if(isprojectile(parent)) + RegisterSignal(parent, COMSIG_PROJECTILE_SELF_ON_HIT, PROC_REF(projectile_hit)) + +/datum/component/bane/UnregisterFromParent() + if(isitem(parent)) + UnregisterSignal(parent, COMSIG_ITEM_WEAPON_LABEL_READOUT) + UnregisterSignal(parent, COMSIG_ITEM_PRE_ATTACK) + UnregisterSignal(parent, COMSIG_ITEM_AFTERATTACK) + UnregisterSignal(parent, COMSIG_MOVABLE_IMPACT_ZONE) + if(isprojectile(parent)) + UnregisterSignal(parent, COMSIG_PROJECTILE_SELF_ON_HIT) + +/datum/component/bane/proc/is_bane_target(atom/target) + if(!isliving(target)) + return FALSE + + var/mob/living/living_target = target + if(affected_biotypes && !(living_target.mob_biotypes & affected_biotypes)) + return FALSE + + return isnull(should_bane_callback) ? TRUE : should_bane_callback.Invoke(target) + +/datum/component/bane/proc/label_readout(obj/item/source, list/readout) + SIGNAL_HANDLER + + if(damage_multiplier == 1 && added_damage == 0 && !label_text) + return + + var/label_line = "" + if(damage_multiplier > 1 || added_damage > 0) + label_line += "It is especially effective against" + else if(damage_multiplier < 1 || added_damage < 0) + label_line += "It is less effective against" + else + label_line += "It interacts uniquely with" // for custom behaviors? + + label_line += " " + if(label_text) + label_line += label_text + else if(affected_biotypes) + var/list/affected_biotypes_readable = bitfield_to_list(affected_biotypes, MOB_BIOTYPES_READABLE) + label_line += "[english_list(affected_biotypes_readable)] enemies" + else + label_line += "certain enemies" + + if(damage_multiplier > 1 || added_damage > 0) + var/magnitude = "" + switch(max(damage_multiplier, added_damage / 10)) + if(3 to INFINITY) + magnitude = "massively increased" + if(2 to 3) + magnitude = "greatly increased" + if(1.5 to 2) + magnitude = "significantly increased" + if(1 to 1.5) + magnitude = "slightly increased" + + label_line += ", dealing [span_warning(magnitude)] damage per hit" + + else if(damage_multiplier < 1 || added_damage < 0) + var/magnitude = "" + switch(min(damage_multiplier, 10 / abs(added_damage || 1))) + if(-INFINITY to 0) + magnitude = "no" + if(0 to 0.3) + magnitude = "massively reduced" + if(0.3 to 0.6) + magnitude = "greatly reduced" + if(0.6 to 0.9) + magnitude = "significantly reduced" + if(0.9 to 1) + magnitude = "slightly reduced" + + label_line += ", dealing [span_warning(magnitude)] damage per hit" + + label_line += "." + readout += label_line + +// Item attack handling +/datum/component/bane/proc/pre_attack(datum/source, atom/target, mob/living/attacker, list/modifiers, list/attack_modifiers) + SIGNAL_HANDLER + + if(!is_bane_target(target)) + return + + if(added_damage != 0) + MODIFY_ATTACK_FORCE(attack_modifiers, added_damage) + if(damage_multiplier != 1) + MODIFY_ATTACK_FORCE_MULTIPLIER(attack_modifiers, damage_multiplier) + + pre_bane_callback?.Invoke(target, attacker, attack_modifiers) + +/datum/component/bane/proc/after_attack(datum/source, atom/target, mob/living/attacker, ...) + SIGNAL_HANDLER + + if(!is_bane_target(target)) + return + + SEND_SIGNAL(target, COMSIG_LIVING_BANED, source, attacker) + on_bane_callback?.Invoke(target, attacker) + +// Throw impact handling +/datum/component/bane/proc/on_thrown_hit(datum/source, atom/hit_atom, hit_zone, blocked, datum/thrownthing/throwingdatum) + SIGNAL_HANDLER + + if(!is_bane_target(hit_atom)) + return + + var/mob/thrower = throwingdatum?.thrower?.resolve() + var/list/damage_modifiers = list("[FORCE_MULTIPLIER]" = damage_multiplier, "[FORCE_MODIFIER]" = added_damage) + pre_bane_callback?.Invoke(hit_atom, thrower, damage_modifiers) + + // We're not modifying the throwforce of the item we're just applying more damage as a separate damage event + // That's why we do damage_multiplier - 1 (so that a 1.5x multiplier would apply 0.5x damage here for a total of 1.5x) + var/obj/item/throwing_item = parent + var/extra_damage = (throwing_item.throwforce * max(0, damage_modifiers[FORCE_MULTIPLIER] - 1)) + damage_modifiers[FORCE_MODIFIER] + if(extra_damage > 0) + var/mob/living/living_target = hit_atom // safe assertion from is_bane_target + living_target.apply_damage(extra_damage, throwing_item.damtype, hit_zone, blocked) + + SEND_SIGNAL(hit_atom, COMSIG_LIVING_BANED, thrower, hit_atom) + on_bane_callback?.Invoke(hit_atom, thrower) + +// Projectile hit handling +/datum/component/bane/proc/projectile_hit(datum/source, atom/firer, atom/target, angle, hit_zone, blocked, ...) + SIGNAL_HANDLER + + if(!is_bane_target(target)) + return + + var/list/damage_modifiers = list("[FORCE_MULTIPLIER]" = damage_multiplier, "[FORCE_MODIFIER]" = added_damage) + pre_bane_callback?.Invoke(target, firer, damage_modifiers) + + // We're not modifying the projectile damage we're just applying more damage as a separate damage event + // That's why we do damage_multiplier - 1 (so that a 1.5x multiplier would apply 0.5x damage here for a total of 1.5x) + var/obj/projectile/projectile_owner = parent + var/extra_damage = (projectile_owner.damage * max(0, damage_modifiers[FORCE_MULTIPLIER] - 1)) + damage_modifiers[FORCE_MODIFIER] + if(extra_damage > 0) + var/mob/living/living_target = target // safe assertion from is_bane_target + living_target.apply_damage(extra_damage, projectile_owner.damage_type, hit_zone, blocked) + + SEND_SIGNAL(target, COMSIG_LIVING_BANED, firer, target) + on_bane_callback?.Invoke(target, firer) diff --git a/code/datums/components/blob_minion.dm b/code/datums/components/blob_minion.dm index 8e8f796d3ae..6549410f4a4 100644 --- a/code/datums/components/blob_minion.dm +++ b/code/datums/components/blob_minion.dm @@ -74,7 +74,6 @@ var/mob/living/living_parent = parent living_parent.add_faction(ROLE_BLOB) ADD_TRAIT(parent, TRAIT_BLOB_ALLY, REF(src)) - remove_verb(parent, /mob/living/verb/pulled) // No dragging people into the blob RegisterSignal(parent, COMSIG_MOB_MIND_INITIALIZED, PROC_REF(on_mind_init)) RegisterSignal(parent, COMSIG_ATOM_UPDATE_ICON, PROC_REF(on_update_appearance)) RegisterSignal(parent, COMSIG_MOB_GET_STATUS_TAB_ITEMS, PROC_REF(on_update_status_tab)) @@ -98,7 +97,6 @@ living_parent.pass_flags &= ~PASSBLOB living_parent.remove_faction(ROLE_BLOB) REMOVE_TRAIT(parent, TRAIT_BLOB_ALLY, REF(src)) - add_verb(parent, /mob/living/verb/pulled) UnregisterSignal(parent, list( COMSIG_ATOM_BLOB_ACT, COMSIG_ATOM_FIRE_ACT, diff --git a/code/datums/components/butchering.dm b/code/datums/components/butchering.dm index bdc41329a74..0ccaa013943 100644 --- a/code/datums/components/butchering.dm +++ b/code/datums/components/butchering.dm @@ -318,6 +318,7 @@ wound.remove_wound() wound.apply_wound(replacement, silent = TRUE) + SEND_SIGNAL(target, COMSIG_BODYPART_BUTCHERED, replacement) return replacement /datum/component/butchering/proc/start_butcher(obj/item/source, mob/living/target, mob/living/user) diff --git a/code/datums/components/crafting/crafting.dm b/code/datums/components/crafting/crafting.dm index a15e0903af0..66e1d7fcdf1 100644 --- a/code/datums/components/crafting/crafting.dm +++ b/code/datums/components/crafting/crafting.dm @@ -180,7 +180,8 @@ for(var/obj/item/item in source.contents) within_source += item if(item.atom_storage) - within_source += item.contents + for(var/obj/item/item_stored_within in item.contents) + within_source += item_stored_within for(var/obj/item/item as anything in within_source) if(!item.tool_behaviour) diff --git a/code/datums/components/crafting/furniture.dm b/code/datums/components/crafting/furniture.dm index a1d55a785ec..ec4cd62df1d 100644 --- a/code/datums/components/crafting/furniture.dm +++ b/code/datums/components/crafting/furniture.dm @@ -117,4 +117,27 @@ tool_behaviors = list(TOOL_SCREWDRIVER) category = CAT_FURNITURE +/datum/crafting_recipe/signboard + name = "Signboard" + desc = "A sign, you can write anything on it!" + tool_behaviors = list(TOOL_SCREWDRIVER) + result = /obj/structure/signboard + reqs = list( + /obj/item/stack/sheet/mineral/wood = 5, + ) + time = 5 SECONDS + category = CAT_FURNITURE + +/datum/crafting_recipe/holosign + name = "Holographic Signboard" + desc = "A sign, you can write anything on it! Now available in many colors!" + tool_behaviors = list(TOOL_SCREWDRIVER, TOOL_MULTITOOL) + result = /obj/structure/signboard/holosign + reqs = list( + /obj/item/stack/sheet/iron = 5, + /obj/item/stack/cable_coil = 5, + /obj/item/stock_parts/micro_laser = 1, + ) + time = 10 SECONDS + category = CAT_FURNITURE diff --git a/code/datums/components/crafting/ranged_weapon.dm b/code/datums/components/crafting/ranged_weapon.dm index 53929a6f68d..ae234ea7516 100644 --- a/code/datums/components/crafting/ranged_weapon.dm +++ b/code/datums/components/crafting/ranged_weapon.dm @@ -292,8 +292,8 @@ return ..() /datum/crafting_recipe/deagle_prime_mag - name = "Regal Condor Magazine (10mm Reaper)" - result = /obj/item/ammo_box/magazine/r10mm + name = "Regal Condor Magazine (.45 Reaper)" + result = /obj/item/ammo_box/magazine/r45 reqs = list( /obj/item/stack/sheet/iron = 10, /obj/item/stack/sheet/mineral/gold = 10, diff --git a/code/datums/components/crafting/robot.dm b/code/datums/components/crafting/robot.dm index cf8938deed4..dd1972b3fe8 100644 --- a/code/datums/components/crafting/robot.dm +++ b/code/datums/components/crafting/robot.dm @@ -1,6 +1,6 @@ /datum/crafting_recipe/ed209 name = "ED209" - result = /mob/living/simple_animal/bot/secbot/ed209 + result = /mob/living/basic/bot/secbot/ed209 reqs = list( /obj/item/robot_suit = 1, /obj/item/clothing/head/helmet/sec = 1, @@ -18,7 +18,7 @@ /datum/crafting_recipe/secbot name = "Secbot" - result = /mob/living/simple_animal/bot/secbot + result = /mob/living/basic/bot/secbot reqs = list( /obj/item/assembly/signaler = 1, /obj/item/clothing/head/helmet/sec = 1, @@ -72,7 +72,7 @@ /datum/crafting_recipe/honkbot name = "Honkbot" - result = /mob/living/basic/bot/honkbot + result = /mob/living/basic/bot/secbot/honkbot reqs = list( /obj/item/storage/box/clown = 1, /obj/item/bodypart/arm/right/robot = 1, diff --git a/code/datums/components/crafting/tools.dm b/code/datums/components/crafting/tools.dm index 29ea7a60010..b1d2c107866 100644 --- a/code/datums/components/crafting/tools.dm +++ b/code/datums/components/crafting/tools.dm @@ -131,6 +131,10 @@ ) category = CAT_TOOLS +/datum/crafting_recipe/jaws_of_recovery/New() + LAZYADD(blacklist, typecacheof(/obj/item/crowbar/power/paramedic, ignore_root_path = TRUE)) + return ..() + /datum/crafting_recipe/lantern name = "Lantern" result = /obj/item/flashlight/lantern diff --git a/code/datums/components/digitigrade_linb.dm b/code/datums/components/digitigrade_linb.dm new file mode 100644 index 00000000000..6b7776474b5 --- /dev/null +++ b/code/datums/components/digitigrade_linb.dm @@ -0,0 +1,142 @@ +/// Updates the limb id of a bodypart if the mob is wearing digitigrade squishing clothing +/datum/component/digitigrade_limb + /// Id when wearing digitigrade squishing clothing + var/squashed_id + /// Id when not wearing digitigrade squishing clothing + var/free_id + + /// Lazylist of refs that are squishing this limb + VAR_PRIVATE/list/squashing_us + +/datum/component/digitigrade_limb/Initialize(squashed_id, free_id) + if(!istype(parent, /obj/item/bodypart/leg)) + return COMPONENT_INCOMPATIBLE + + var/obj/item/bodypart/limb = parent + limb.bodytype |= BODYTYPE_DIGITIGRADE + + src.squashed_id = squashed_id + src.free_id = free_id || initial(limb.limb_id) + + RegisterSignal(parent, COMSIG_BODYPART_UPDATED, PROC_REF(update_limb_id_comsig)) + RegisterSignal(parent, COMSIG_BODYPART_ATTACHED, PROC_REF(on_attach)) + RegisterSignal(parent, COMSIG_BODYPART_REMOVED, PROC_REF(on_remove)) + RegisterSignal(parent, COMSIG_BODYPART_BUTCHERED, PROC_REF(on_butchered)) + + if(ishuman(limb.owner)) + on_attach(limb, limb.owner) + +/datum/component/digitigrade_limb/Destroy() + UnregisterSignal(parent, COMSIG_BODYPART_UPDATED) + UnregisterSignal(parent, COMSIG_BODYPART_ATTACHED) + UnregisterSignal(parent, COMSIG_BODYPART_REMOVED) + + UnregisterSignal(parent, COMSIG_BODYPART_BUTCHERED) + var/obj/item/bodypart/limb = parent + if(!QDELING(parent) && ishuman(limb.owner)) + on_remove(limb, limb.owner) + limb.bodytype &= ~BODYTYPE_DIGITIGRADE + return ..() + +/datum/component/digitigrade_limb/proc/on_attach(obj/item/bodypart/limb, mob/living/carbon/new_limb_owner) + SIGNAL_HANDLER + + RegisterSignal(new_limb_owner, COMSIG_MOB_EQUIPPED_ITEM, PROC_REF(equipped_item)) + RegisterSignal(new_limb_owner, COMSIG_MOB_DROPPED_ITEM, PROC_REF(unequipped_item)) + RegisterSignal(new_limb_owner, COMSIG_CARBON_ITEM_COVERAGE_CHANGED, PROC_REF(coverage_changed)) + for(var/obj/item/equipped as anything in new_limb_owner.get_equipped_items()) + if(equipped_item(new_limb_owner, equipped, new_limb_owner.get_slot_by_item(equipped))) + LAZYOR(squashing_us, REF(equipped)) + +/datum/component/digitigrade_limb/proc/on_remove(obj/item/bodypart/limb, mob/living/carbon/old_limb_owner) + SIGNAL_HANDLER + + UnregisterSignal(old_limb_owner, COMSIG_MOB_EQUIPPED_ITEM) + UnregisterSignal(old_limb_owner, COMSIG_MOB_DROPPED_ITEM) + UnregisterSignal(old_limb_owner, COMSIG_CARBON_ITEM_COVERAGE_CHANGED) + LAZYNULL(squashing_us) + update_limb_id() + +/datum/component/digitigrade_limb/proc/equipped_item(mob/living/carbon/equipper, obj/item/equipped_item, slot) + SIGNAL_HANDLER + + if((slot & equipped_item.slot_flags) && item_squishes_limb(equipped_item, equipper)) + LAZYOR(squashing_us, REF(equipped_item)) + update_limb_id() + +/datum/component/digitigrade_limb/proc/unequipped_item(mob/living/carbon/equipper, obj/item/equipped_item) + SIGNAL_HANDLER + + LAZYREMOVE(squashing_us, REF(equipped_item)) + update_limb_id() + +// Snowflake case for updating whether our jumpsuit should squish us +/datum/component/digitigrade_limb/proc/coverage_changed(mob/living/carbon/equipper, added_slots, removed_slots) + SIGNAL_HANDLER + + if(!((added_slots|removed_slots) & HIDEJUMPSUIT)) + return + + var/obj/item/clothing/uniform = equipper.get_item_by_slot(ITEM_SLOT_ICLOTHING) + if(isnull(uniform)) + return + + var/uniform_ref = REF(uniform) + if(uniform_ref in squashing_us) + if(added_slots & HIDEJUMPSUIT) + LAZYREMOVE(squashing_us, uniform_ref) + update_limb_id() + + else + if((removed_slots & HIDEJUMPSUIT) && item_squishes_limb(uniform, equipper)) + LAZYOR(squashing_us, uniform_ref) + update_limb_id() + +/datum/component/digitigrade_limb/proc/item_squishes_limb(obj/item/equipped_item, mob/living/carbon/equipper) + if(!(equipped_item.body_parts_covered & (LEGS|FEET))) + return FALSE + + switch(equipper.get_slot_by_item(equipped_item)) + if(ITEM_SLOT_FEET, ITEM_SLOT_OCLOTHING) + return !(equipped_item.supports_variations_flags & DIGITIGRADE_VARIATIONS) + if(ITEM_SLOT_ICLOTHING) // If the jumpsuit is obscured, it shouldn't contribute to squishing + return !(equipped_item.supports_variations_flags & DIGITIGRADE_VARIATIONS) && !(equipper.obscured_slots & HIDEJUMPSUIT) + + return FALSE + +/// This is just ran on update_limb() to ensure we always have the correct ID +/datum/component/digitigrade_limb/proc/update_limb_id_comsig() + SIGNAL_HANDLER + update_limb_id(sprite_update = FALSE) + +/// Digitigrade limbs that are butchered add the component to the replacement limb +/datum/component/digitigrade_limb/proc/on_butchered(datum/source, obj/item/bodypart/replacement) + SIGNAL_HANDLER + squashed_id = "[initial(replacement.limb_id)]_[BODYPART_ID_DIGITIGRADE]" + free_id = initial(replacement.limb_id) + replacement.TakeComponent(src) + +/datum/component/digitigrade_limb/proc/update_limb_id(sprite_update = TRUE) + var/obj/item/bodypart/limb = parent + var/old_id = limb.limb_id + if(LAZYLEN(squashing_us)) + limb.limb_id = squashed_id + limb.remove_bodyshape(BODYSHAPE_DIGITIGRADE) + + else + limb.limb_id = free_id + limb.add_bodyshape(BODYSHAPE_DIGITIGRADE) + + if(!sprite_update || old_id == limb.limb_id) + return + + if(isnull(limb.owner)) + limb.update_icon_dropped() + return + + // Ensures any items that with a variation are updated + for(var/obj/item/thing as anything in limb.owner.get_equipped_items(INCLUDE_PROSTHETICS|INCLUDE_ABSTRACT)) + if(thing.supports_variations_flags & DIGITIGRADE_VARIATIONS) + thing.update_slot_icon() + // Updates underwear and mob sprites + limb.owner.update_body() diff --git a/code/datums/components/fantasy/suffixes.dm b/code/datums/components/fantasy/suffixes.dm index 2b25e442b23..20a55c04e29 100644 --- a/code/datums/components/fantasy/suffixes.dm +++ b/code/datums/components/fantasy/suffixes.dm @@ -58,7 +58,6 @@ name = "of slaying (random species, carbon or simple animal)" placement = AFFIX_SUFFIX alignment = AFFIX_GOOD - var/list/target_types_by_comp = list() /datum/fantasy_affix/bane/apply(datum/component/fantasy/comp, newName) . = ..() @@ -83,16 +82,9 @@ // This works even with the species picks since we're only accessing the name var/obj/item/master = comp.parent - master.AddElement(/datum/element/bane, target_type = picked_mobtype) - target_types_by_comp[comp] = picked_mobtype + comp.appliedComponents += master.AddComponent(/datum/component/bane, affected_biotypes = picked_mobtype, damage_multiplier = 2) return "[newName] of [initial(picked_mobtype.name)] slaying" -/datum/fantasy_affix/bane/remove(datum/component/fantasy/comp) - var/picked_mobtype = target_types_by_comp[comp] - var/obj/item/master = comp.parent - master.RemoveElement(/datum/element/bane, picked_mobtype) - target_types_by_comp -= comp - /datum/fantasy_affix/summoning name = "of summoning (dangerous, can pick all but megafauna tier stuff)" placement = AFFIX_SUFFIX diff --git a/code/datums/components/force_move.dm b/code/datums/components/force_move.dm index 62fe26d71f7..c69fa0d6c5e 100644 --- a/code/datums/components/force_move.dm +++ b/code/datums/components/force_move.dm @@ -10,6 +10,8 @@ var/mob/mob_parent = parent var/dist = get_dist(mob_parent, target) var/datum/move_loop/loop = GLOB.move_manager.move_towards(mob_parent, target, delay = 1, timeout = dist) + if(!loop) + return COMPONENT_INCOMPATIBLE RegisterSignal(mob_parent, COMSIG_MOB_CLIENT_PRE_LIVING_MOVE, PROC_REF(stop_move)) RegisterSignal(mob_parent, COMSIG_ATOM_PRE_PRESSURE_PUSH, PROC_REF(stop_pressure)) if(spin) diff --git a/code/datums/components/ghostrole_on_revive.dm b/code/datums/components/ghostrole_on_revive.dm index 52ea1d0bd07..ef64f42fb74 100644 --- a/code/datums/components/ghostrole_on_revive.dm +++ b/code/datums/components/ghostrole_on_revive.dm @@ -87,11 +87,13 @@ /datum/component/ghostrole_on_revive/proc/prepare_brain(obj/item/organ/source) ADD_TRAIT(source, TRAIT_GHOSTROLE_ON_REVIVE, REF(src)) RegisterSignal(source, COMSIG_ORGAN_IMPLANTED, PROC_REF(prepare_mob_from_brain)) + RegisterSignal(source, COMSIG_ATOM_EXAMINE, PROC_REF(brain_examine)) UnregisterSignal(source, COMSIG_ORGAN_REMOVED) /datum/component/ghostrole_on_revive/proc/unprepare_brain(obj/item/organ/source) REMOVE_TRAIT(source, TRAIT_GHOSTROLE_ON_REVIVE, REF(src)) UnregisterSignal(source, COMSIG_ORGAN_IMPLANTED) + UnregisterSignal(source, COMSIG_ATOM_EXAMINE) RegisterSignal(source, COMSIG_ORGAN_REMOVED, PROC_REF(prepare_brain)) source.owner?.med_hud_set_status() @@ -102,6 +104,11 @@ UnregisterSignal(source, COMSIG_ORGAN_IMPLANTED) prepare_mob(owner) +/datum/component/ghostrole_on_revive/proc/brain_examine(datum/source, mob/user, list/examine_list) + SIGNAL_HANDLER + + examine_list += span_info("Another soul may take [source.p_their()] place if put in a body...") + /datum/component/ghostrole_on_revive/proc/on_revive(mob/living/source) SIGNAL_HANDLER diff --git a/code/datums/components/hat_stabilizer.dm b/code/datums/components/hat_stabilizer.dm index b7d1a4a3ce2..909eba12a2f 100644 --- a/code/datums/components/hat_stabilizer.dm +++ b/code/datums/components/hat_stabilizer.dm @@ -195,7 +195,7 @@ /datum/component/hat_stabilizer/proc/on_hat_movement(obj/hat, mob/user) SIGNAL_HANDLER - remove_hat(user) + remove_hat(ismob(user) ? user : null) /datum/component/hat_stabilizer/proc/on_secondary_attack_hand(datum/source, mob/user) SIGNAL_HANDLER diff --git a/code/datums/components/heart_eater.dm b/code/datums/components/heart_eater.dm index d61aec5ac43..bb17bb3f5eb 100644 --- a/code/datums/components/heart_eater.dm +++ b/code/datums/components/heart_eater.dm @@ -35,11 +35,13 @@ . = ..() RegisterSignal(parent, COMSIG_SPECIES_GAIN, PROC_REF(on_species_change)) RegisterSignal(parent, COMSIG_LIVING_FINISH_EAT, PROC_REF(eat_eat_eat)) + RegisterSignal(parent, COMSIG_LIVING_UNARMED_ATTACK, PROC_REF(try_rip_heart)) /datum/component/heart_eater/UnregisterFromParent() . = ..() UnregisterSignal(parent, COMSIG_LIVING_FINISH_EAT) UnregisterSignal(parent, COMSIG_SPECIES_GAIN) + UnregisterSignal(parent, COMSIG_LIVING_UNARMED_ATTACK) /datum/component/heart_eater/proc/prepare_species(mob/living/carbon/human/eater) if(eater.get_liked_foodtypes() & GORE) @@ -68,7 +70,7 @@ var/obj/item/organ/heart/previous_heart = last_heart_we_ate?.resolve() if(we_ate_heart == previous_heart) return - if (!HAS_TRAIT(we_ate_heart, TRAIT_USED_ORGAN)) + if (!HAS_TRAIT(we_ate_heart, TRAIT_ORGAN_USED_BY_PLAYER)) to_chat(eater, span_warning("This heart is utterly lifeless, you won't receive any boons from consuming it!")) return bites_taken = 0 @@ -119,3 +121,61 @@ eater.adjust_tox_loss(-50) eater.adjust_oxy_loss(-50) eater.adjust_stamina_loss(-50) + +/datum/component/heart_eater/proc/try_rip_heart(mob/living/source, mob/living/carbon/target, proximity, modifiers) + SIGNAL_HANDLER + if(!istype(target)) + return + if(!IS_DEAD_OR_INCAP(target)) + return + if(!source.combat_mode) + return + if(source.zone_selected != BODY_ZONE_CHEST) + return + var/obj/item/bodypart/chest = target.get_bodypart(BODY_ZONE_CHEST) + if(!can_rip_heart(source, target, source.active_hand_index)) + return + if(chest.get_wound_type(/datum/wound/blunt/bone/critical) && !target.get_organ_slot(ORGAN_SLOT_HEART)) //Don't bother trying to rip a heart out of someone we can see doesn't have one. + return + INVOKE_ASYNC(src, PROC_REF(do_rip_heart), source, target) + return COMPONENT_CANCEL_ATTACK_CHAIN + +/datum/component/heart_eater/proc/can_rip_heart(mob/living/user, mob/living/carbon/target, hand_index) + if(!IS_DEAD_OR_INCAP(target)) + return FALSE + if(!user.has_hand_for_held_index(hand_index)) + return FALSE + if(user.get_item_for_held_index(hand_index)) + return FALSE + return TRUE + +/datum/component/heart_eater/proc/do_rip_heart(mob/living/user, mob/living/carbon/target) + playsound(target, 'sound/items/weapons/slice.ogg', 50, TRUE) + var/hand_index = user.active_hand_index + if(!do_after( + user, + 3 SECONDS, + target, + timed_action_flags = IGNORE_HELD_ITEM, + extra_checks = CALLBACK(src, PROC_REF(can_rip_heart), user, target, hand_index), + interaction_key = "[DOAFTER_SOURCE_RIP_HEART]_[hand_index]", + max_interact_count = 1, + )) + user.balloon_alert(user, "interrupted!") + return + var/obj/item/bodypart/chest = target.get_bodypart(BODY_ZONE_CHEST) + chest.force_wound_upwards(/datum/wound/blunt/bone/critical, wound_source = "heart ripped") + var/obj/item/organ/heart = target.get_organ_slot(ORGAN_SLOT_HEART) + if(!heart) + target.balloon_alert(user, "no heart!?") + return + heart.Remove(target) + to_chat(user, span_warning("You rip [target]'s [heart.name] out of [target.p_their()] chest!")) + target.visible_message( + span_warning("[user] rips [target]'s [heart.name] out of [target.p_their()] chest!"), + span_userdanger("[user] rips your [heart.name] out of your chest!"), + span_userdanger("You feel something being torn out of your chest!"), + ignored_mobs = list(user), + ) + if(!user.put_in_hand(heart, hand_index)) + heart.forceMove(user.drop_location()) diff --git a/code/datums/components/hitsplat.dm b/code/datums/components/hitsplat.dm new file mode 100644 index 00000000000..89de3d1fa65 --- /dev/null +++ b/code/datums/components/hitsplat.dm @@ -0,0 +1,177 @@ +/** + * Component to display hitsplats + */ +/datum/component/hitsplat + ///positions of all hitsplats + var/list/hitsplat_positions = list( + list(0, -2) = null, + list(0, 10) = null, + list(10, 0) = null, + list(-10, 0) = null, + list(10, 12) = null, + list(-10, 12) = null, + list(0, 22) = null, + ) + + var/obj/effect/overlay/vis/hitsplat/hitsplat_type = /obj/effect/overlay/vis/hitsplat/debugging + // Alot less spammy and more useable as a smite or ingame feature. Off for ALL the health adjustments + var/only_attacks = FALSE + +/datum/component/hitsplat/Initialize(hitsplat_type, only_attacks) + if(!ismob(parent)) + return COMPONENT_INCOMPATIBLE + if(hitsplat_type) + src.hitsplat_type = hitsplat_type + src.only_attacks = only_attacks + +/datum/component/hitsplat/RegisterWithParent() + if(only_attacks) + RegisterSignal(parent, COMSIG_MOB_APPLY_DAMAGE, PROC_REF(on_attacked)) + RegisterSignal(parent, COMSIG_ATOM_AFTER_ATTACKEDBY, PROC_REF(after_attackby)) + else + RegisterSignals(parent, COMSIG_LIVING_ADJUST_STANDARD_DAMAGE_TYPES, PROC_REF(on_damage_adjusted)) + RegisterSignal(parent, COMSIG_CARBON_LIMB_DAMAGED, PROC_REF(on_limb_damage)) + +/datum/component/hitsplat/UnregisterFromParent() + if(only_attacks) + UnregisterSignal(parent, list(COMSIG_MOB_APPLY_DAMAGE, COMSIG_ATOM_AFTER_ATTACKEDBY)) + else + UnregisterSignal(parent, list(COMSIG_CARBON_LIMB_DAMAGED) + COMSIG_LIVING_ADJUST_STANDARD_DAMAGE_TYPES) + + +/datum/component/hitsplat/proc/after_attackby(atom/target, obj/item/weapon) + SIGNAL_HANDLER + if(weapon.force) //will be handled by on_attacked + return NONE + spawn_hitsplat(0) + +/datum/component/hitsplat/proc/on_attacked(mob/source, damage_amount, damagetype, def_zone, blocked) + SIGNAL_HANDLER + + if(damagetype == STAMINA || damage_amount < 0) + return NONE + spawn_hitsplat(damage_amount, damagetype) + +/datum/component/hitsplat/proc/on_damage_adjusted(mob/source, type, amount) + SIGNAL_HANDLER + + if(type == STAMINA) + return NONE + spawn_hitsplat(amount, type) + +/datum/component/hitsplat/proc/on_limb_damage(mob/living/our_mob, limb, brute, burn) + SIGNAL_HANDLER + + if(brute) + spawn_hitsplat(brute, BRUTE) + if(burn) + spawn_hitsplat(burn, BURN) + +/datum/component/hitsplat/proc/spawn_hitsplat(amount, type) + var/obj/effect/overlay/vis/hitsplat/new_hitsplat = new hitsplat_type() + new_hitsplat.set_damage_amount(amount, type) + add_hitsplat(new_hitsplat) + +/datum/component/hitsplat/proc/add_hitsplat(obj/effect/new_hitsplat) + + RegisterSignal(new_hitsplat, COMSIG_QDELETING, PROC_REF(on_hitsplat_delete)) + var/mob/living_parent = parent + living_parent.vis_contents += new_hitsplat + + for(var/list/hitsplat in hitsplat_positions) + if(!isnull(hitsplat_positions[hitsplat])) + continue + hitsplat_positions[hitsplat] = new_hitsplat + new_hitsplat.pixel_w = hitsplat[1] + new_hitsplat.pixel_z = hitsplat[2] + return + + var/list/first_hitsplat = hitsplat_positions[1] + qdel(hitsplat_positions[first_hitsplat]) + hitsplat_positions[first_hitsplat] = new_hitsplat + new_hitsplat.pixel_w = first_hitsplat[1] + new_hitsplat.pixel_z = first_hitsplat[2] + +/datum/component/hitsplat/proc/on_hitsplat_delete(datum/source) + SIGNAL_HANDLER + + for(var/list/hitsplat in hitsplat_positions) + if(hitsplat_positions[hitsplat] == source) + hitsplat_positions[hitsplat] = null + + +/obj/effect/overlay/vis/hitsplat + name = "hitsplat" + icon = 'icons/effects/hitsplats.dmi' + icon_state = "hitsplat_default" + base_icon_state = "hitsplat" + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + layer = ABOVE_MOB_LAYER + vis_flags = VIS_INHERIT_PLANE + ///the damage amount we're displaying + var/damage_amount = 0 + /// Percision of rounding for damage number + var/rounding = 1 + /// Controls how accurate we try and be to runescape visuals, otherwise we go for consise debugging information + var/lore_accurate = TRUE + /// Color of text of image + var/text_color + +/obj/effect/overlay/vis/hitsplat/Initialize(mapload) + . = ..() + QDEL_IN(src, 2 SECONDS) + +/obj/effect/overlay/vis/hitsplat/proc/set_damage_amount(damage_number, damage_type) + damage_amount = damage_number + + if(lore_accurate) + if(damage_amount < 0) + icon_state = "[base_icon_state]_heal" + else if(damage_amount == 0) + icon_state = "[base_icon_state]_blocked" + else if(damage_type == TOX) + icon_state = "[base_icon_state]_poison" + else if(damage_type == BURN) + icon_state = "[base_icon_state]_burn" + else + switch(damage_type) + if(BRUTE) + text_color = COLOR_RED + if(BURN) + text_color = COLOR_ORANGE + if(TOX) + text_color = COLOR_GREEN + if(OXY) + text_color = COLOR_BLUE + if(STAMINA) + text_color = COLOR_YELLOW + + update_appearance(UPDATE_OVERLAYS) + + +/obj/effect/overlay/vis/hitsplat/lore_accurate + +/obj/effect/overlay/vis/hitsplat/lore_accurate/update_overlays() + . = ..() + var/hitsplat_num = CEILING(abs(damage_amount), rounding) + var/image/hitsplat_text = image(loc = src, layer = layer + 0.1) + hitsplat_text.pixel_w = 1 + hitsplat_text.pixel_z = 10 + hitsplat_text.maptext = MAPTEXT("[hitsplat_num]") + . += hitsplat_text + + +/obj/effect/overlay/vis/hitsplat/debugging + icon_state = null // Just the maptext + base_icon_state = null + rounding = 0.01 + lore_accurate = FALSE + +/obj/effect/overlay/vis/hitsplat/debugging/update_overlays() + . = ..() + var/hitsplat_num = CEILING(damage_amount, rounding) + var/image/hitsplat_text = image(loc = src, layer = layer + 0.1) + hitsplat_text.pixel_w = 1 + hitsplat_text.pixel_z = 10 + hitsplat_text.maptext = MAPTEXT("[hitsplat_num]") + . += hitsplat_text diff --git a/code/datums/components/ingredients_holder.dm b/code/datums/components/ingredients_holder.dm index afa52f3fc53..e5c46d2896f 100644 --- a/code/datums/components/ingredients_holder.dm +++ b/code/datums/components/ingredients_holder.dm @@ -72,6 +72,7 @@ RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) RegisterSignal(parent, COMSIG_ATOM_EXITED, PROC_REF(food_exited)) RegisterSignal(parent, COMSIG_ATOM_PROCESSED, PROC_REF(on_processed)) + RegisterSignal(parent, COMSIG_PIZZA_SLICE_TAKEN, PROC_REF(on_slice_taken)) RegisterSignal(parent, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, PROC_REF(on_requesting_context_from_item)) ADD_TRAIT(parent, TRAIT_INGREDIENTS_HOLDER, INNATE_TRAIT) @@ -81,6 +82,7 @@ COMSIG_ATOM_EXAMINE, COMSIG_ATOM_EXITED, COMSIG_ATOM_PROCESSED, + COMSIG_PIZZA_SLICE_TAKEN, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, )) REMOVE_TRAIT(parent, TRAIT_INGREDIENTS_HOLDER, INNATE_TRAIT) @@ -287,6 +289,11 @@ for (var/atom/result as anything in results) result.AddComponent(/datum/component/ingredients_holder, null, fill_type, ingredient_type = ingredient_type, max_ingredients = max_ingredients, processed_holder = src) +/// Pizzas have unique slicing interaction so we need to do this +/datum/component/ingredients_holder/proc/on_slice_taken(datum/source, mob/living/user, obj/item/slice) + SIGNAL_HANDLER + slice.AddComponent(/datum/component/ingredients_holder, null, fill_type, ingredient_type = ingredient_type, max_ingredients = max_ingredients, processed_holder = src) + /** * Adds context sensitivy directly to the customizable reagent holder file for screentips * Arguments: diff --git a/code/datums/components/jetpack.dm b/code/datums/components/jetpack.dm index c49c7d12154..3ebc9da823f 100644 --- a/code/datums/components/jetpack.dm +++ b/code/datums/components/jetpack.dm @@ -109,7 +109,7 @@ RegisterSignal(new_user, COMSIG_MOVABLE_SPACEMOVE, PROC_REF(stabilize)) if (effect_type) setup_trail(new_user) - new_user.inertia_move_multiplier /= drift_force // lower multiplier = faster drifting + new_user.inertia_move_multiplier_active /= drift_force // lower multiplier = faster drifting /datum/component/jetpack/proc/deactivate(datum/source, mob/old_user) SIGNAL_HANDLER @@ -126,7 +126,7 @@ COMSIG_MOVABLE_SPACEMOVE, )) QDEL_NULL(trail) - old_user.inertia_move_multiplier *= drift_force + old_user.inertia_move_multiplier_active *= drift_force /datum/component/jetpack/proc/move_react(mob/source) SIGNAL_HANDLER diff --git a/code/datums/components/leash.dm b/code/datums/components/leash.dm index ef0b278c799..2047d3ffb87 100644 --- a/code/datums/components/leash.dm +++ b/code/datums/components/leash.dm @@ -2,17 +2,17 @@ /// but teleporting if necessary. /datum/component/leash /// The owner of the leash. If this is qdeleted, the leash is as well. - var/atom/movable/owner - + var/atom/owner /// The maximum distance you can move from your owner var/distance - /// The object type to create on the old turf when forcibly teleporting out var/force_teleport_out_effect - /// The object type to create on the new turf when forcibly teleporting out var/force_teleport_in_effect - + /// Avoid sending out "too far" bubbles + var/silent = FALSE + /// Should we snap instead of teleporting back? + var/snap_on_teleport = FALSE VAR_PRIVATE // Pathfinding can yield, so only move us closer if this is the best one current_path_tick = 0 @@ -21,10 +21,12 @@ performing_path_move = FALSE /datum/component/leash/Initialize( - atom/movable/owner, + atom/owner, distance = 3, force_teleport_out_effect, force_teleport_in_effect, + silent = FALSE, + snap_on_teleport = FALSE, ) . = ..() @@ -32,8 +34,8 @@ stack_trace("Parent must be a movable") return COMPONENT_INCOMPATIBLE - if (!ismovable(owner)) - stack_trace("[owner] (owner) is not a movable") + if (!isatom(owner)) + stack_trace("[owner] (owner) is not an atom") return COMPONENT_INCOMPATIBLE if (!isnum(distance)) @@ -52,18 +54,22 @@ src.distance = distance src.force_teleport_out_effect = force_teleport_out_effect src.force_teleport_in_effect = force_teleport_in_effect + src.silent = silent + src.snap_on_teleport = snap_on_teleport RegisterSignal(owner, COMSIG_QDELETING, PROC_REF(on_owner_qdel)) + RegisterSignal(parent, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(on_parent_pre_move)) + check_distance() + + if (!ismovable(owner)) + return + var/static/list/container_connections = list( COMSIG_MOVABLE_MOVED = PROC_REF(on_owner_moved), ) - AddComponent(/datum/component/connect_containers, owner, container_connections) RegisterSignal(owner, COMSIG_MOVABLE_MOVED, PROC_REF(on_owner_moved)) - RegisterSignal(parent, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(on_parent_pre_move)) - - check_distance() /datum/component/leash/Destroy() owner = null @@ -97,7 +103,7 @@ if (get_dist(new_location_turf, owner) <= distance) return NONE - if (ismob(source)) + if (ismob(source) && !silent) source.balloon_alert(source, "too far!") return COMPONENT_MOVABLE_BLOCK_PRE_MOVE @@ -124,7 +130,7 @@ var/list/path = get_path_to(parent, owner, mintargetdist = distance) - if (last_completed_path_tick > our_path_tick) + if (last_completed_path_tick > our_path_tick || QDELETED(src)) return last_completed_path_tick = our_path_tick @@ -158,9 +164,11 @@ /datum/component/leash/proc/force_teleport_back(reason) PRIVATE_PROC(TRUE) - var/atom/movable/movable_parent = parent + if (snap_on_teleport) + qdel(src) + return - SSblackbox.record_feedback("tally", "leash_force_teleport_back", 1, reason) + var/atom/movable/movable_parent = parent if (force_teleport_out_effect) new force_teleport_out_effect(movable_parent.loc) @@ -171,7 +179,9 @@ new force_teleport_in_effect(movable_parent.loc) if (ismob(movable_parent)) - movable_parent.balloon_alert(movable_parent, "moved out of range!") + SSblackbox.record_feedback("tally", "leash_force_teleport_back", 1, reason) + if(!silent) + movable_parent.balloon_alert(movable_parent, "moved out of range!") SEND_SIGNAL(parent, COMSIG_LEASH_FORCE_TELEPORT) diff --git a/code/datums/components/manual_blinking.dm b/code/datums/components/manual_blinking.dm index aed2c531e3d..b02646dc686 100644 --- a/code/datums/components/manual_blinking.dm +++ b/code/datums/components/manual_blinking.dm @@ -28,7 +28,7 @@ var/mob/living/carbon/carbon_parent = parent ADD_TRAIT(carbon_parent, TRAIT_PREVENT_BLINK_LOOPS, REF(src)) - carbon_parent.update_body() + carbon_parent.update_eyes() parent_eyes = carbon_parent.get_organ_slot(ORGAN_SLOT_EYES) if(!parent_eyes || IS_ROBOTIC_ORGAN(parent_eyes)) @@ -47,7 +47,7 @@ to_chat(parent, span_notice("You revert back to automatic blinking.")) var/mob/living/carbon/carbon_parent = parent carbon_parent.cure_blind(REF(src)) - carbon_parent.update_body() + carbon_parent.update_eyes() return ..() /datum/component/manual_blinking/RegisterWithParent() diff --git a/code/datums/components/plumbing/_plumbing.dm b/code/datums/components/plumbing/_plumbing.dm index 87c89b20441..35ba39e5f2f 100644 --- a/code/datums/components/plumbing/_plumbing.dm +++ b/code/datums/components/plumbing/_plumbing.dm @@ -100,7 +100,7 @@ if(istype(duct)) if(duct.neighbours && (duct.duct_layer & ducting_layer)) duct.neighbours[parent] = opposite_dir - duct.update_appearance(UPDATE_ICON_STATE) + duct.update_appearance(UPDATE_ICON) duct.net.add_plumber(src, direction) continue @@ -123,7 +123,7 @@ for(var/obj/machinery/duct/pipe as anything in net.ducts) if(pipe.neighbours[parent]) pipe.neighbours -= parent - pipe.update_appearance(UPDATE_ICON_STATE) + pipe.update_appearance(UPDATE_ICON) //remove ourself from this network and delete it if emtpy if(net.remove_plumber(src)) @@ -171,9 +171,7 @@ if(tile_covered) return - //Copied from ducts handle_layer() var/offset - switch(ducting_layer) if(FIRST_DUCT_LAYER) offset = -10 @@ -186,12 +184,12 @@ if(FIFTH_DUCT_LAYER) offset = 10 - var/duct_x = offset - parent_movable.pixel_x - parent_movable.pixel_w - var/duct_y = offset - parent_movable.pixel_y - parent_movable.pixel_z var/duct_layer = PLUMBING_PIPE_VISIBILE_LAYER + ducting_layer * 0.0003 for(var/direction in GLOB.cardinals) var/color + var/duct_x = offset - parent_movable.pixel_x - parent_movable.pixel_w + var/duct_y = offset - parent_movable.pixel_y - parent_movable.pixel_z if(direction & initial(demand_connects)) color = demand_color else if(direction & initial(supply_connects)) @@ -221,6 +219,7 @@ new_supply_connects |= turn(direction, angle) demand_connects = new_demand_connects supply_connects = new_supply_connects + parent_obj.update_appearance(UPDATE_OVERLAYS) if(length(ducts)) disable() diff --git a/code/datums/components/plumbing/boulder_reactions.dm b/code/datums/components/plumbing/boulder_reactions.dm new file mode 100644 index 00000000000..982a7839d7a --- /dev/null +++ b/code/datums/components/plumbing/boulder_reactions.dm @@ -0,0 +1,32 @@ +/// The boulder machines take in many types of chems, but should only ever eject "waste" chems, +/datum/component/plumbing/boulder_reactions + demand_connects = WEST + supply_connects = EAST + +/datum/component/plumbing/boulder_reactions/Initialize(ducting_layer) + if(!istype(parent, /obj/machinery/bouldertech/refinery)) + return COMPONENT_INCOMPATIBLE + return ..() + +/datum/component/plumbing/boulder_reactions/send_request(dir) + var/obj/machinery/bouldertech/refinery/the_refinery = parent + var/list/datum/reagents/boosters = the_refinery.get_booster_reagents() + + for(var/datum/reagent/booster as anything in boosters) + process_request(MACHINE_REAGENT_TRANSFER, booster, dir, TRUE) + +/datum/component/plumbing/boulder_reactions/can_give(amount, reagent, datum/ductnet/net) + if(!reagents.total_volume || amount <= 0) + return FALSE + + var/obj/machinery/bouldertech/refinery/the_refinery = parent + if(reagent) + if(reagent != the_refinery.waste_chemical) //Always allow waste chemicals to enter. + return FALSE + + return !!reagents.has_reagent(the_refinery.waste_chemical) + +/datum/component/plumbing/boulder_reactions/transfer_to(datum/component/plumbing/target, amount, reagent, datum/ductnet/net, round_robin) + var/obj/machinery/bouldertech/refinery/the_refinery = parent + + reagents.trans_to(target.recipient_reagents_holder(), amount, target_id = the_refinery.waste_chemical, methods = round_robin ? LINEAR : NONE) diff --git a/code/datums/components/plumbing/chemical_acclimator.dm b/code/datums/components/plumbing/chemical_acclimator.dm index a8bb511c374..4f3b1dcc4d9 100644 --- a/code/datums/components/plumbing/chemical_acclimator.dm +++ b/code/datums/components/plumbing/chemical_acclimator.dm @@ -1,7 +1,6 @@ /datum/component/plumbing/acclimator demand_connects = WEST supply_connects = EAST - var/obj/machinery/plumbing/acclimator/myacclimator /datum/component/plumbing/acclimator/Initialize(ducting_layer) if(!istype(parent, /obj/machinery/plumbing/acclimator)) diff --git a/code/datums/components/reflection.dm b/code/datums/components/reflection.dm index 5e786b0c4ac..bd24a4e4f82 100644 --- a/code/datums/components/reflection.dm +++ b/code/datums/components/reflection.dm @@ -204,6 +204,7 @@ reflection.name = "[target.name]'s reflection" SEND_SIGNAL(target, COMSIG_REFLECTION_UPDATED, parent, reflection) + SEND_SIGNAL(parent, COMSIG_REFLECTED_IMAGE_UPDATED, reflection) ///Called when the target movable changes its appearance or dir. /datum/component/reflection/proc/update_reflection(atom/movable/source) diff --git a/code/datums/components/religious_tool.dm b/code/datums/components/religious_tool.dm index 2d51563d7b0..19cf2e07941 100644 --- a/code/datums/components/religious_tool.dm +++ b/code/datums/components/religious_tool.dm @@ -182,7 +182,7 @@ if(performing_rite.invoke_effect(user, parent)) performing_rite.post_invoke_effects(user, parent) - easy_access_sect.adjust_favor(-performing_rite.favor_cost) + easy_access_sect.adjust_favor(-performing_rite.favor_cost) if(!(performing_rite.rite_flags & RITE_ALLOW_MULTIPLE_PERFORMS)) if(performing_rite.rite_flags & RITE_AUTO_DELETE) diff --git a/code/datums/components/reskinnable_atom.dm b/code/datums/components/reskinnable_atom.dm index ab46ec0c329..9abf3ed6c60 100644 --- a/code/datums/components/reskinnable_atom.dm +++ b/code/datums/components/reskinnable_atom.dm @@ -258,7 +258,7 @@ var/list/atom_skins = get_atom_skins() for(var/reskin_name, reskin_typepath in get_skins_by_name()) var/datum/atom_skin/reskin = atom_skins[reskin_typepath] - items[reskin_name] = image(icon = reskin.new_icon || atom_parent.icon, icon_state = reskin.new_icon_state || atom_parent.icon_state) + items[reskin_name] = reskin.get_preview_icon(atom_parent) sort_list(items) diff --git a/code/datums/components/revenant_prison.dm b/code/datums/components/revenant_prison.dm new file mode 100644 index 00000000000..d5ba6529a62 --- /dev/null +++ b/code/datums/components/revenant_prison.dm @@ -0,0 +1,67 @@ +/datum/component/revenant_prison + // Whether a revenant should be created upon release + var/create_on_release = FALSE + // The revenant which is currently imprisoned + var/mob/living/basic/revenant/revenant + // ckey of the player who controlled it when it was imprisoned + var/old_ckey + +/datum/component/revenant_prison/Initialize(mob/living/basic/revenant/revenant, create_on_release = FALSE) + if(create_on_release) + return ..() + if(!istype(revenant) || !isobj(parent)) + return COMPONENT_INCOMPATIBLE + . = ..() + + src.revenant = revenant + revenant.dormant = TRUE + old_ckey = revenant.client?.ckey + revenant.forceMove(parent) + +/datum/component/revenant_prison/Destroy() + if(revenant?.client) + revenant.ghostize(can_reenter_corpse = FALSE) + QDEL_NULL(revenant) + return ..() + +/datum/component/revenant_prison/proc/on_parent_break(obj/source, damage_flags) + SIGNAL_HANDLER + source.visible_message(span_revenwarning("The revenant cackles as it escapes from [source]!")) + playsound(source.loc, 'sound/effects/chemistry/ahaha.ogg', 100, TRUE) + release_revenant(source, cause = "[parent] breaking") + +/datum/component/revenant_prison/proc/release_revenant(obj/source, cause) + SIGNAL_HANDLER + if(create_on_release) + revenant = new(get_turf(parent)) + if(!revenant) + qdel(src) + return + message_admins("[revenant] [ADMIN_FLW(revenant)] has been released from [source] [ADMIN_JMP(source)]. Cause: [cause]") + if(!revenant.reform(old_ckey)) + message_admins("Couldn't reform revenant upon release.") + revenant = null + qdel(src) + +/datum/component/revenant_prison/proc/shift_reflection(datum/source, obj/effect/abstract/reflection) + SIGNAL_HANDLER + apply_wibbly_filters(reflection) + +/datum/component/revenant_prison/proc/on_parent_examine(datum/source, mob/user, list/examine_list) + if(istype(parent, /obj/structure/mirror)) + examine_list += span_revenwarning("The reflection is shifting and distorted.") + +/datum/component/revenant_prison/RegisterWithParent() + RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_parent_examine)) + RegisterSignal(parent, COMSIG_ATOM_BREAK, PROC_REF(on_parent_break)) + RegisterSignal(parent, COMSIG_REVENANT_RELEASE, PROC_REF(release_revenant)) + RegisterSignal(parent, COMSIG_REFLECTED_IMAGE_UPDATED, PROC_REF(shift_reflection)) + +/datum/component/revenant_prison/UnregisterFromParent() + UnregisterSignal(parent, COMSIG_ATOM_EXAMINE) + UnregisterSignal(parent, COMSIG_ATOM_BREAK) + UnregisterSignal(parent, COMSIG_REVENANT_RELEASE) + UnregisterSignal(parent, COMSIG_REFLECTED_IMAGE_UPDATED) + +/datum/component/revenant_prison/PostTransfer(datum/new_parent) + revenant.forceMove(new_parent) diff --git a/code/datums/components/riding/riding.dm b/code/datums/components/riding/riding.dm index 8e5f1eab52f..5b094e65e57 100644 --- a/code/datums/components/riding/riding.dm +++ b/code/datums/components/riding/riding.dm @@ -30,8 +30,8 @@ var/list/rider_traits = list(TRAIT_NO_FLOATING_ANIM) /// We don't need roads where we're going if this is TRUE, allow normal movement in space tiles var/override_allow_spacemove = FALSE - /// can anyone other than the rider unbuckle the rider? - var/can_force_unbuckle = TRUE + /// determines behavior for other mobs trying to unbuckle riders + var/other_unbuckle = CAN_FORCE_UNBUCKLE /// Like last_bumped for mobs, but for vehicles. Exists to allow the door bump cooldown while also passing door openings through Bumped() var/vehicle_last_bumped = 0 @@ -67,8 +67,13 @@ RegisterSignals(parent, GLOB.movement_type_addtrait_signals, PROC_REF(on_movement_type_trait_gain)) RegisterSignals(parent, GLOB.movement_type_removetrait_signals, PROC_REF(on_movement_type_trait_loss)) RegisterSignal(parent, COMSIG_SUPERMATTER_CONSUMED, PROC_REF(on_entered_supermatter)) - if(!can_force_unbuckle) - RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, PROC_REF(force_unbuckle)) + switch(other_unbuckle) + if(CANNOT_FORCE_UNBUCKLE) + RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, PROC_REF(block_unbuckle)) + if(CAN_DISARM_UNBUCKLE) + RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, PROC_REF(block_unbuckle)) + if(isliving(parent)) + RegisterSignal(parent, COMSIG_LIVING_DISARM_HIT, PROC_REF(parent_disarmed)) /// This proc is called when a rider unbuckles, whether they chose to or not. If there's no more riders, this will be the riding component's death knell. /datum/component/riding/proc/vehicle_mob_unbuckle(datum/source, mob/living/rider, force = FALSE) @@ -88,6 +93,7 @@ unequip_buckle_inhands(rider) rider.updating_glide_size = TRUE UnregisterSignal(rider, COMSIG_LIVING_TRY_PULL) + UnregisterSignal(rider, COMSIG_LIVING_DISARM_HIT) for (var/trait in GLOB.movement_type_trait_to_flag) if (HAS_TRAIT(parent, trait)) REMOVE_TRAIT(rider, trait, REF(src)) @@ -105,6 +111,8 @@ if(rider.pulling == parent) rider.stop_pulling() RegisterSignal(rider, COMSIG_LIVING_TRY_PULL, PROC_REF(on_rider_try_pull)) + if(other_unbuckle == CAN_DISARM_UNBUCKLE) + RegisterSignal(rider, COMSIG_LIVING_DISARM_HIT, PROC_REF(rider_disarmed)) for (var/trait in GLOB.movement_type_trait_to_flag) if (HAS_TRAIT(parent, trait)) @@ -317,13 +325,110 @@ for (var/mob/rider in movable_parent.buckled_mobs) REMOVE_TRAIT(rider, trait, REF(src)) -/datum/component/riding/proc/force_unbuckle(atom/movable/source, mob/living/living_hitter) +/// Block attempts to unbuckle by direct click in certain conditions +/datum/component/riding/proc/block_unbuckle(atom/movable/source, mob/living/unbuckler) SIGNAL_HANDLER - if((living_hitter in source.buckled_mobs)) - return + if(!source.has_buckled_mobs() || (unbuckler in source.buckled_mobs)) + return NONE + + switch(other_unbuckle) + if(CANNOT_FORCE_UNBUCKLE) + to_chat(unbuckler, span_warning("You can't dismount [source]'s rider[length(source.buckled_mobs) == 1 ? "" : "s"]!")) + if(CAN_DISARM_UNBUCKLE) + parent_disarmed(source, unbuckler) + return COMPONENT_CANCEL_ATTACK_CHAIN +/// If our parent is a living mob it can be disarmed which may trigger a forced unbuckle +/datum/component/riding/proc/parent_disarmed(mob/living/source, mob/living/disarmer) + SIGNAL_HANDLER + if(!source.has_buckled_mobs() || (disarmer in source.buckled_mobs)) + return + var/mob/living/throwing = pick(source.buckled_mobs) + var/disarm_chance = get_disarm_chance(source) + get_disarm_chance(disarmer) + if(!prob(disarm_chance)) + if(disarm_chance > 0) + source.visible_message( + span_warning("[disarmer] shoves [source] around, trying to throw off [source.p_their()] rider[length(source.buckled_mobs) == 1 ? "" : "s"]!"), + span_warning("[disarmer] shoves you around, trying to throw off your rider[length(source.buckled_mobs) == 1 ? "" : "s"]!"), + vision_distance = COMBAT_MESSAGE_RANGE, + ) + if(source.is_blind()) + to_chat(source, span_warning("Someone shoves you around, trying to throw off your rider[length(source.buckled_mobs) == 1 ? "" : "s"]!")) + if(!disarmer.is_blind()) + switch(disarm_chance) + if(50 to INFINITY) + to_chat(disarmer, span_warning("[source] barely holds stable as you shove them around! Keep at it!")) + if(25 to 50) + to_chat(disarmer, span_warning("[source] holds stable as you shove them around! Weakening [source.p_their()] stability would help...")) + if(-INFINITY to 25) + to_chat(disarmer, span_warning("[source] effortlessly holds stable as you shove them around! You'd need to weaken [source.p_their()] stability...!")) + return + source.visible_message( + span_warning("As [disarmer] shoves [source] around, [throwing] is thrown from [parent]!"), + span_warning("As [disarmer] shoves you around, [throwing] is thrown from you!"), + ) + if(source.is_blind()) + to_chat(source, span_warning("As someone shoves you around, you feel [length(source.buckled_mobs) == 1 ? "your rider" : "one of your riders"] get thrown from you!")) + + source.unbuckle_mob(throwing, force = TRUE) + throwing.Knockdown(throwing.has_status_effect(/datum/status_effect/staggered) ? SHOVE_KNOCKDOWN_COLLATERAL : SHOVE_KNOCKDOWN_HUMAN) + +/// If our rider is disarmed, they may be thrown from the vehicle depending on their and the disarmer's stats +/datum/component/riding/proc/rider_disarmed(mob/living/rider, mob/living/disarmer) + SIGNAL_HANDLER + var/disarm_chance = get_disarm_chance(parent) + get_disarm_chance(rider) + if(!prob(disarm_chance)) + if(disarm_chance > 0) + rider.visible_message( + span_warning("[disarmer] shoves [rider] around, trying to throw [rider.p_them()] off [parent]!"), + span_warning("As [disarmer] shoves you around, you [(disarm_chance >= 50 ? "barely" : (disarm_chance >= 25 ? "" : "effortlessly"))] manage to hold on to [parent]!"), + vision_distance = COMBAT_MESSAGE_RANGE, + ) + if(rider.is_blind()) + to_chat(rider, span_warning("As someone shoves you around, you [(disarm_chance >= 50 ? "barely" : (disarm_chance >= 25 ? "" : "effortlessly"))] manage to hold on to [parent]!")) + if(!disarmer.is_blind()) + switch(disarm_chance) + if(50 to INFINITY) + to_chat(disarmer, span_warning("[rider] barely holds on to [parent] as you shove them around! Keep at it!")) + if(25 to 50) + to_chat(disarmer, span_warning("[rider] holds on to [parent] as you shove them around! Weakening [rider.p_their()] [pick("balance", "grip", "hold")] would help...")) + if(-INFINITY to 25) + to_chat(disarmer, span_warning("[rider] effortlessly holds on to [parent] as you shove them around! You'd need to weaken [rider.p_their()] [pick("balance", "grip", "hold")]...!")) + return + + rider.visible_message( + span_warning("As [disarmer] shoves [rider] around, [rider.p_they()] lose [rider.p_their()] [pick("balance", "grip", "hold")] and fall off [parent]!"), + span_warning("As [disarmer] shoves you around, you lose your [pick("balance", "grip", "hold")] and fall off [parent]!") + ) + if(rider.is_blind()) + to_chat(rider, span_warning("As someone shoves you around, you lose your [pick("balance", "grip", "hold")] and fall off [parent]!")) + + var/atom/movable/riding = parent + riding.unbuckle_mob(rider, force = TRUE) + if(rider.has_status_effect(/datum/status_effect/staggered)) + rider.Knockdown(2 SECONDS) + +/// Calculates chance to be thrown off the mount based on mob state +/datum/component/riding/proc/get_disarm_chance(mob/living/disarmed) + if(!isliving(disarmed)) + return 0 + + var/staminaloss = round(disarmed.get_stamina_loss(), 0.1) + var/healthpercent = round(1 - (disarmed.health / disarmed.maxHealth), 0.01) + + var/chance = 0 + + chance += disarmed.has_status_effect(/datum/status_effect/staggered) ? 25 : 0 + chance += INCAPACITATED_IGNORING(disarmed, INCAPABLE_STASIS) ? 75 : 0 + chance += staminaloss >= 10 ? (staminaloss * 0.5) : 0 + chance += healthpercent >= 0.25 ? ((disarmed.health / disarmed.maxHealth) * 50) : 0 + + chance -= max(0, disarmed.mob_size - MOB_SIZE_HUMAN) * 12.5 + + return chance + /// When we touch a crystal, kill everything inside us /datum/component/riding/proc/on_entered_supermatter(atom/movable/ridden, atom/movable/supermatter) SIGNAL_HANDLER diff --git a/code/datums/components/riding/riding_mob.dm b/code/datums/components/riding/riding_mob.dm index b14e96e9cd8..cd8d630d2e7 100644 --- a/code/datums/components/riding/riding_mob.dm +++ b/code/datums/components/riding/riding_mob.dm @@ -452,6 +452,7 @@ ) /datum/component/riding/creature/pony + other_unbuckle = CAN_DISARM_UNBUCKLE vehicle_move_delay = 1.5 COOLDOWN_DECLARE(pony_trot_cooldown) @@ -668,7 +669,7 @@ ) /datum/component/riding/creature/leaper - can_force_unbuckle = FALSE + other_unbuckle = CAN_DISARM_UNBUCKLE can_use_abilities = TRUE ride_check_flags = JUST_FRIEND_RIDERS @@ -813,3 +814,40 @@ TEXT_EAST = list(0, 0, MOB_BELOW_PIGGYBACK_LAYER), TEXT_WEST = list(0, 0, MOB_BELOW_PIGGYBACK_LAYER), ) + + +/datum/component/riding/creature/ed_bot + ai_behavior_while_ridden = RIDING_PAUSE_AI_MOVEMENT //shoot while moving! + can_use_abilities = TRUE + uses_native_speed = TRUE + +/datum/component/riding/creature/ed_bot/get_rider_offsets_and_layers(pass_index, mob/offsetter) + return list( + TEXT_NORTH = list(0, 7), + TEXT_SOUTH = list(0, 7), + TEXT_EAST = list(-10, 7), + TEXT_WEST = list(10, 7), + ) + +/datum/component/riding/creature/ed_bot/get_parent_offsets_and_layers() + return list( + TEXT_NORTH = list(0, 0, MOB_BELOW_PIGGYBACK_LAYER), + TEXT_SOUTH = list(0, 0, MOB_ABOVE_PIGGYBACK_LAYER), + TEXT_EAST = list(0, 0, MOB_BELOW_PIGGYBACK_LAYER), + TEXT_WEST = list(0, 0, MOB_BELOW_PIGGYBACK_LAYER), + ) + +/datum/component/riding/creature/ed_bot/ride_check(mob/living/rider, consequences = TRUE) + . = ..() + if(!.) + return + var/mob/living/basic/bot/secbot/my_bot = parent + if(!(my_bot.bot_mode_flags & BOT_MODE_ON)) + return FALSE + return (my_bot.bot_access_flags & BOT_COVER_EMAGGED) + +/datum/component/riding/creature/ed_bot/nukie + +/datum/component/riding/creature/ed_bot/nukie/ride_check(mob/living/rider, consequences = TRUE) + var/mob/living/basic/bot/secbot/my_bot = parent + return my_bot.faction_check_atom(rider) diff --git a/code/datums/components/riding/riding_vehicle.dm b/code/datums/components/riding/riding_vehicle.dm index c9be8746ec8..cabff5c5d02 100644 --- a/code/datums/components/riding/riding_vehicle.dm +++ b/code/datums/components/riding/riding_vehicle.dm @@ -160,6 +160,7 @@ /datum/component/riding/vehicle/lavaboat/dragonboat vehicle_move_delay = 1 + keytype = null /datum/component/riding/vehicle/lavaboat/dragonboat/get_rider_offsets_and_layers(pass_index, mob/offsetter) return list( @@ -169,11 +170,6 @@ TEXT_WEST = list(1, 2), ) -/datum/component/riding/vehicle/lavaboat/dragonboat - vehicle_move_delay = 1 - keytype = null - - /datum/component/riding/vehicle/janicart keytype = /obj/item/key/janitor diff --git a/code/datums/components/style/style.dm b/code/datums/components/style/style.dm index 9f65e710989..065dca7c56d 100644 --- a/code/datums/components/style/style.dm +++ b/code/datums/components/style/style.dm @@ -20,9 +20,6 @@ #define ACTION_GEYSER_MARKED "GEYSER MARKED" #define ACTION_VENT_TAPPED "VENT TAPPED" -#define ACTION_MULTIPLIER_PER_VENT_VALUE 0.1 -#define ACTION_MULTIPLIER_MAJOR_KILL 0.1 - /datum/component/style /// Amount of style we have. var/style_points = -1 @@ -75,13 +72,15 @@ ) -/datum/component/style/Initialize(multitooled = FALSE) +/datum/component/style/Initialize(multitooled = FALSE, stored_permanent_multiplier = 0) if(!ismob(parent)) return COMPONENT_INCOMPATIBLE START_PROCESSING(SSdcs, src) if(multitooled) src.multitooled = multitooled + if(stored_permanent_multiplier) + src.permanent_multiplier = stored_permanent_multiplier ADD_TRAIT(parent, TRAIT_STYLISH, REF(src)) // SKYRAT EDIT ADD - allows style meter chads to do flips @@ -331,6 +330,10 @@ else source.balloon_alert(source, "unable to hotswap!") +/// Increase our permanent multiplier based on the modifier. +/datum/component/style/proc/adjust_permanent_multiplier(modifier) + permanent_multiplier += modifier + // Point givers /datum/component/style/proc/on_punch(mob/living/carbon/human/punching_person, atom/attacked_atom, proximity) SIGNAL_HANDLER @@ -375,10 +378,10 @@ add_action(ACTION_GIBTONITE_BOOM, 50) return - if(rock.mineralType) + if(rock.mineral_type) if(exp_multiplier) add_action(ACTION_ORE_MINED, 40) - rock.mineralAmt = ROUND_UP(rock.mineralAmt * (1 + ((rank * 0.1) - 0.3))) // You start out getting 20% less ore, but it goes up to 20% more at S-tier + rock.mineral_amt = ROUND_UP(rock.mineral_amt * (1 + ((rank * 0.1) - 0.3))) // You start out getting 20% less ore, but it goes up to 20% more at S-tier /datum/component/style/proc/on_resonator_burst(datum/source, mob/creator, mob/living/hit_living) SIGNAL_HANDLER @@ -422,7 +425,6 @@ var/vent_value = vent.boulder_size / BOULDER_SIZE_MEDIUM add_action(ACTION_VENT_TAPPED, 250 * vent_value) - permanent_multiplier += ACTION_MULTIPLIER_PER_VENT_VALUE * vent_value // Emote-based multipliers /datum/component/style/proc/on_taunt() @@ -450,7 +452,6 @@ if(ismegafauna(died)) add_action(ACTION_MAJOR_KILL, 350) - permanent_multiplier += ACTION_MULTIPLIER_MAJOR_KILL else if(died.maxHealth >= 75) //at least legions add_action(ACTION_KILL, 125) @@ -479,6 +480,3 @@ #undef ACTION_MARK_DETONATED #undef ACTION_GEYSER_MARKED #undef ACTION_VENT_TAPPED - -#undef ACTION_MULTIPLIER_PER_VENT_VALUE -#undef ACTION_MULTIPLIER_MAJOR_KILL diff --git a/code/datums/components/style/style_meter.dm b/code/datums/components/style/style_meter.dm index 7b399927e33..535242b8b61 100644 --- a/code/datums/components/style/style_meter.dm +++ b/code/datums/components/style/style_meter.dm @@ -7,12 +7,15 @@ In addition, at high style, you are able to swap an item in your hand with one in your backpack by hitting one with another." icon_state = "style_meter" icon = 'icons/obj/clothing/glasses.dmi' + w_class = WEIGHT_CLASS_SMALL /// The style meter component we give. var/datum/component/style/style_meter /// Mutable appearance added to the attached glasses var/mutable_appearance/meter_appearance /// If this is multitooled, which is passed onto the component on-creation, if one doesn't currently exist var/multitooled = FALSE + /// Stored permanent multiplier from doing mining-related tasks (e.g. vents, megafauna) + var/stored_permanent_multiplier = 0 /obj/item/style_meter/Initialize(mapload) . = ..() @@ -49,7 +52,7 @@ if(carbon_wearer.glasses != interacting_with) return . - style_meter = carbon_wearer.AddComponent(/datum/component/style, multitooled) + start_meter(carbon_wearer) return . /obj/item/style_meter/Moved(atom/old_loc, Dir, momentum_change) @@ -68,7 +71,7 @@ QDEL_NULL(style_meter) return - style_meter = equipper.AddComponent(/datum/component/style, multitooled) + start_meter(equipper) /// Signal proc for when the meter-holding glasses are dropped/unequipped @@ -122,6 +125,37 @@ return QDEL_NULL(style_meter) +/// Create the style meter component, attach it to our wearer, register other things onto the component. +/obj/item/style_meter/proc/start_meter(mob/living/carbon/carbon_wearer) + style_meter = carbon_wearer.AddComponent(/datum/component/style, multitooled, stored_permanent_multiplier) + RegisterSignal(SSdcs, COMSIG_GLOB_MOB_DEATH, PROC_REF(on_death)) + RegisterSignal(carbon_wearer, COMSIG_LIVING_ON_VENT_WIN, PROC_REF(on_vent_win)) + +/// On a successful vent tap, adjust permanent multiplier, scaling with vent value. +/obj/item/style_meter/proc/on_vent_win(datum/source, obj/structure/ore_vent/vent) + SIGNAL_HANDLER + + var/vent_value = vent.boulder_size / BOULDER_SIZE_MEDIUM + adjust_permanent_multiplier(ACTION_MULTIPLIER_PER_VENT_VALUE * vent_value) + +/// When something dies, if it's a megafauna, adjust our permanent multiplier. +/obj/item/style_meter/proc/on_death(datum/source, mob/living/died, gibbed) + SIGNAL_HANDLER + if(!style_meter) + return + // If we have an active style meter, we're on someone's face. Use them to check if the dead megafauna could be credited to them... + var/mob/mob_parent = style_meter.parent + if(mob_parent.faction_check_atom(died) || !died.has_faction(FACTION_MINING) || (died.z != mob_parent.z) || !(died in view(mob_parent.client?.view, get_turf(mob_parent)))) + return + + if(ismegafauna(died)) + adjust_permanent_multiplier(ACTION_MULTIPLIER_MAJOR_KILL) + +/// Adjust the stored permanent multiplier. If we have an active style meter, update that style meter too. +/obj/item/style_meter/proc/adjust_permanent_multiplier(modifier) + stored_permanent_multiplier += modifier + if(style_meter) + style_meter.adjust_permanent_multiplier(modifier) /atom/movable/screen/style_meter_background icon_state = "style_meter_background" diff --git a/code/datums/components/temporary_body.dm b/code/datums/components/temporary_body.dm index d069116cf0a..bf1dc618d48 100644 --- a/code/datums/components/temporary_body.dm +++ b/code/datums/components/temporary_body.dm @@ -79,7 +79,7 @@ SIGNAL_HANDLER var/mob/new_body = parent - var/mob/dead/observer/ghost = new_body.get_ghost() || new_body.ghostize() + var/mob/dead/observer/ghost = new_body.get_ghost() || new_body.ghostize(forced = TRUE) if(QDELETED(ghost)) stack_trace("[src] belonging to [parent] was completely unable to find a ghost to put back into a body!") qdel(src) // i guess this is useless now @@ -90,7 +90,7 @@ if(old_mind.current != old_body) stack_trace("Temporary body returning mind to old body, but the mind's current body doesn't match the old body!") old_mind.set_current(old_body) - if(old_body.stat != DEAD) + if(old_body.stat != DEAD && !IS_FAKE_KEY(old_body.key)) ghost.reenter_corpse() qdel(src) // we're done here diff --git a/code/datums/components/transforming.dm b/code/datums/components/transforming.dm index 5fdbc446da6..f8d325cf98d 100644 --- a/code/datums/components/transforming.dm +++ b/code/datums/components/transforming.dm @@ -24,6 +24,16 @@ var/sharpness_on /// Hitsound played when active var/hitsound_on + /// Force when the weapon is inactive + var/force_off + /// Throwforce when the weapon is inactive + var/throwforce_off + /// Throw speed of the weapon when inactive + var/throw_speed_off + /// Weight class of the weapon when inactive + var/w_class_off + /// The sharpness of the weapon when inactive + var/sharpness_off /// List of the original continuous attack verbs the item has. var/list/attack_verb_continuous_off /// List of the original simple attack verbs the item has. @@ -75,6 +85,12 @@ src.clumsy_damage = clumsy_damage src.inhand_icon_change = inhand_icon_change + src.force_off = item_parent.force + src.throwforce_off = item_parent.throwforce + src.throw_speed_off = item_parent.throw_speed + src.sharpness_off = item_parent.sharpness // Raw value, not via the getter + src.w_class_off = item_parent.w_class + if(attack_verb_continuous_on) src.attack_verb_continuous_on = attack_verb_continuous_on attack_verb_continuous_off = item_parent.attack_verb_continuous @@ -95,6 +111,10 @@ RegisterSignal(parent, COMSIG_DETECTIVE_SCANNED, PROC_REF(on_scan)) RegisterSignal(parent, COMSIG_ITEM_APPLY_FANTASY_BONUSES, PROC_REF(apply_fantasy_bonuses)) RegisterSignal(parent, COMSIG_ITEM_REMOVE_FANTASY_BONUSES, PROC_REF(remove_fantasy_bonuses)) + RegisterSignal(parent, COMSIG_ATOM_FINALIZE_MATERIAL_EFFECTS, PROC_REF(on_materials_updated)) + RegisterSignal(parent, COMSIG_ATOM_FINALIZE_REMOVE_MATERIAL_EFFECTS, PROC_REF(on_materials_updated)) + RegisterSignal(parent, COMSIG_ATOM_SINGLE_MATERIAL_EFFECT_APPLY, PROC_REF(on_material_apply)) + RegisterSignal(parent, COMSIG_ATOM_SINGLE_MATERIAL_EFFECT_REMOVE, PROC_REF(on_material_remove)) /datum/component/transforming/proc/apply_fantasy_bonuses(obj/item/source, bonus) SIGNAL_HANDLER @@ -110,9 +130,38 @@ force_on = source.reset_fantasy_variable("force_on", force_on) throwforce_on = source.reset_fantasy_variable("throwforce_on", throwforce_on) +/datum/component/transforming/proc/on_material_apply(obj/item/source, datum/material/material, amount, multiplier) + SIGNAL_HANDLER + // Opposite state's force needs to be calculated for each material's effect + if (active) + force_off *= GET_MATERIAL_MODIFIER(source.get_material_force_modifier(material, initial(source.sharpness)), multiplier) + throwforce_off *= GET_MATERIAL_MODIFIER(source.get_material_throwforce_modifier(material, initial(source.sharpness)), multiplier) + else + force_on *= GET_MATERIAL_MODIFIER(source.get_material_force_modifier(material, sharpness_on), multiplier) + throwforce_on *= GET_MATERIAL_MODIFIER(source.get_material_throwforce_modifier(material, sharpness_on), multiplier) + +/datum/component/transforming/proc/on_material_remove(obj/item/source, datum/material/material, amount, multiplier) + SIGNAL_HANDLER + // Same as appliation but inversed + if (active) + force_off /= GET_MATERIAL_MODIFIER(source.get_material_force_modifier(material, initial(source.sharpness)), multiplier) + throwforce_off /= GET_MATERIAL_MODIFIER(source.get_material_throwforce_modifier(material, initial(source.sharpness)), multiplier) + else + force_on /= GET_MATERIAL_MODIFIER(source.get_material_force_modifier(material, sharpness_on), multiplier) + throwforce_on /= GET_MATERIAL_MODIFIER(source.get_material_throwforce_modifier(material, sharpness_on), multiplier) + +/datum/component/transforming/proc/on_materials_updated(obj/item/source, list/materials, datum/material/main_material) + SIGNAL_HANDLER + // Current force can be set directly + if (active) + force_on = source.force + throwforce_on = source.throwforce + else + force_off = source.force + throwforce_off = source.throwforce /datum/component/transforming/UnregisterFromParent() - UnregisterSignal(parent, list(COMSIG_ITEM_ATTACK_SELF, COMSIG_ITEM_SHARPEN_ACT, COMSIG_DETECTIVE_SCANNED)) + UnregisterSignal(parent, list(COMSIG_ITEM_ATTACK_SELF, COMSIG_ITEM_SHARPEN_ACT, COMSIG_DETECTIVE_SCANNED, COMSIG_ATOM_FINALIZE_MATERIAL_EFFECTS, COMSIG_ATOM_FINALIZE_REMOVE_MATERIAL_EFFECTS)) /datum/component/transforming/proc/on_scan(datum/source, mob/user, datum/detective_scanner_log/entry) SIGNAL_HANDLER @@ -198,13 +247,13 @@ */ /datum/component/transforming/proc/set_active(obj/item/source) ADD_TRAIT(source, TRAIT_TRANSFORM_ACTIVE, REF(src)) - if(sharpness_on) + if(!isnull(sharpness_on)) source.sharpness = sharpness_on - if(force_on) - source.force = force_on + (source.sharpness ? sharpened_bonus : 0) - if(throwforce_on) - source.throwforce = throwforce_on + (source.sharpness ? sharpened_bonus : 0) - if(throw_speed_on) + if(!isnull(force_on)) + source.force = force_on + if(!isnull(throwforce_on)) + source.throwforce = throwforce_on + if(!isnull(throw_speed_on)) source.throw_speed = throw_speed_on if(LAZYLEN(attack_verb_continuous_on)) @@ -228,14 +277,14 @@ */ /datum/component/transforming/proc/set_inactive(obj/item/source) REMOVE_TRAIT(source, TRAIT_TRANSFORM_ACTIVE, REF(src)) - if(sharpness_on) - source.sharpness = initial(source.sharpness) - if(force_on) - source.force = initial(source.force) + (source.sharpness ? sharpened_bonus : 0) - if(throwforce_on) - source.throwforce = initial(source.throwforce) + (source.sharpness ? sharpened_bonus : 0) - if(throw_speed_on) - source.throw_speed = initial(source.throw_speed) + if(!isnull(sharpness_on)) + source.sharpness = sharpness_off + if(!isnull(force_on)) + source.force = force_off + if(!isnull(throwforce_on)) + source.throwforce = throwforce_off + if(!isnull(throw_speed_on)) + source.throw_speed = throwforce_off if(LAZYLEN(attack_verb_continuous_on)) source.attack_verb_continuous = attack_verb_continuous_off @@ -248,6 +297,8 @@ source.icon_state = initial(source.post_init_icon_state) else source.icon_state = initial(source.icon_state) // BUBBER CHANGE END + source.update_weight_class(w_class_off) + source.icon_state = initial(source.icon_state) source.inhand_icon_state = initial(source.inhand_icon_state) source.update_appearance() source.update_inhand_icon() @@ -310,3 +361,11 @@ if(force_on + increment > max) return COMPONENT_BLOCK_SHARPEN_MAXED sharpened_bonus = increment + force_on += sharpened_bonus + throwforce_on += sharpened_bonus + force_off += sharpened_bonus + throwforce_off += sharpened_bonus + // Mimics base whetstone effect for the on state + sharpness_on = SHARP_EDGED + if (!active) + return COMPONENT_BLOCK_SHARPEN_SHARPNESS diff --git a/code/datums/components/tug_towards.dm b/code/datums/components/tug_towards.dm index 6b1a094b6d1..338d27660ee 100644 --- a/code/datums/components/tug_towards.dm +++ b/code/datums/components/tug_towards.dm @@ -40,13 +40,18 @@ /datum/component/tug_towards/Destroy(force) tugging_to_targets.Cut() - animate( - parent, - pixel_x = -current_tug_offset_x, - pixel_y = -current_tug_offset_y, - time = 0.2 SECONDS, - flags = ANIMATION_RELATIVE - ) + if(isliving(parent)) + var/mob/living/living_parent = parent + living_parent.remove_offsets(REF(src)) + + else + animate( + parent, + pixel_x = -current_tug_offset_x, + pixel_y = -current_tug_offset_y, + time = 0.2 SECONDS, + flags = ANIMATION_RELATIVE + ) return ..() @@ -93,6 +98,9 @@ SIGNAL_HANDLER PRIVATE_PROC(TRUE) + if(QDELETED(src)) + return // another movement call could have deleted us + var/atom/atom_parent = parent var/mob/mob_parent = parent @@ -123,13 +131,18 @@ if (total_tug_x == current_tug_offset_x && total_tug_y == current_tug_offset_y) return - animate( - atom_parent, - pixel_x = -current_tug_offset_x + total_tug_x, - pixel_y = -current_tug_offset_y + total_tug_y, - time = 0.2 SECONDS, - flags = ANIMATION_RELATIVE - ) + if(isliving(mob_parent)) + var/mob/living/living_parent = mob_parent + living_parent.add_offsets(REF(src), x_add = total_tug_x, y_add = total_tug_y) + + else + animate( + atom_parent, + pixel_x = -current_tug_offset_x + total_tug_x, + pixel_y = -current_tug_offset_y + total_tug_y, + time = 0.2 SECONDS, + flags = ANIMATION_RELATIVE + ) current_tug_offset_x = total_tug_x current_tug_offset_y = total_tug_y diff --git a/code/datums/components/twohanded.dm b/code/datums/components/twohanded.dm index a65d8c4f3c7..0db3642eb60 100644 --- a/code/datums/components/twohanded.dm +++ b/code/datums/components/twohanded.dm @@ -149,6 +149,8 @@ RegisterSignal(parent, COMSIG_ITEM_REMOVE_FANTASY_BONUSES, PROC_REF(remove_fantasy_bonuses)) RegisterSignal(parent, COMSIG_ATOM_FINALIZE_MATERIAL_EFFECTS, PROC_REF(on_materials_updated)) RegisterSignal(parent, COMSIG_ATOM_FINALIZE_REMOVE_MATERIAL_EFFECTS, PROC_REF(on_materials_updated)) + RegisterSignal(parent, COMSIG_ATOM_SINGLE_MATERIAL_EFFECT_APPLY, PROC_REF(on_material_apply)) + RegisterSignal(parent, COMSIG_ATOM_SINGLE_MATERIAL_EFFECT_REMOVE, PROC_REF(on_material_remove)) // Remove all siginals registered to the parent item /datum/component/two_handed/UnregisterFromParent() @@ -427,15 +429,26 @@ SIGNAL_HANDLER // With materials assigned we need to update our forces. if (wielded) - // Materials modify force multiplicatively! Most of the time, for snowflakes they gotta handle it themselves - if (!isnull(force_wielded)) - force_unwielded *= source.force / force_wielded force_wielded = source.force else - if (!isnull(force_unwielded)) - force_wielded *= source.force / force_unwielded force_unwielded = source.force +/datum/component/two_handed/proc/on_material_apply(obj/item/source, datum/material/material, amount, multiplier) + SIGNAL_HANDLER + // Opposite state's force needs to be calculated for each material's effect + if (wielded) + force_unwielded *= GET_MATERIAL_MODIFIER(source.get_material_force_modifier(material, source.sharpness), multiplier) + else + force_wielded *= GET_MATERIAL_MODIFIER(source.get_material_force_modifier(material, source.sharpness), multiplier) + +/datum/component/two_handed/proc/on_material_remove(obj/item/source, datum/material/material, amount, multiplier) + SIGNAL_HANDLER + // Same as appliation but inversed + if (wielded) + force_unwielded /= GET_MATERIAL_MODIFIER(source.get_material_force_modifier(material, source.sharpness), multiplier) + else + force_wielded /= GET_MATERIAL_MODIFIER(source.get_material_force_modifier(material, source.sharpness), multiplier) + /** * The offhand dummy item for two handed items */ diff --git a/code/datums/dash_weapon.dm b/code/datums/dash_weapon.dm index 8a02894bc1e..c55ce0be79b 100644 --- a/code/datums/dash_weapon.dm +++ b/code/datums/dash_weapon.dm @@ -68,12 +68,14 @@ current_charges-- addtimer(CALLBACK(src, PROC_REF(charge)), charge_rate) owner?.update_mob_action_buttons() + SEND_SIGNAL(src, COMSIG_DASH_ACTION_DASHED) return TRUE /// Callback for [/proc/teleport] to increment our charges after use. /datum/action/innate/dash/proc/charge() current_charges = clamp(current_charges + 1, 0, max_charges) + SEND_SIGNAL(src, COMSIG_DASH_ACTION_CHARGED) var/obj/item/dashing_item = target if(!istype(dashing_item)) diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index 55d8e28b197..3d7fff25706 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -60,6 +60,9 @@ GLOBAL_LIST_INIT(vv_var_blacklist, list( return FALSE if(href_list[VV_HK_MODIFY_TRAITS]) usr.client.holder.modify_traits(src) + if(href_list[VV_HK_DEBUG_APPEARANCE]) // On base datum as it is shared by atoms and mutable_appearance/image VVs + usr.client.holder.appearance_debug.set_target(src) + usr.client.holder.appearance_debug.ui_interact(usr) return TRUE /datum/proc/vv_get_header() diff --git a/code/datums/diseases/_disease.dm b/code/datums/diseases/_disease.dm index 1dab6b40aea..4754ac1594c 100644 --- a/code/datums/diseases/_disease.dm +++ b/code/datums/diseases/_disease.dm @@ -113,6 +113,7 @@ /datum/disease/proc/register_disease_signals() if(isnull(affected_mob)) return + RegisterSignal(affected_mob, COMSIG_LIVING_LIFE, PROC_REF(on_life)) if(spread_flags & DISEASE_SPREAD_AIRBORNE) RegisterSignal(affected_mob, COMSIG_CARBON_PRE_BREATHE, PROC_REF(on_breath)) @@ -120,12 +121,21 @@ /datum/disease/proc/unregister_disease_signals() if(isnull(affected_mob)) return - UnregisterSignal(affected_mob, COMSIG_CARBON_PRE_BREATHE) + UnregisterSignal(affected_mob, list(COMSIG_LIVING_LIFE, COMSIG_CARBON_PRE_BREATHE)) // Proc to determine if the virus can resist natural recovery /datum/disease/proc/get_recovery_failure_chance() return 0 +/datum/disease/proc/on_life(datum/source, seconds_per_tick) + SIGNAL_HANDLER + PRIVATE_PROC(TRUE) + + if(HAS_TRAIT(affected_mob, TRAIT_STASIS) || QDELETED(src) || (affected_mob.stat == DEAD && !process_dead)) + return + + stage_act(seconds_per_tick) + ///Proc to process the disease and decide on whether to advance, cure or make the symptoms appear. Returns a boolean on whether to continue acting on the symptoms or not. /datum/disease/proc/stage_act(seconds_per_tick) var/slowdown = HAS_TRAIT(affected_mob, TRAIT_VIRUS_RESISTANCE) ? 0.5 : 1 // spaceacillin slows stage speed by 50% @@ -165,9 +175,11 @@ // if(!(disease_flags & CHRONIC) && disease_flags & CURABLE && bypasses_immunity != TRUE) if(!(disease_flags & CHRONIC) && disease_flags & CURABLE && bypasses_immunity != TRUE && bypasses_disease_recovery != TRUE) // BUBBER EDIT CHANGE - DISEASE OUTBREAK UPDATES switch(severity) - if(DISEASE_SEVERITY_POSITIVE) //good viruses don't go anywhere after hitting max stage - you can try to get rid of them by sleeping earlier - cycles_to_beat = max(DISEASE_RECOVERY_SCALING, DISEASE_CYCLES_POSITIVE) //because of the way we later check for recovery_prob, we need to floor this at least equal to the scaling to avoid infinitely getting less likely to cure - if(((HAS_TRAIT(affected_mob, TRAIT_NOHUNGER)) || ((affected_mob.nutrition > NUTRITION_LEVEL_STARVING) && (affected_mob.satiety >= 0))) && slowdown == 1) //any sort of malnourishment/immunosuppressant opens you to losing a good virus + if(DISEASE_SEVERITY_POSITIVE) + if(slowdown < 1 || (!(HAS_TRAIT(affected_mob, TRAIT_NOHUNGER)) && (affected_mob.satiety < DISEASE_SATIETY_THRESHOLD || affected_mob.nutrition < NUTRITION_LEVEL_STARVING))) + cycles_to_beat = max(DISEASE_RECOVERY_SCALING, DISEASE_CYCLES_POSITIVE) + else + recovery_prob = 0 return TRUE if(DISEASE_SEVERITY_NONTHREAT) cycles_to_beat = max(DISEASE_RECOVERY_SCALING, DISEASE_CYCLES_NONTHREAT) @@ -187,14 +199,14 @@ recovery_prob += DISEASE_RECOVERY_CONSTANT + (peaked_cycles / (cycles_to_beat / DISEASE_RECOVERY_SCALING)) //more severe viruses are beaten back more aggressively after the peak if(stage_peaked) recovery_prob *= DISEASE_PEAKED_RECOVERY_MULTIPLIER - if(slowdown != 1) //using spaceacillin can help get them over the finish line to kill a virus with decreasing effect over time + if(slowdown < 1) //using spaceacillin can help get them over the finish line to kill a virus with decreasing effect over time recovery_prob += clamp((((1 - slowdown)*(DISEASE_SLOWDOWN_RECOVERY_BONUS * 2)) * ((DISEASE_SLOWDOWN_RECOVERY_BONUS_DURATION - chemical_offsets) / DISEASE_SLOWDOWN_RECOVERY_BONUS_DURATION)), 0, DISEASE_SLOWDOWN_RECOVERY_BONUS) chemical_offsets = min(chemical_offsets + 1, DISEASE_SLOWDOWN_RECOVERY_BONUS_DURATION) if(!HAS_TRAIT(affected_mob, TRAIT_NOHUNGER)) - if(affected_mob.satiety < 0 || affected_mob.nutrition < NUTRITION_LEVEL_STARVING) //being malnourished makes it a lot harder to defeat your illness + if(affected_mob.satiety < DISEASE_SATIETY_THRESHOLD || affected_mob.nutrition < NUTRITION_LEVEL_STARVING) //being malnourished makes it a lot harder to defeat your illness recovery_prob -= DISEASE_MALNUTRITION_RECOVERY_PENALTY else - if(affected_mob.satiety >= 0) + if(affected_mob.satiety > 0) recovery_prob += round((DISEASE_SATIETY_RECOVERY_MULTIPLIER * (affected_mob.satiety/MAX_SATIETY)), 0.1) if(affected_mob.mob_mood) // this and most other modifiers below a shameless rip from sleeping healing buffs, but feeling good helps make it go away quicker @@ -245,7 +257,7 @@ var/failure_chance = (1 - get_recovery_failure_chance() / 100) if(SPT_PROB(recovery_prob * failure_chance, seconds_per_tick)) if(stage == 1 && prob(cure_chance * DISEASE_FINAL_CURE_CHANCE_MULTIPLIER)) //if we reduce FROM stage == 1, cure the virus - after defeating its cure_chance in a final battle - if(!HAS_TRAIT(affected_mob, TRAIT_NOHUNGER) && (affected_mob.satiety < 0 || affected_mob.nutrition < NUTRITION_LEVEL_STARVING)) + if(!HAS_TRAIT(affected_mob, TRAIT_NOHUNGER) && (affected_mob.satiety < DISEASE_SATIETY_THRESHOLD || affected_mob.nutrition < NUTRITION_LEVEL_STARVING)) if(stage_peaked == FALSE) //if you didn't ride out the virus from its peak, if you're malnourished when it cures, you don't get resistance cure(add_resistance = FALSE) return FALSE diff --git a/code/datums/diseases/floor_diseases/gastritium.dm b/code/datums/diseases/floor_diseases/gastritium.dm index 228cfa7496a..e8755511147 100644 --- a/code/datums/diseases/floor_diseases/gastritium.dm +++ b/code/datums/diseases/floor_diseases/gastritium.dm @@ -44,11 +44,10 @@ /datum/disease/gastritium/proc/tritium_burp(hot_chance = FALSE) var/datum/gas_mixture/burp = new - ADD_GAS(/datum/gas/tritium, burp.gases) - burp.gases[/datum/gas/tritium][MOLES] = MOLES_GAS_VISIBLE + burp.set_gas(/datum/gas/tritium, MOLES_GAS_VISIBLE) burp.temperature = affected_mob.bodytemperature if(hot_chance && prob(tritium_burp_hot_chance)) - burp.temperature = TRITIUM_MINIMUM_BURN_TEMPERATURE + burp.set_temperature(TRITIUM_MINIMUM_BURN_TEMPERATURE) if(affected_mob.stat == CONSCIOUS) to_chat(affected_mob, span_warning("Your throat feels hot!")) affected_mob.visible_message("burps out green gas.", visible_message_flags = EMOTE_MESSAGE) diff --git a/code/datums/diseases/gbs.dm b/code/datums/diseases/gbs.dm index c5e0e760e94..2eba4bdb961 100644 --- a/code/datums/diseases/gbs.dm +++ b/code/datums/diseases/gbs.dm @@ -34,3 +34,9 @@ affected_mob.investigate_log("has been gibbed by GBS.", INVESTIGATE_DEATHS) affected_mob.gib(DROP_ALL_REMAINS) return FALSE + +/datum/disease/gbs/no_transmission + name = "Non-Transmissible GBS" + spread_text = "Skin contact" + spread_flags = DISEASE_SPREAD_NON_CONTAGIOUS + spreading_modifier = 0 diff --git a/code/datums/diseases/verminous_plague.dm b/code/datums/diseases/verminous_plague.dm new file mode 100644 index 00000000000..8e56f7fcc08 --- /dev/null +++ b/code/datums/diseases/verminous_plague.dm @@ -0,0 +1,76 @@ +GLOBAL_LIST_INIT(cursed_vermin_by_stage, list( + "1" = list( // Mostly harmless + /mob/living/basic/butterfly = 1, + /mob/living/basic/cockroach = 4, + /mob/living/basic/cockroach/bloodroach = 1, + /mob/living/basic/frog = 2, + /mob/living/basic/mouse = 2, + /mob/living/basic/snail = 2, + /mob/living/basic/spider/maintenance = 1, + ), + "2" = list( // Deal damage but not that dangerous + /mob/living/basic/cockroach/bloodroach = 1, + /mob/living/basic/cockroach/sewer = 1, + /mob/living/basic/bee = 4, + /mob/living/basic/frog = 3, + /mob/living/basic/frog/crazy = 2, + /mob/living/basic/mouse/rat = 4, + /mob/living/basic/snail/angry = 2, + ), + "3" = list( // More annoying + /mob/living/basic/bee/toxin = 4, + /mob/living/basic/cockroach/hauberoach = 3, + /mob/living/basic/frog/crazy = 3, + /mob/living/basic/mouse/rat = 3, + /mob/living/basic/spider/growing/spiderling/hunter = 1, + ), +)) + +/// Makes you cough out rats, bugs, etc +/datum/disease/verminous_plague + name = "Verminous Plague" + desc = "You can't stop germinating small animals." + form = "Affliction" + agent = "Wizard's Curse" + cure_text = "Exorcism" + viable_mobtypes = list(/mob/living/carbon/human) + cures = list(/datum/reagent/consumable/salt, /datum/reagent/water/holywater) + spread_flags = DISEASE_SPREAD_CONTACT_SKIN + severity = DISEASE_SEVERITY_MEDIUM + max_stages = 3 + stage_prob = 2 + needs_all_cures = FALSE + /// Chance to spawn something + var/spawn_chance = 5 + +/datum/disease/verminous_plague/stage_act(seconds_per_tick) + . = ..() + if (SPT_PROB(spawn_chance, seconds_per_tick)) + spawn_mob() + +/// Creates a pest +/datum/disease/verminous_plague/proc/spawn_mob() + var/creating_type = pick_weight(GLOB.cursed_vermin_by_stage["[stage]"]) + var/mob/living/created = new creating_type(affected_mob.drop_location()) + if (QDELETED(created)) + return + + var/obj/item/organ/lungs = affected_mob.get_organ_slot(ORGAN_SLOT_LUNGS) + if (lungs && affected_mob.emote("cough")) + affected_mob.visible_message(span_warning("[affected_mob] coughs out [created]!")) + lungs.apply_organ_damage(stage * 2) + else + affected_mob.vomit(VOMIT_CATEGORY_BLOOD_STUNLESS | MOB_VOMIT_FORCE) + affected_mob.visible_message(span_warning("[affected_mob] vomits out [created]!")) + + if (stage == 1 || !created.ai_controller) + return + + created.ai_controller.set_blackboard_key(BB_BASIC_MOB_CURRENT_TARGET, affected_mob) + created.ai_controller.insert_blackboard_key_lazylist(BB_BASIC_MOB_RETALIATE_LIST, affected_mob) + +/datum/disease/verminous_plague/update_stage(new_stage) + var/was_stage = stage + . = ..() + if (new_stage > was_stage) + spawn_mob() diff --git a/code/datums/dna/dna.dm b/code/datums/dna/dna.dm index 99387228494..2a723a53722 100644 --- a/code/datums/dna/dna.dm +++ b/code/datums/dna/dna.dm @@ -4,7 +4,7 @@ */ GLOBAL_LIST_INIT(total_ui_len_by_block, populate_total_ui_len_by_block()) -GLOBAL_LIST_INIT(standard_mutation_sources, list(MUTATION_SOURCE_ACTIVATED, MUTATION_SOURCE_MUTATOR, MUTATION_SOURCE_TIMED_INJECTOR)) +GLOBAL_LIST_INIT(standard_mutation_sources, list(MUTATION_SOURCE_ACTIVATED, MUTATION_SOURCE_MUTATOR)) /proc/populate_total_ui_len_by_block() . = list() @@ -89,21 +89,21 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) new_dna.unique_features = unique_features new_dna.features = features.Copy() new_dna.real_name = real_name + //BUBBER EDIT ADDITION BEGIN - CUSTOMIZATION + new_dna.mutant_bodyparts = LAZYCOPY(mutant_bodyparts) + new_dna.body_markings = body_markings.Copy() + new_dna.update_body_size() + //BUBBER EDIT ADDITION END new_dna.temporary_mutations = LAZYLISTDUPLICATE(temporary_mutations) new_dna.mutation_index = mutation_index new_dna.default_mutation_genes = default_mutation_genes - // BUBBER EDIT ADDITION BEGIN - CUSTOMIZATION - new_dna.mutant_bodyparts = mutant_bodyparts.Copy() - new_dna.body_markings = body_markings.Copy() - new_dna.update_body_size() - // BUBBER EDIT ADDITION END //if the new DNA has a holder, transform them immediately, otherwise save it if(new_dna.holder) if (iscarbon(new_dna.holder)) var/mob/living/carbon/as_carbon = new_dna.holder as_carbon.set_blood_type(blood_type) - if(transfer_flags & COPY_DNA_SPECIES) - new_dna.holder.set_species(species.type, icon_update = FALSE) + if(transfer_flags & COPY_DNA_SPECIES) + as_carbon.set_species(species.type, icon_update = 0, pref_load = FALSE, override_features = features.Copy(), override_mutantparts = LAZYCOPY(mutant_bodyparts), override_markings = body_markings.Copy()) else new_dna.blood_type = blood_type if(transfer_flags & COPY_DNA_SPECIES) @@ -160,7 +160,7 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) var/datum/mutation/actual_mutation = get_mutation(mutation_to_remove) if(!actual_mutation || !(sources & actual_mutation.sources)) - return + return FALSE actual_mutation.sources -= sources @@ -174,6 +174,7 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) qdel(actual_mutation) update_instability(FALSE) + return TRUE /datum/dna/proc/check_mutation(mutation_type) return get_mutation(mutation_type) @@ -653,7 +654,7 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) return var/datum/mutation/mutation = dna.get_mutation(mutation_path) if(mutation) - mutation.scrambled = TRUE + mutation.scrambled = FALSE //set to FALSE to allow easy_random_mutate obtained genes to be saved in DNA consoles /mob/living/carbon/proc/random_mutate_unique_identity() if(!has_dna()) diff --git a/code/datums/drift_handler.dm b/code/datums/drift_handler.dm index 9eef89f7ee5..1d4bee6708a 100644 --- a/code/datums/drift_handler.dm +++ b/code/datums/drift_handler.dm @@ -223,4 +223,4 @@ return COMSIG_MOB_CLIENT_BLOCK_PRE_MOVE /datum/drift_handler/proc/get_loop_delay(atom/movable/movable) - return (DEFAULT_INERTIA_SPEED / ((1 - INERTIA_SPEED_COEF) + drift_force * INERTIA_SPEED_COEF)) * movable.inertia_move_multiplier + return (DEFAULT_INERTIA_SPEED / ((1 - INERTIA_SPEED_COEF) + drift_force * INERTIA_SPEED_COEF)) * min(movable.inertia_move_multiplier_passive, movable.inertia_move_multiplier_active) diff --git a/code/datums/elements/ai_retaliate.dm b/code/datums/elements/ai_retaliate.dm index 03465d3c246..4fcb5158143 100644 --- a/code/datums/elements/ai_retaliate.dm +++ b/code/datums/elements/ai_retaliate.dm @@ -24,4 +24,4 @@ if (victim == attacker) return - victim.ai_controller?.insert_blackboard_key_lazylist(BB_BASIC_MOB_RETALIATE_LIST, attacker) + victim.ai_controller?.set_blackboard_key_assoc_lazylist(BB_BASIC_MOB_RETALIATE_LIST, attacker, world.time) diff --git a/code/datums/elements/bane.dm b/code/datums/elements/bane.dm deleted file mode 100644 index 002aefc6a36..00000000000 --- a/code/datums/elements/bane.dm +++ /dev/null @@ -1,98 +0,0 @@ -/// Deals extra damage to mobs of a certain type, species, or biotype. -/// This doesn't directly modify the normal damage of the weapon, instead it applies its own damage separately ON TOP of normal damage -/// ie. a sword that does 10 damage with a bane element attached that has a 0.5 damage_multiplier will do: -/// 10 damage from the swords normal attack + 5 damage (50%) from the bane element -/datum/element/bane - element_flags = ELEMENT_BESPOKE - argument_hash_start_idx = 2 - /// can be a mob or a species. - var/target_type - /// multiplier of the extra damage based on the force of the item. - var/damage_multiplier - /// Added after the above. - var/added_damage - /// If it requires combat mode on to deal the extra damage or not. - var/requires_combat_mode - /// if we want it to only affect a certain mob biotype - var/mob_biotypes - var/bane_damage_override // BUBBER EDIT ADDITION - -/datum/element/bane/Attach(datum/target, target_type = /mob/living, mob_biotypes = NONE, damage_multiplier=1, added_damage = 0, requires_combat_mode = TRUE, bane_damage_override) // BUBBER EDIT ADDITION - added bane_damage_override arg - . = ..() - - if(!ispath(target_type, /mob/living) && !ispath(target_type, /datum/species)) - return ELEMENT_INCOMPATIBLE - - src.target_type = target_type - src.damage_multiplier = damage_multiplier - src.added_damage = added_damage - src.requires_combat_mode = requires_combat_mode - src.mob_biotypes = mob_biotypes - src.bane_damage_override = bane_damage_override // BUBBER EDIT ADDITION - target.AddElementTrait(TRAIT_ON_HIT_EFFECT, REF(src), /datum/element/on_hit_effect) - RegisterSignal(target, COMSIG_ON_HIT_EFFECT, PROC_REF(do_bane)) - -/datum/element/bane/Detach(datum/source) - UnregisterSignal(source, COMSIG_ON_HIT_EFFECT) - REMOVE_TRAIT(source, TRAIT_ON_HIT_EFFECT, REF(src)) - return ..() - -/datum/element/bane/proc/do_bane(datum/element_owner, mob/living/bane_applier, mob/living/baned_target, hit_zone, throw_hit) - if(!check_biotype_path(bane_applier, baned_target)) - return - if(SEND_SIGNAL(element_owner, COMSIG_OBJECT_PRE_BANING, baned_target) & COMPONENT_CANCEL_BANING) - return - - var/force_boosted - var/applied_dam_type - - if(isitem(element_owner)) - var/obj/item/item_owner = element_owner - force_boosted = item_owner.force - applied_dam_type = item_owner.damtype - else if(isprojectile(element_owner)) - var/obj/projectile/projectile_owner = element_owner - force_boosted = projectile_owner.damage - applied_dam_type = projectile_owner.damage_type - else if (isliving(element_owner)) - var/mob/living/living_owner = element_owner - force_boosted = (living_owner.melee_damage_lower + living_owner.melee_damage_upper) / 2 - //commence crying. yes, these really are the same check. FUCK. - if(isbasicmob(living_owner)) - var/mob/living/basic/basic_owner = living_owner - applied_dam_type = basic_owner.melee_damage_type - else if(isanimal(living_owner)) - var/mob/living/simple_animal/simple_owner = living_owner - applied_dam_type = simple_owner.melee_damage_type - else - return - else - return - // BUBBER EDIT ADDITION BEGIN - allows for silver wpns to burn lycans - if (bane_damage_override) - applied_dam_type = bane_damage_override - // BUBBER EDIT ADDITION END - var/extra_damage = max(0, (force_boosted * damage_multiplier) + added_damage) - baned_target.apply_damage(extra_damage, applied_dam_type, hit_zone) - SEND_SIGNAL(baned_target, COMSIG_LIVING_BANED, bane_applier, baned_target) // for extra effects when baned. - SEND_SIGNAL(element_owner, COMSIG_OBJECT_ON_BANING, baned_target) - -/** - * Checks typepaths and the mob's biotype, returning TRUE if correct and FALSE if wrong. - * Additionally checks if combat mode is required, and if so whether it's enabled or not. - */ -/datum/element/bane/proc/check_biotype_path(atom/bane_applier, atom/target) - if(!isliving(target)) - return FALSE - var/mob/living/living_target = target - if(isliving(bane_applier) && bane_applier) - var/mob/living/living_bane_applier = bane_applier - if(requires_combat_mode && !living_bane_applier.combat_mode) - return FALSE - var/is_correct_biotype = living_target.mob_biotypes & mob_biotypes - if(mob_biotypes && !(is_correct_biotype)) - return FALSE - if(ispath(target_type, /mob/living)) - return istype(living_target, target_type) - else //species type - return is_species(living_target, target_type) diff --git a/code/datums/elements/block_area_power_fail.dm b/code/datums/elements/block_area_power_fail.dm new file mode 100644 index 00000000000..8de9ed24118 --- /dev/null +++ b/code/datums/elements/block_area_power_fail.dm @@ -0,0 +1,67 @@ +// Used to differentiate what is protecting an area +#define AREA_TRAIT_SOURCE(the_source) "[type]_[the_source.type]" +#define MOVABLE_TRAIT_SOURCE(the_source) "[type]_[REF(the_source)]" +#define TURF_TRAIT_SOURCE(the_source) "[type]_[the_source.x]-[the_source.y]-[the_source.z]" + +/** + * ## block_area_power_fail + * + * Element that interacts with the grid check event (and similar effects) to protect certain rooms + * + * * Attach to an area to prevent arbitrary power outages from affecting it + * * Attach to a movable to prevent arbitrary power outages from affecting the area it's in + * * Attach to a turf to prevent arbitrary power outages from affecting its area + */ +/datum/element/block_area_power_fail + element_flags = ELEMENT_DETACH_ON_HOST_DESTROY + +/datum/element/block_area_power_fail/Attach(datum/target) + . = ..() + if(isarea(target)) // practically just a complicated way to do add trait + ADD_TRAIT(target, TRAIT_AREA_BLOCK_POWER_FAIL, AREA_TRAIT_SOURCE(target)) + + else if(ismovable(target)) // manages adding and removing the trait as the movable moves + var/atom/movable/movable_target = target + movable_target.become_area_sensitive(type) + RegisterSignal(target, COMSIG_ENTER_AREA, PROC_REF(on_movable_entered_area)) + RegisterSignal(target, COMSIG_EXIT_AREA, PROC_REF(on_movable_exited_area)) + on_movable_entered_area(target, get_area(movable_target)) + + else if(isturf(target)) // turfs don't move so it just adds the trait to the turf's area + var/turf/turf_target = target + ADD_TRAIT(turf_target.loc, TRAIT_AREA_BLOCK_POWER_FAIL, TURF_TRAIT_SOURCE(turf_target)) + + else + return ELEMENT_INCOMPATIBLE + +/datum/element/block_area_power_fail/Detach(datum/source) + . = ..() + if(isarea(source)) + REMOVE_TRAIT(source, TRAIT_AREA_BLOCK_POWER_FAIL, AREA_TRAIT_SOURCE(source)) + + else if(ismovable(source)) + var/atom/movable/movable_source = source + movable_source.lose_area_sensitivity(type) + UnregisterSignal(source, COMSIG_ENTER_AREA) + UnregisterSignal(source, COMSIG_EXIT_AREA) + on_movable_exited_area(source, get_area(movable_source)) + + else if(isturf(source)) + var/turf/turf_source = source + REMOVE_TRAIT(turf_source.loc, TRAIT_AREA_BLOCK_POWER_FAIL, TURF_TRAIT_SOURCE(turf_source)) + +/datum/element/block_area_power_fail/proc/on_movable_entered_area(atom/movable/source, area/new_area) + SIGNAL_HANDLER + + if(new_area) + ADD_TRAIT(new_area, TRAIT_AREA_BLOCK_POWER_FAIL, MOVABLE_TRAIT_SOURCE(source)) + +/datum/element/block_area_power_fail/proc/on_movable_exited_area(atom/movable/source, area/old_area) + SIGNAL_HANDLER + + if(old_area) + REMOVE_TRAIT(old_area, TRAIT_AREA_BLOCK_POWER_FAIL, MOVABLE_TRAIT_SOURCE(source)) + +#undef AREA_TRAIT_SOURCE +#undef MOVABLE_TRAIT_SOURCE +#undef TURF_TRAIT_SOURCE diff --git a/code/datums/elements/cuffable_item.dm b/code/datums/elements/cuffable_item.dm index b81068d2361..6939681099c 100644 --- a/code/datums/elements/cuffable_item.dm +++ b/code/datums/elements/cuffable_item.dm @@ -47,13 +47,24 @@ if(cuffs.used || DOING_INTERACTION_WITH_TARGET(user, source)) return - if(HAS_TRAIT_FROM(source, TRAIT_NODROP, CUFFED_ITEM_TRAIT)) - to_chat(user, span_warning("[source] is already cuffed to your wrist!")) + for(var/datum/status_effect/cuffed_item/effect in user.status_effects) + if(effect.cuffed == source) + to_chat(user, span_warning("[source] is already cuffed to your wrist!")) + return + if(effect.cuffed_to == user.get_inactive_hand()) + to_chat(user, span_warning("You already have something cuffed to your opposite wrist!")) + return + + if(!user.get_inactive_hand()) + to_chat(user, span_warning("You don't have another hand to cuff [source] to!")) return if(cuffs.handcuffs_clumsiness_check(user)) return + if(SEND_SIGNAL(source, COMSIG_ITEM_PRE_CUFFED_TO_MOB, user, cuffs) & BLOCK_ITEM_CUFF) + return + source.balloon_alert(user, "cuffing item...") playsound(source, cuffs.cuffsound, 30, TRUE, -2) if(!do_after(user, cuffs.get_handcuff_time(user), source)) diff --git a/code/datums/elements/cult_eyes.dm b/code/datums/elements/cult_eyes.dm index 68d70a47092..6e95d9b1bca 100644 --- a/code/datums/elements/cult_eyes.dm +++ b/code/datums/elements/cult_eyes.dm @@ -30,7 +30,7 @@ return var/mob/living/carbon/human/human_parent = target human_parent.add_eye_color(BLOODCULT_EYE, EYE_COLOR_CULT_PRIORITY) - human_parent.update_body() + human_parent.update_eyes() /** * Detach proc @@ -42,6 +42,6 @@ if (ishuman(target)) var/mob/living/carbon/human/human_parent = target human_parent.remove_eye_color(EYE_COLOR_CULT_PRIORITY) - human_parent.update_body() + human_parent.update_eyes() UnregisterSignal(target, list(COMSIG_CHANGELING_TRANSFORM, COMSIG_HUMAN_MONKEYIZE, COMSIG_MONKEY_HUMANIZE)) return ..() diff --git a/code/datums/elements/death_gases.dm b/code/datums/elements/death_gases.dm index b93c870f817..7589e719415 100644 --- a/code/datums/elements/death_gases.dm +++ b/code/datums/elements/death_gases.dm @@ -30,7 +30,7 @@ SIGNAL_HANDLER var/datum/gas_mixture/mix_to_spawn = new() mix_to_spawn.add_gas(gas_type) - mix_to_spawn.gases[gas_type][MOLES] = amount_of_gas - mix_to_spawn.temperature = T20C + mix_to_spawn.set_gas(gas_type, amount_of_gas) + mix_to_spawn.set_temperature(T20C) var/turf/open/our_turf = get_turf(target) our_turf.assume_air(mix_to_spawn) diff --git a/code/datums/elements/kill_achievement.dm b/code/datums/elements/kill_achievement.dm index ccd2e827c50..6ec8854d0f7 100644 --- a/code/datums/elements/kill_achievement.dm +++ b/code/datums/elements/kill_achievement.dm @@ -9,7 +9,7 @@ /// A memory to grant to killers, if any var/kill_memory_type = null /// Range in which to grant the achievement - var/achievement_range = 7 + var/achievement_range = 12 /// Threshold for damage dealt with a crusher to count it as a crusher kill /// If null, then no kill counts as a crusher kill var/crusher_kill_threshold = 0.6 diff --git a/code/datums/elements/loomable.dm b/code/datums/elements/loomable.dm index 46704429ee9..942c6cf75a0 100644 --- a/code/datums/elements/loomable.dm +++ b/code/datums/elements/loomable.dm @@ -104,7 +104,7 @@ if (ispath(resulting_atom, /obj/item/stack)) var/obj/item/stack/stack_type = resulting_atom while (spawning_amount > 0) - new_thing = new resulting_atom(target.drop_location(), new_amount = min(spawning_amount, stack_type::max_amount)) + new_thing = new resulting_atom(target.drop_location(), min(spawning_amount, stack_type::max_amount)) spawning_amount -= stack_type::max_amount else for(var/repeated in 1 to spawning_amount) diff --git a/code/datums/elements/moving_randomly.dm b/code/datums/elements/moving_randomly.dm new file mode 100644 index 00000000000..5677ab2c7b9 --- /dev/null +++ b/code/datums/elements/moving_randomly.dm @@ -0,0 +1,26 @@ +/// Just move something around in the simplest way possible +/datum/element/moving_randomly + element_flags = ELEMENT_DETACH_ON_HOST_DESTROY + + /// Movables that we are moving around + var/list/movers = list() + +/datum/element/moving_randomly/Attach(datum/target) + . = ..() + + if(!ismovable(target)) + return ELEMENT_INCOMPATIBLE + + movers += target + +/datum/element/moving_randomly/Detach(datum/source, ...) + . = ..() + + movers -= source + +/datum/element/moving_randomly/New() + START_PROCESSING(SSdcs, src) + +/datum/element/moving_randomly/process(seconds_per_tick) + for(var/atom/movable/mover as anything in movers) + mover.Move(get_step(mover, pick(GLOB.alldirs))) diff --git a/code/datums/elements/nullrod_core.dm b/code/datums/elements/nullrod_core.dm index fa48e421f8e..6b4a309ba35 100644 --- a/code/datums/elements/nullrod_core.dm +++ b/code/datums/elements/nullrod_core.dm @@ -19,7 +19,7 @@ effects_we_clear = list(/obj/effect/rune, /obj/effect/heretic_rune, /obj/effect/cosmic_rune), \ ) target.AddComponent(/datum/component/cult_kill_tracker) - target.AddElement(/datum/element/bane, mob_biotypes = MOB_SPIRIT, damage_multiplier = 0, added_damage = 25, requires_combat_mode = FALSE) + target.AddComponent(/datum/component/bane, affected_biotypes = MOB_SPIRIT, added_damage = 25) ADD_TRAIT(target, TRAIT_NULLROD_ITEM, ELEMENT_TRAIT(type)) if(!PERFORM_ALL_TESTS(focus_only/nullrod_variants) || !chaplain_spawnable) diff --git a/code/datums/elements/relay_attackers.dm b/code/datums/elements/relay_attackers.dm index 6dd9e8dfd47..b5bae4f80b7 100644 --- a/code/datums/elements/relay_attackers.dm +++ b/code/datums/elements/relay_attackers.dm @@ -37,25 +37,25 @@ /datum/element/relay_attackers/proc/after_attackby(atom/target, obj/item/weapon, mob/attacker, list/modifiers) SIGNAL_HANDLER if(weapon.force) - relay_attacker(target, attacker, weapon.damtype == STAMINA ? ATTACKER_STAMINA_ATTACK : ATTACKER_DAMAGING_ATTACK) + relay_attacker(target, attacker, weapon.damtype == STAMINA ? ATTACKER_STAMINA_ATTACK : ATTACKER_DAMAGING_ATTACK, get_dir(target, attacker)) /datum/element/relay_attackers/proc/on_attack_generic(atom/target, mob/living/attacker, list/modifiers) SIGNAL_HANDLER // Check for a shove. if(LAZYACCESS(modifiers, RIGHT_CLICK)) - relay_attacker(target, attacker, ATTACKER_SHOVING) + relay_attacker(target, attacker, ATTACKER_SHOVING, get_dir(target, attacker)) return // Else check for combat mode. if(attacker.combat_mode) - relay_attacker(target, attacker, ATTACKER_DAMAGING_ATTACK) + relay_attacker(target, attacker, ATTACKER_DAMAGING_ATTACK, get_dir(target, attacker)) return /datum/element/relay_attackers/proc/on_attack_npc(atom/target, mob/living/attacker) SIGNAL_HANDLER if(attacker.melee_damage_upper > 0) - relay_attacker(target, attacker, ATTACKER_DAMAGING_ATTACK) + relay_attacker(target, attacker, ATTACKER_DAMAGING_ATTACK, get_dir(target, attacker)) /// Even if another component blocked this hit, someone still shot at us /datum/element/relay_attackers/proc/on_bullet_act(atom/target, obj/projectile/hit_projectile) @@ -64,7 +64,7 @@ return if(!ismob(hit_projectile.firer)) return - relay_attacker(target, hit_projectile.firer, hit_projectile.damage_type == STAMINA ? ATTACKER_STAMINA_ATTACK : ATTACKER_DAMAGING_ATTACK) + relay_attacker(target, hit_projectile.firer, ATTACK_RANGED | hit_projectile.damage_type == STAMINA ? ATTACKER_STAMINA_ATTACK : ATTACKER_DAMAGING_ATTACK, get_dir(target, hit_projectile)) /// Even if another component blocked this hit, someone still threw something /datum/element/relay_attackers/proc/on_hitby(atom/target, atom/movable/hit_atom, datum/thrownthing/throwingdatum) @@ -77,16 +77,16 @@ var/atom/thrown_by = throwingdatum?.get_thrower() if(!istype(thrown_by)) return - relay_attacker(target, thrown_by, hit_item.damtype == STAMINA ? ATTACKER_STAMINA_ATTACK : ATTACKER_DAMAGING_ATTACK) + relay_attacker(target, thrown_by, ATTACK_RANGED | hit_item.damtype == STAMINA ? ATTACKER_STAMINA_ATTACK : ATTACKER_DAMAGING_ATTACK, get_dir(target, hit_atom)) /datum/element/relay_attackers/proc/on_attack_hulk(atom/target, mob/attacker) SIGNAL_HANDLER - relay_attacker(target, attacker, ATTACKER_DAMAGING_ATTACK) + relay_attacker(target, attacker, ATTACKER_DAMAGING_ATTACK, get_dir(target, attacker)) /datum/element/relay_attackers/proc/on_attack_mech(atom/target, obj/vehicle/sealed/mecha/mecha_attacker, mob/living/pilot, mecha_attack_cooldown) SIGNAL_HANDLER - relay_attacker(target, mecha_attacker, ATTACKER_DAMAGING_ATTACK) + relay_attacker(target, mecha_attacker, ATTACKER_DAMAGING_ATTACK, get_dir(target, mecha_attacker)) /// Send out a signal identifying whoever just attacked us (usually a mob but sometimes a mech or turret) -/datum/element/relay_attackers/proc/relay_attacker(atom/victim, atom/attacker, attack_flags) - SEND_SIGNAL(victim, COMSIG_ATOM_WAS_ATTACKED, attacker, attack_flags) +/datum/element/relay_attackers/proc/relay_attacker(atom/victim, atom/attacker, attack_flags, direction) + SEND_SIGNAL(victim, COMSIG_ATOM_WAS_ATTACKED, attacker, attack_flags, direction) diff --git a/code/datums/elements/tool_blocker.dm b/code/datums/elements/tool_blocker.dm index e7fdefd6c87..f1ce1f4fa4a 100644 --- a/code/datums/elements/tool_blocker.dm +++ b/code/datums/elements/tool_blocker.dm @@ -2,23 +2,47 @@ /datum/element/tool_blocker element_flags = ELEMENT_BESPOKE argument_hash_start_idx = 2 + /// e.g. TOOL_SCREWDRIVER, TOOL_CROWBAR var/tool_type + /// Bitflag representing which tool_acts to block + var/action_type -/datum/element/tool_blocker/Attach(datum/target, tool_type) +/datum/element/tool_blocker/Attach(datum/target, tool_type, action_type = TOOL_ACT_ALL) . = ..() + if(isnull(tool_type) || !(action_type & TOOL_ACT_ALL)) + return ELEMENT_INCOMPATIBLE + src.tool_type = tool_type - RegisterSignals(target, list( - COMSIG_ATOM_TOOL_ACT(tool_type), - COMSIG_ATOM_SECONDARY_TOOL_ACT(tool_type), - ), PROC_REF(block_tool)) + src.action_type = action_type + + var/list/signals_to_register = list() + + if(action_type & TOOL_ACT_PRIMARY) + signals_to_register += COMSIG_ATOM_TOOL_ACT(tool_type) + if(action_type & TOOL_ACT_SECONDARY) + signals_to_register += COMSIG_ATOM_SECONDARY_TOOL_ACT(tool_type) + if(isturf(target)) + RegisterSignal(target, COMSIG_QDELETING, PROC_REF(on_turf_deleted), override = TRUE) + + RegisterSignals(target, signals_to_register, PROC_REF(block_tool)) /datum/element/tool_blocker/Detach(datum/source, ...) - UnregisterSignal(source, list( - COMSIG_ATOM_TOOL_ACT(tool_type), - COMSIG_ATOM_SECONDARY_TOOL_ACT(tool_type), - )) + var/list/signals_to_unregister = list() + + if(action_type & TOOL_ACT_PRIMARY) + signals_to_unregister += COMSIG_ATOM_TOOL_ACT(tool_type) + if(action_type & TOOL_ACT_SECONDARY) + signals_to_unregister += COMSIG_ATOM_SECONDARY_TOOL_ACT(tool_type) + if(isturf(source)) + signals_to_unregister += COMSIG_QDELETING + UnregisterSignal(source, signals_to_unregister) + return ..() /datum/element/tool_blocker/proc/block_tool(...) SIGNAL_HANDLER return ITEM_INTERACT_SKIP_TO_ATTACK + +/datum/element/tool_blocker/proc/on_turf_deleted(datum/source) + SIGNAL_HANDLER + Detach(source) diff --git a/code/datums/elements/weapon_description.dm b/code/datums/elements/weapon_description.dm index 022318abfcf..23acb72960c 100644 --- a/code/datums/elements/weapon_description.dm +++ b/code/datums/elements/weapon_description.dm @@ -97,6 +97,8 @@ if(attached_proc) readout += call(source, attached_proc)() + SEND_SIGNAL(source, COMSIG_ITEM_WEAPON_LABEL_READOUT, readout) + // Finally bringing the fields together return readout.Join("\n") diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm index 02e133b5718..e8cef1fd5ff 100644 --- a/code/datums/helper_datums/teleport.dm +++ b/code/datums/helper_datums/teleport.dm @@ -28,22 +28,16 @@ switch(channel) if(TELEPORT_CHANNEL_BLUESPACE) - if(istype(teleatom, /obj/item/storage/backpack/holding)) - precision = rand(1,100) - - var/static/list/bag_cache = typecacheof(/obj/item/storage/backpack/holding, /obj/item/mod/control, /obj/item/mod/module/storage) - var/list/bagholding = typecache_filter_list(teleatom.get_all_contents(), bag_cache) - for(var/obj/item/mod/modsuit_or_module in bagholding) - var/datum/storage/storage = modsuit_or_module.atom_storage - if(istype(storage, /datum/storage/bag_of_holding) && storage.real_location == storage.parent) - continue - bagholding -= modsuit_or_module - if(bagholding.len) - precision = max(rand(1,100)*bagholding.len,100) + var/interference = 0 + for(var/obj/item/check as anything in teleatom.get_all_contents_type(/obj/item)) + if(check.item_flags & BLUESPACE_INTERFERENCE) + interference += 1 + if(interference) + precision = max(rand(1,100)*interference,100) if(isliving(teleatom)) var/mob/living/MM = teleatom - to_chat(MM, span_warning("The bluespace interface on your bag of holding interferes with the teleport!")) - + to_chat(MM, span_warning("The clashing pulls of bluespace interfere with your teleport!")) + // if effects are not specified and not explicitly disabled, sparks if((!effectin || !effectout) && !no_effects) var/datum/effect_system/basic/spark_spread/sparks = new(teleatom, 5, TRUE) diff --git a/code/datums/hotkeys_help.dm b/code/datums/hotkeys_help.dm index 0e90c7dffe5..5fe826f3682 100644 --- a/code/datums/hotkeys_help.dm +++ b/code/datums/hotkeys_help.dm @@ -10,6 +10,15 @@ ui = new(user, src, "HotkeysHelp") ui.open() +/datum/hotkeys_help/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + var/mob/user = ui.user + if(action == "open_keybindings") + user.client.prefs.current_window = PREFERENCE_TAB_KEYBINDINGS + user.client.prefs.ui_interact(usr) + user.client.uiclose(ui.window.id) + return TRUE + // Not static data since user could rebind keys. /datum/hotkeys_help/ui_data(mob/user) // List every keybind to chat. diff --git a/code/datums/keybinding/communication.dm b/code/datums/keybinding/communication.dm index 13781d55933..4297f4714b4 100644 --- a/code/datums/keybinding/communication.dm +++ b/code/datums/keybinding/communication.dm @@ -11,8 +11,11 @@ . = ..() if(.) return + if(!user.prefs.read_preference(/datum/preference/toggle/tgui_input)) + winset(user, null, "command=[VERB_SAY]") + return TRUE winset(user, null, "command=[user.tgui_say_create_open_command(SAY_CHANNEL)];") - winset(user, "tgui_say.browser", "focus=true") + winset(user, SKIN_TGUISAY_BROWSER, "focus=true") return TRUE /datum/keybinding/client/communication/radio @@ -26,8 +29,11 @@ . = ..() if(.) return + if(!user.prefs.read_preference(/datum/preference/toggle/tgui_input)) + winset(user, null, "command=[VERB_SAY]") + return TRUE winset(user, null, "command=[user.tgui_say_create_open_command(RADIO_CHANNEL)]") - winset(user, "tgui_say.browser", "focus=true") + winset(user, SKIN_TGUISAY_BROWSER, "focus=true") return TRUE /datum/keybinding/client/communication/ooc @@ -40,8 +46,11 @@ . = ..() if(.) return + if(!user.prefs.read_preference(/datum/preference/toggle/tgui_input)) + winset(user, null, "command=[VERB_OOC]") + return TRUE winset(user, null, "command=[user.tgui_say_create_open_command(OOC_CHANNEL)]") - winset(user, "tgui_say.browser", "focus=true") + winset(user, SKIN_TGUISAY_BROWSER, "focus=true") return TRUE /datum/keybinding/client/communication/me @@ -54,6 +63,27 @@ . = ..() if(.) return + if(!user.prefs.read_preference(/datum/preference/toggle/tgui_input)) + winset(user, null, "command=[VERB_ME]") + return TRUE winset(user, null, "command=[user.tgui_say_create_open_command(ME_CHANNEL)]") + winset(user, SKIN_TGUISAY_BROWSER, "focus=true") + return TRUE + +/datum/keybinding/client/communication/pray + hotkey_keys = list("P") + name = PRAY_CHANNEL + full_name = "Pray" + description = "Allows you to directly send a message to your deity (Admins) in an IC manner." + keybind_signal = COMSIG_KB_CLIENT_PRAY_DOWN + +/datum/keybinding/client/communication/pray/down(client/user, turf/target, mousepos_x, mousepos_y) + . = ..() + if(.) + return + if(!user.prefs.read_preference(/datum/preference/toggle/tgui_input)) + winset(user, null, "command=[VERB_PRAY]") + return TRUE + winset(user, null, "command=[user.tgui_say_create_open_command(PRAY_CHANNEL)];") winset(user, "tgui_say.browser", "focus=true") return TRUE diff --git a/code/datums/keybinding/mob.dm b/code/datums/keybinding/mob.dm index 86bf3ab9933..6d25e6ab2c4 100644 --- a/code/datums/keybinding/mob.dm +++ b/code/datums/keybinding/mob.dm @@ -161,7 +161,7 @@ /datum/keybinding/mob/target/head_cycle hotkey_keys = list("Numpad8") name = "target_head_cycle" - full_name = "Target: Cycle Head" + full_name = "Target: Cycle head" description = "Pressing this key targets the head, and continued presses will cycle to the eyes and mouth. This will impact where you hit people, and can be used for surgery." keybind_signal = COMSIG_KB_MOB_TARGETCYCLEHEAD_DOWN @@ -189,7 +189,7 @@ /datum/keybinding/mob/target/r_arm hotkey_keys = list("Numpad4") name = "target_r_arm" - full_name = "Target: right arm" + full_name = "Target: Right arm" description = "Pressing this key targets the right arm. This will impact where you hit people, and can be used for surgery." keybind_signal = COMSIG_KB_MOB_TARGETRIGHTARM_DOWN @@ -203,7 +203,7 @@ /datum/keybinding/mob/target/left_arm hotkey_keys = list("Numpad6") name = "target_left_arm" - full_name = "Target: left arm" + full_name = "Target: Left arm" description = "Pressing this key targets the body. This will impact where you hit people, and can be used for surgery." keybind_signal = COMSIG_KB_MOB_TARGETLEFTARM_DOWN @@ -224,7 +224,7 @@ /datum/keybinding/mob/target/left_leg hotkey_keys = list("Numpad3") name = "target_left_leg" - full_name = "Target: left leg" + full_name = "Target: Left leg" description = "Pressing this key targets the left leg. This will impact where you hit people, and can be used for surgery." keybind_signal = COMSIG_KB_MOB_TARGETLEFTLEG_DOWN diff --git a/code/datums/lazy_template.dm b/code/datums/lazy_template.dm index 3faefc0cc78..d527d46b6d6 100644 --- a/code/datums/lazy_template.dm +++ b/code/datums/lazy_template.dm @@ -104,6 +104,7 @@ loaded_atom_movables |= thing SSatoms.InitializeAtoms(loaded_areas + loaded_atom_movables + loaded_turfs) + SSlighting.setup_static_lighting_if_needed(loaded_turfs) SSmachines.setup_template_powernets(loaded_cables) SSair.setup_template_machinery(loaded_atmospherics) @@ -111,6 +112,10 @@ reservations += reservation return reservation +/datum/lazy_template/nukie_elevator + key = LAZY_TEMPLATE_KEY_NUKIEELEVATOR + map_name = "nukie_elevator" + /datum/lazy_template/nukie_base key = LAZY_TEMPLATE_KEY_NUKIEBASE map_name = "nukie_base" diff --git a/code/datums/looping_sounds/machinery_sounds.dm b/code/datums/looping_sounds/machinery_sounds.dm index cd9d7fd862d..871a5ca7bf9 100644 --- a/code/datums/looping_sounds/machinery_sounds.dm +++ b/code/datums/looping_sounds/machinery_sounds.dm @@ -161,10 +161,10 @@ /datum/looping_sound/firealarm mid_sounds = list( - 'sound/machines/fire_alarm/FireAlarm1.ogg', - 'sound/machines/fire_alarm/FireAlarm2.ogg', - 'sound/machines/fire_alarm/FireAlarm3.ogg', - 'sound/machines/fire_alarm/FireAlarm4.ogg', + 'sound/machines/fire_alarm/fire_alarm1.ogg', + 'sound/machines/fire_alarm/fire_alarm2.ogg', + 'sound/machines/fire_alarm/fire_alarm3.ogg', + 'sound/machines/fire_alarm/fire_alarm4.ogg', ) mid_length = 2.4 SECONDS volume = 30 @@ -207,6 +207,9 @@ extra_range = MEDIUM_RANGE_SOUND_EXTRARANGE falloff_exponent = 4 +/datum/looping_sound/soup/toxic + volume = 40 + /datum/looping_sound/cryo_cell mid_sounds = list( 'sound/machines/cryo/cryo_1.ogg', diff --git a/code/datums/mapgen/CaveGenerator.dm b/code/datums/mapgen/CaveGenerator.dm index c54b1e0c451..0bafac1f5a6 100644 --- a/code/datums/mapgen/CaveGenerator.dm +++ b/code/datums/mapgen/CaveGenerator.dm @@ -1,5 +1,10 @@ /// The random offset applied to square coordinates, causes intermingling at biome borders #define BIOME_RANDOM_SQUARE_DRIFT 2 +// Categories for spawned things +#define CAVE_SPAWN_MOB "mob" +#define CAVE_SPAWN_FEATURE "feature" +#define CAVE_SPAWN_TENDRIL "tendril" +#define CAVE_SPAWN_MEGAFAUNA "megafauna" /datum/map_generator/cave_generator var/name = "Cave Generator" @@ -31,14 +36,13 @@ var/list/weighted_feature_spawn_list ///Expanded list of extra features that can spawn in the area. Reads from the weighted list var/list/feature_spawn_list - /// The turf types to replace with a biome-related turf, as typecache. - /// Leave empty for all open turfs (but not closed turfs) to be hijacked. - var/list/biome_accepted_turfs = list() /// An associative list of biome type to the list of turfs that were /// generated of that biome specifically. Helps to improve the efficiency /// of biome-related operations. Is populated through /// `generate_terrain_with_biomes()`. var/list/generated_turfs_per_biome = list() + /// Same as generated_turfs_per_biome, but additionally indexed by area + var/list/generated_turfs_per_area_biome = list() /// 2D list of all biomes based on heat and humidity combos. Associative by /// `BIOME_X_HEAT` and then by `BIOME_X_HUMIDITY` (i.e. /// `possible_biomes[BIOME_LOW_HEAT][BIOME_LOWMEDIUM_HUMIDITY]`). @@ -49,15 +53,39 @@ /// result in slower transitions var/perlin_zoom = 65 - ///Base chance of spawning a mob + /// Should we populate turfs through biome datums if we have such + var/biome_population = TRUE + /// Noise threshold above which a biome is considered high heat + var/high_heat_threshold = -0.1 + /// Noise threshold above which a biome is considered medium heat + var/medium_heat_threshold = -0.3 + /// Noise threshold above which a biome is considered high humidity + var/high_humidity_threshold = -0.1 + /// Noise threshold above which a biome is considered medium humidity + var/medium_humidity_threshold = -0.3 + /// Should all generators on the same z level use the same seeds? + var/shared_seed = TRUE + /// Stamp size for DBP noise, aka frequency + var/biome_stamp_size = 75 + /// Stored noise maps per z level if we use a shared seed + var/static_biome_maps = list() + + /// Base chance of spawning a mob var/mob_spawn_chance = 6 - ///Base chance of spawning flora + /// Base chance of spawning flora var/flora_spawn_chance = 2 - ///Base chance of spawning features + /// Base chance of spawning features var/feature_spawn_chance = 0.25 - ///Unique ID for this spawner + /// Unique ID for this spawner var/string_gen + /// Radius around features within which we avoid spawning other features + var/feature_exclusion_radius = 7 + /// Radius around mobs which we avoid spawning other mobs + var/mob_exclusion_radius = 12 + /// Radius around megafauna within which we avoid spawning tendrils + var/megafauna_exclusion_radius = 7 + ///Chance of cells starting closed var/initial_closed_chance = 45 ///Amount of smoothing iterations @@ -101,7 +129,6 @@ open_turf_types = expand_weights(weighted_open_turf_types) closed_turf_types = expand_weights(weighted_closed_turf_types) - /datum/map_generator/cave_generator/generate_terrain(list/turfs, area/generate_in) . = ..() if(!(generate_in.area_flags_mapping & CAVES_ALLOWED)) @@ -141,31 +168,54 @@ * This should only be called by `generate_terrain()`, if you have to call this, * you're probably doing something wrong. */ -/datum/map_generator/cave_generator/proc/generate_terrain_with_biomes(list/turfs, area/generate_in) +/datum/map_generator/cave_generator/proc/generate_terrain_with_biomes(list/turf/turfs, area/generate_in) if(!(generate_in.area_flags_mapping & CAVES_ALLOWED)) return - var/humidity_seed = rand(0, 50000) - var/heat_seed = rand(0, 50000) + var/humidity_seed = null + var/heat_seed = null + + // Make sure that all caves on the same z level generate smoothly regardless of the area + if (shared_seed) + var/static/list/static_heat = null + var/static/list/static_humi = null + if (!static_heat) + static_heat = list() + static_humi = list() + + var/z_key = "[turfs[1].z]" + if (!static_heat[z_key]) + static_heat[z_key] = rand(0, 50000) + static_humi[z_key] = rand(0, 50000) + + heat_seed = static_heat[z_key] + humidity_seed = static_humi[z_key] + else + humidity_seed = rand(0, 50000) + heat_seed = rand(0, 50000) var/start_time = REALTIMEOFDAY string_gen = rustg_cnoise_generate("[initial_closed_chance]", "[smoothing_iterations]", "[birth_limit]", "[death_limit]", "[world.maxx]", "[world.maxy]") //Generate the raw CA data var/humidity_gen = list() - humidity_gen[BIOME_HIGH_HUMIDITY] = rustg_dbp_generate("[humidity_seed]", "60", "75", "[world.maxx]", "-0.1", "1.1") - humidity_gen[BIOME_MEDIUM_HUMIDITY] = rustg_dbp_generate("[humidity_seed]", "60", "75", "[world.maxx]", "-0.3", "-0.1") + humidity_gen[BIOME_HIGH_HUMIDITY] = rustg_dbp_generate("[humidity_seed]", "60", "[biome_stamp_size]", "[world.maxx]", "[high_heat_threshold]", "1.1") + humidity_gen[BIOME_MEDIUM_HUMIDITY] = rustg_dbp_generate("[humidity_seed]", "60", "[biome_stamp_size]", "[world.maxx]", "[medium_heat_threshold]", "[high_heat_threshold]") var/heat_gen = list() - heat_gen[BIOME_HIGH_HEAT] = rustg_dbp_generate("[heat_seed]", "60", "75", "[world.maxx]", "-0.1", "1.1") - heat_gen[BIOME_MEDIUM_HEAT] = rustg_dbp_generate("[heat_seed]", "60", "75", "[world.maxx]", "-0.3", "-0.1") + heat_gen[BIOME_HIGH_HEAT] = rustg_dbp_generate("[heat_seed]", "60", "[biome_stamp_size]", "[world.maxx]", "[high_heat_threshold]", "1.1") + heat_gen[BIOME_MEDIUM_HEAT] = rustg_dbp_generate("[heat_seed]", "60", "[biome_stamp_size]", "[world.maxx]", "[medium_heat_threshold]", "[high_heat_threshold]") - var/list/expanded_closed_turfs = src.closed_turf_types - var/list/expanded_open_turfs = src.open_turf_types + if (shared_seed) + static_biome_maps["[turfs[1].z]"] = list( + BIOME_HIGH_HUMIDITY = humidity_gen[BIOME_HIGH_HUMIDITY], + BIOME_MEDIUM_HUMIDITY = humidity_gen[BIOME_MEDIUM_HUMIDITY], + BIOME_HIGH_HEAT = heat_gen[BIOME_HIGH_HEAT], + BIOME_MEDIUM_HEAT = heat_gen[BIOME_MEDIUM_HEAT], + ) + var/list/to_generate = list() for(var/turf/gen_turf as anything in turfs) //Go through all the turfs and generate them var/closed = string_gen[world.maxx * (gen_turf.y - 1) + gen_turf.x] != "0" - var/new_turf_type = pick(closed ? expanded_closed_turfs : expanded_open_turfs) - var/datum/biome/selected_biome // Here comes the meat of the biome code. @@ -183,36 +233,48 @@ BIOME_HIGH_HEAT : text2num(heat_gen[BIOME_MEDIUM_HEAT][coordinate]) ? BIOME_MEDIUM_HEAT : BIOME_LOW_HEAT selected_biome = possible_biomes[heat_level][humidity_level] - - // Currently, we only affect open turfs, because biomes don't currently - // have a definition for biome-specific closed turfs. - if((!length(biome_accepted_turfs) && !closed) || biome_accepted_turfs[new_turf_type]) - LAZYADD(generated_turfs_per_biome[selected_biome], gen_turf) - - else - // The assumption is this will be faster then changeturf, and changeturf isn't required since by this point - // The old tile hasn't got the chance to init yet - var/turf/new_turf = new new_turf_type(gen_turf) - - if(gen_turf.turf_flags & NO_RUINS) - new_turf.turf_flags |= NO_RUINS - + LAZYSET(to_generate[selected_biome], gen_turf, closed) CHECK_TICK - for(var/biome in generated_turfs_per_biome) + for(var/biome in to_generate) var/datum/biome/generating_biome = SSmapping.biomes[biome] - - var/list/turf/generated_turfs = generating_biome.generate_turfs_for_terrain(generated_turfs_per_biome[biome]) - - generated_turfs_per_biome[biome] = generated_turfs + var/list/turf/generated_turfs = generating_biome.generate_turfs_for_terrain(to_generate[biome]) + generated_turfs_per_biome[biome] = (generated_turfs_per_biome[biome] || list()) + generated_turfs + var/list/area_list = generated_turfs_per_area_biome[biome] + if (!area_list) + area_list = list() + generated_turfs_per_area_biome[biome] = area_list + area_list[generate_in] = generated_turfs var/message = "[name] terrain generation finished in [(REALTIMEOFDAY - start_time)/10]s!" to_chat(world, span_boldannounce("[message]"), MESSAGE_TYPE_DEBUG) log_world(message) +/// Returns a biome datum that the turf was initialized with, or would be if it is present on our Z level and we use a consistent shared seed +/// Not consistent between calls by itself due to using RNG in perlin zoom, needs a static coordinate-based formula +/datum/map_generator/cave_generator/proc/get_biome_for_turf(turf/target) + for (var/biome in generated_turfs_per_biome) + var/list/generated_turfs = generated_turfs_per_biome[biome] + if (generated_turfs[target]) + return biome + + var/list/biome_map = static_biome_maps["[target.z]"] + if (!shared_seed || !biome_map) + return null + + var/drift_x = clamp((target.x + rand(-BIOME_RANDOM_SQUARE_DRIFT, BIOME_RANDOM_SQUARE_DRIFT)), 1, world.maxx) + var/drift_y = clamp((target.y + rand(-BIOME_RANDOM_SQUARE_DRIFT, BIOME_RANDOM_SQUARE_DRIFT)), 2, world.maxy) + var/coordinate = world.maxx * (drift_y - 1) + drift_x + + var/humidity_level = text2num(biome_map[BIOME_HIGH_HUMIDITY][coordinate]) ? \ + BIOME_HIGH_HUMIDITY : text2num(biome_map[BIOME_MEDIUM_HUMIDITY][coordinate]) ? BIOME_MEDIUM_HUMIDITY : BIOME_LOW_HUMIDITY + var/heat_level = text2num(biome_map[BIOME_HIGH_HEAT][coordinate]) ? \ + BIOME_HIGH_HEAT : text2num(biome_map[BIOME_MEDIUM_HEAT][coordinate]) ? BIOME_MEDIUM_HEAT : BIOME_LOW_HEAT + + return possible_biomes[heat_level][humidity_level] /datum/map_generator/cave_generator/populate_terrain(list/turfs, area/generate_in) - if(length(possible_biomes)) + if (biome_population && length(possible_biomes)) return populate_terrain_with_biomes(turfs, generate_in) // Area var pullouts to make accessing in the loop faster @@ -223,88 +285,98 @@ var/start_time = REALTIMEOFDAY - for(var/turf/target_turf as anything in turfs) - if(!(target_turf.type in open_turf_types)) //only put stuff on open turfs we generated, so closed walls and rivers and stuff are skipped + // Assoc list of spawned categories to + var/list/spawn_data = list( + CAVE_SPAWN_FEATURE = list(), + CAVE_SPAWN_TENDRIL = list(), + CAVE_SPAWN_MOB = list(), + CAVE_SPAWN_MEGAFAUNA = list(), + ) + + var/list/open_turf_cache = typecacheof(open_turf_types) + for (var/turf/target_turf as anything in turfs) + // Only put stuff on open turfs we generated, so closed walls and rivers and stuff are skipped + if (!is_type_in_typecache(target_turf, open_turf_cache)) continue - // If we've spawned something yet - var/spawned_something = FALSE + CHECK_TICK - if(!(target_turf.turf_flags & TURF_BLOCKS_POPULATE_TERRAIN_FLORAFEATURES)) - ///Spawning isn't done in procs to save on overhead on the 60k turfs we're going through. - //FLORA SPAWNING HERE - if(flora_allowed && prob(flora_spawn_chance)) + if (!(target_turf.turf_flags & TURF_BLOCKS_POPULATE_TERRAIN_FLORAFEATURES)) + if (flora_allowed && prob(flora_spawn_chance)) var/flora_type = pick(flora_spawn_list) new flora_type(target_turf) - spawned_something = TRUE + continue - //FEATURE SPAWNING HERE - //we may have generated something from the flora list on the target turf, so let's not place - //a feature here if that's the case (because it would look stupid) - if(feature_allowed && !spawned_something && prob(feature_spawn_chance)) + if (feature_allowed && prob(feature_spawn_chance)) var/can_spawn = TRUE - - var/atom/picked_feature = pick(feature_spawn_list) - - for(var/obj/structure/existing_feature in range(7, target_turf)) - if(istype(existing_feature, picked_feature)) + for(var/turf/spawn_turf as anything in spawn_data[CAVE_SPAWN_FEATURE]) + if (get_dist(spawn_turf, target_turf) <= feature_exclusion_radius) can_spawn = FALSE break - if(can_spawn) + if (can_spawn) + var/picked_feature = pick(feature_spawn_list) new picked_feature(target_turf) - spawned_something = TRUE + spawn_data[CAVE_SPAWN_FEATURE] += target_turf + continue - //MOB SPAWNING HERE - if(mobs_allowed && !spawned_something && prob(mob_spawn_chance)) - var/atom/picked_mob = pick(mob_spawn_list) - var/is_megafauna = FALSE + if (!mobs_allowed || !prob(mob_spawn_chance)) + continue - if(picked_mob == SPAWN_MEGAFAUNA) - if(megas_allowed) //this is danger. it's boss time. - picked_mob = pick(megafauna_spawn_list) - is_megafauna = TRUE - else //this is not danger, don't spawn a boss, spawn something else - picked_mob = pick(mob_spawn_no_mega_list) //What if we used 100% of the brain...and did something (slightly) less shit than a while loop? + var/picked_mob = pick(megas_allowed ? mob_spawn_list : mob_spawn_no_mega_list) + var/is_megafauna = FALSE + if (picked_mob == SPAWN_MEGAFAUNA) + picked_mob = pick(megafauna_spawn_list) + is_megafauna = TRUE - var/can_spawn = TRUE - - // prevents tendrils spawning in each other's collapse range - if(ispath(picked_mob, /obj/structure/spawner/lavaland)) - for(var/obj/structure/spawner/lavaland/spawn_blocker in range(2, target_turf)) - can_spawn = FALSE - break - // if the random is not a tendril (hopefully meaning it is a mob), avoid spawning if there's another one within 12 tiles - else - var/list/things_in_range = range(12, target_turf) - for(var/mob/living/mob_blocker in things_in_range) - if(ismining(mob_blocker)) - can_spawn = FALSE - break - // Also block spawns if there's a random lavaland mob spawner nearby and it's not a mega - if(!is_megafauna) - can_spawn = can_spawn && !(locate(/obj/effect/spawner/random/lavaland_mob) in things_in_range) - //if there's a megafauna within standard view don't spawn anything at all (This isn't really consistent, I don't know why we do this. you do you tho) - if(can_spawn) - for(var/mob/living/simple_animal/hostile/megafauna/found_fauna in range(7, target_turf)) + var/can_spawn = TRUE + if(ispath(picked_mob, /mob/living/basic/mining/tendril)) + // Prevents tendrils spawning in each other's collapse range + for(var/turf/spawn_turf as anything in spawn_data[CAVE_SPAWN_TENDRIL]) + if (get_dist(spawn_turf, target_turf) <= 2) can_spawn = FALSE break - if(can_spawn) - if(ispath(picked_mob, /mob/living/simple_animal/hostile/megafauna/bubblegum)) //there can be only one bubblegum, so don't waste spawns on it - weighted_megafauna_spawn_list.Remove(picked_mob) - megafauna_spawn_list = expand_weights(weighted_megafauna_spawn_list) - megas_allowed = megas_allowed && length(megafauna_spawn_list) - new picked_mob(target_turf) - spawned_something = TRUE - CHECK_TICK + // Also avoid spawning them next to megafauna + for(var/turf/spawn_turf as anything in spawn_data[CAVE_SPAWN_MEGAFAUNA]) + if (get_dist(spawn_turf, target_turf) <= megafauna_exclusion_radius) + can_spawn = FALSE + break + else if (is_megafauna) + // Megafauna can spawn wherever it wants as long as its not next to another mega + for(var/turf/spawn_turf as anything in spawn_data[CAVE_SPAWN_MEGAFAUNA]) + if (get_dist(spawn_turf, target_turf) <= megafauna_exclusion_radius) + can_spawn = FALSE + break + else + for(var/turf/spawn_turf as anything in spawn_data[CAVE_SPAWN_MOB]) + if (get_dist(spawn_turf, target_turf) <= mob_exclusion_radius) + can_spawn = FALSE + break + + if (!can_spawn) + continue + + if (ispath(picked_mob, /mob/living/basic/mining/tendril)) + spawn_data[CAVE_SPAWN_TENDRIL] += target_turf + else + if (is_megafauna) + spawn_data[CAVE_SPAWN_MEGAFAUNA] += target_turf + spawn_data[CAVE_SPAWN_MOB] += target_turf + + new picked_mob(target_turf) + + // There can be only one Bubblegum, so don't waste spawns on it + if(ispath(picked_mob, /mob/living/simple_animal/hostile/megafauna/bubblegum)) + weighted_megafauna_spawn_list.Remove(picked_mob) + megafauna_spawn_list = expand_weights(weighted_megafauna_spawn_list) + megas_allowed = megas_allowed && length(megafauna_spawn_list) var/message = "[name] terrain population finished in [(REALTIMEOFDAY - start_time)/10]s!" add_startup_message(message) //SKYRAT EDIT CHANGE //to_chat(world, span_boldannounce("[message]"), MESSAGE_TYPE_DEBUG) //SKYRAT EDIT ORIGINAL log_world(message) - /** * This handles the population of terrain with biomes. Should only be called by * `populate_terrain()`, if you find yourself calling this, you're probably not @@ -328,9 +400,10 @@ log_world(message) return - for(var/biome in generated_turfs_per_biome) + for(var/biome in generated_turfs_per_area_biome) var/datum/biome/generating_biome = SSmapping.biomes[biome] - generating_biome.populate_turfs(generated_turfs_per_biome[biome], flora_allowed, features_allowed, fauna_allowed) + var/list/areas_list = generated_turfs_per_area_biome[biome] + generating_biome.populate_turfs(areas_list[generate_in], flora_allowed, features_allowed, fauna_allowed) CHECK_TICK @@ -338,7 +411,6 @@ to_chat(world, span_boldannounce("[message]"), MESSAGE_TYPE_DEBUG) log_world(message) - /datum/map_generator/cave_generator/jungle possible_biomes = list( BIOME_LOW_HEAT = list( @@ -360,3 +432,7 @@ #undef BIOME_RANDOM_SQUARE_DRIFT +#undef CAVE_SPAWN_MOB +#undef CAVE_SPAWN_FEATURE +#undef CAVE_SPAWN_TENDRIL +#undef CAVE_SPAWN_MEGAFAUNA diff --git a/code/datums/mapgen/Cavegens/LavalandGenerator.dm b/code/datums/mapgen/Cavegens/LavalandGenerator.dm index be4dc3710f2..40c25b51c28 100644 --- a/code/datums/mapgen/Cavegens/LavalandGenerator.dm +++ b/code/datums/mapgen/Cavegens/LavalandGenerator.dm @@ -2,47 +2,30 @@ weighted_open_turf_types = list(/turf/open/misc/asteroid/basalt/lava_land_surface = 1) weighted_closed_turf_types = list(/turf/closed/mineral/random/volcanic = 1) - weighted_mob_spawn_list = list( - SPAWN_MEGAFAUNA = 2, - /obj/effect/spawner/random/lavaland_mob/goliath = 50, - /obj/effect/spawner/random/lavaland_mob/legion = 30, - /obj/effect/spawner/random/lavaland_mob/watcher = 40, - /mob/living/basic/mining/bileworm = 20, - /mob/living/basic/mining/brimdemon = 20, - /mob/living/basic/mining/lobstrosity/lava = 20, - /obj/effect/spawner/random/lavaland_mob/raptor = 15, - /mob/living/basic/mining/goldgrub = 10, - /obj/structure/spawner/lavaland = 2, - /obj/structure/spawner/lavaland/goliath = 3, - /obj/structure/spawner/lavaland/legion = 3, - ) + possible_biomes = list( + BIOME_LOW_HEAT = list( + BIOME_LOW_HUMIDITY = /datum/biome/lavaland/basalt, + BIOME_MEDIUM_HUMIDITY = /datum/biome/lavaland/basalt, + BIOME_HIGH_HUMIDITY = /datum/biome/lavaland/shale, + ), + BIOME_MEDIUM_HEAT = list( + BIOME_LOW_HUMIDITY = /datum/biome/lavaland/basalt, + BIOME_MEDIUM_HUMIDITY = /datum/biome/lavaland/basalt, + BIOME_HIGH_HUMIDITY = /datum/biome/lavaland/shale, + ), + BIOME_HIGH_HEAT = list( + BIOME_LOW_HUMIDITY = /datum/biome/lavaland/basalt, + BIOME_MEDIUM_HUMIDITY = /datum/biome/lavaland/red_rock, + BIOME_HIGH_HUMIDITY = /datum/biome/lavaland/red_rock, + ), + ) - weighted_flora_spawn_list = list( - /obj/structure/flora/ash/cacti = 1, - /obj/structure/flora/ash/cap_shroom = 2, - /obj/structure/flora/ash/fireblossom = 2, - /obj/structure/flora/ash/leaf_shroom = 2, - /obj/structure/flora/ash/seraka = 2, - /obj/structure/flora/ash/stem_shroom = 2, - /obj/structure/flora/ash/tall_shroom = 2, - ) - - ///Note that this spawn list is also in the icemoon generator - weighted_feature_spawn_list = list( - /obj/structure/geyser/hollowwater = 8, - /obj/structure/geyser/plasma_oxide = 8, - /obj/structure/geyser/protozine = 8, - /obj/structure/geyser/random = 2, - /obj/structure/geyser/wittel = 8, - /obj/structure/geyser/chiral_buffer = 8, - /obj/structure/ore_vent/boss = 1, - ) - - initial_closed_chance = 45 + high_heat_threshold = 0.15 + high_humidity_threshold = 0.15 + biome_stamp_size = 60 smoothing_iterations = 50 - birth_limit = 4 - death_limit = 3 /datum/map_generator/cave_generator/lavaland/ruin_version + biome_population = FALSE weighted_open_turf_types = list(/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins = 1) weighted_closed_turf_types = list(/turf/closed/mineral/volcanic/lava_land_surface/do_not_chasm = 1) diff --git a/code/datums/mapgen/biomes/_biome.dm b/code/datums/mapgen/biomes/_biome.dm index bda1029f431..dc2a17563b3 100644 --- a/code/datums/mapgen/biomes/_biome.dm +++ b/code/datums/mapgen/biomes/_biome.dm @@ -1,7 +1,14 @@ +#define CAVE_SPAWN_MOB "mob" +#define CAVE_SPAWN_FEATURE "feature" +#define CAVE_SPAWN_TENDRIL "tendril" +#define CAVE_SPAWN_MEGAFAUNA "megafauna" + ///This datum handles the transitioning from a turf to a specific biome, and handles spawning decorative structures and mobs. /datum/biome - ///Type of turf this biome creates - var/turf_type + /// Type of turf this biome creates for open turfs + var/open_turf_type + /// Type of turf this biome creates for closed turfs + var/closed_turf_type /// Chance of having a structure from the flora types list spawn var/flora_density = 0 /// Chance of spawning special features, such as geysers. @@ -17,7 +24,17 @@ /// Weighted list of type paths of fauna that can be spawned when the /// turf spawns fauna. var/list/fauna_types = list() - + /// Weighted list of megafauna that can spawn from SPAWN_MEGAFAUNA fauna entry + /// Defaults to GLOB.megafauna_spawn_list + var/list/megafauna_types = null + /// Radius around features within which we avoid spawning other features + var/feature_exclusion_radius = 7 + /// Radius around mobs which we avoid spawning other mobs + var/mob_exclusion_radius = 12 + /// Radius around megafauna within which we avoid spawning tendrils + var/megafauna_exclusion_radius = 7 + /// Minimum distance between tendril spawns + var/tendril_exclusion_radius = 12 /datum/biome/New() . = ..() @@ -30,10 +47,17 @@ if(length(feature_types)) feature_types = expand_weights(feature_types) + if(isnull(megafauna_types)) + megafauna_types = GLOB.megafauna_spawn_list ///This proc handles the creation of a turf of a specific biome type -/datum/biome/proc/generate_turf(turf/gen_turf) - gen_turf.ChangeTurf(turf_type, null, CHANGETURF_DEFER_CHANGE) +/datum/biome/proc/generate_turf(turf/gen_turf, closed) + if (closed) + gen_turf.ChangeTurf(closed_turf_type, null, CHANGETURF_DEFER_CHANGE) + return + + gen_turf.ChangeTurf(open_turf_type, null, CHANGETURF_DEFER_CHANGE) + if(length(flora_types) && prob(flora_density)) var/obj/structure/flora = pick(flora_types) new flora(gen_turf) @@ -52,7 +76,8 @@ /// This proc handles the creation of a turf of a specific biome type, assuming /// that the turf has not been initialized yet. Don't call this unless you know /// what you're doing. -/datum/biome/proc/generate_turf_for_terrain(turf/gen_turf) +/datum/biome/proc/generate_turf_for_terrain(turf/gen_turf, closed) + var/turf_type = closed ? closed_turf_type : open_turf_type var/turf/new_turf = new turf_type(gen_turf) return new_turf @@ -70,8 +95,10 @@ var/list/turf/new_turfs = list() for(var/turf/gen_turf as anything in gen_turfs) + var/closed = gen_turfs[gen_turf] + var/turf_type = closed ? closed_turf_type : open_turf_type var/turf/new_turf = new turf_type(gen_turf) - new_turfs += new_turf + new_turfs[new_turf] = turf_type if(gen_turf.turf_flags & NO_RUINS) new_turf.turf_flags |= NO_RUINS @@ -81,49 +108,6 @@ return new_turfs -/// This proc handles populating the given turf based on whether flora, -/// features and fauna are allowed. Does not take megafauna into account. -/datum/biome/proc/populate_turf(turf/target_turf, flora_allowed, features_allowed, fauna_allowed) - if(flora_allowed && length(flora_types) && prob(flora_density)) - var/obj/structure/flora = pick(flora_types) - new flora(target_turf) - return TRUE - - if(features_allowed && prob(feature_density)) - var/can_spawn = TRUE - - var/atom/picked_feature = pick(feature_types) - - for(var/obj/structure/existing_feature in range(7, target_turf)) - if(istype(existing_feature, picked_feature)) - can_spawn = FALSE - break - - if(can_spawn) - new picked_feature(target_turf) - return TRUE - - if(fauna_allowed && length(fauna_types) && prob(fauna_density)) - var/mob/picked_mob = pick(fauna_types) - - // prevents tendrils spawning in each other's collapse range - if(ispath(picked_mob, /obj/structure/spawner/lavaland)) - for(var/obj/structure/spawner/lavaland/spawn_blocker in range(2, target_turf)) - return FALSE - - // if the random is not a tendril (hopefully meaning it is a mob), avoid spawning if there's another one within 12 tiles - else - var/list/things_in_range = range(12, target_turf) - for(var/mob/living/mob_blocker in things_in_range) - if(ismining(mob_blocker)) - return FALSE - - new picked_mob(target_turf) - return TRUE - - return FALSE - - /** * This proc handles populating the given turfs based on whether flora, features * and fauna are allowed. Does not take megafauna into account. @@ -133,99 +117,102 @@ * allowed type. Aka, we return early if the proc wouldn't do anything anyway. */ /datum/biome/proc/populate_turfs(list/turf/target_turfs, flora_allowed, features_allowed, fauna_allowed) - if(!(flora_allowed && length(flora_types)) && !(features_allowed && length(feature_types)) && !(fauna_allowed && length(fauna_types))) + var/has_flora = flora_allowed && length(flora_types) + var/has_features = features_allowed && length(feature_types) + var/has_fauna = fauna_allowed && length(fauna_types) + + if(!has_flora && !has_features && !has_fauna) return - for(var/turf/target_turf as anything in target_turfs) - // We do the CHECK_TICK here because there's a bunch of continue calls - // in this. - CHECK_TICK + // Assoc list of spawned categories to + // Static as to be shared between all biomes + var/static/list/spawn_data + if (isnull(spawn_data)) + spawn_data = list( + CAVE_SPAWN_FEATURE = list(), + CAVE_SPAWN_TENDRIL = list(), + CAVE_SPAWN_MOB = list(), + CAVE_SPAWN_MEGAFAUNA = list(), + ) - if(flora_allowed && length(flora_types) && prob(flora_density)) - var/obj/structure/flora = pick(flora_types) - new flora(target_turf) + for(var/turf/target_turf as anything in target_turfs) + // Only put stuff on open turfs we generated, so closed walls and rivers and stuff are skipped + if(!istype(target_turf, open_turf_type)) continue - if(features_allowed && prob(feature_density)) - var/can_spawn = TRUE + CHECK_TICK + if (!(target_turf.turf_flags & TURF_BLOCKS_POPULATE_TERRAIN_FLORAFEATURES)) + if (flora_allowed && prob(flora_density)) + var/flora_type = pick(flora_types) + new flora_type(target_turf) + continue - var/atom/picked_feature = pick(feature_types) + if (features_allowed && prob(feature_density)) + var/can_spawn = TRUE + for(var/turf/spawn_turf as anything in spawn_data[CAVE_SPAWN_FEATURE]) + if (get_dist(spawn_turf, target_turf) <= feature_exclusion_radius) + can_spawn = FALSE + break - for(var/obj/structure/existing_feature in range(7, target_turf)) - if(istype(existing_feature, picked_feature)) + if (can_spawn) + var/picked_feature = pick(feature_types) + new picked_feature(target_turf) + spawn_data[CAVE_SPAWN_FEATURE] += target_turf + continue + + if (!fauna_allowed || !prob(fauna_density)) + continue + + var/picked_mob = pick(fauna_types) + var/is_megafauna = FALSE + if (picked_mob == SPAWN_MEGAFAUNA) + picked_mob = pick_weight(megafauna_types) + is_megafauna = TRUE + + var/can_spawn = TRUE + if(ispath(picked_mob, /mob/living/basic/mining/tendril)) + for(var/turf/spawn_turf as anything in spawn_data[CAVE_SPAWN_TENDRIL]) + if (get_dist(spawn_turf, target_turf) <= tendril_exclusion_radius) can_spawn = FALSE break - if(can_spawn) - new picked_feature(target_turf) + if (!can_spawn) continue - if(fauna_allowed && length(fauna_types) && prob(fauna_density)) - var/mob/picked_mob = pick(fauna_types) + // Also avoid spawning them next to megafauna + for(var/turf/spawn_turf as anything in spawn_data[CAVE_SPAWN_MEGAFAUNA]) + if (get_dist(spawn_turf, target_turf) <= megafauna_exclusion_radius) + can_spawn = FALSE + break - // prevents tendrils spawning in each other's collapse range - if(ispath(picked_mob, /obj/structure/spawner/lavaland)) - for(var/obj/structure/spawner/lavaland/spawn_blocker in range(2, target_turf)) - continue + else if (is_megafauna) + // Megafauna can spawn wherever it wants as long as its not next to another mega + for(var/turf/spawn_turf as anything in spawn_data[CAVE_SPAWN_MEGAFAUNA]) + if (get_dist(spawn_turf, target_turf) <= megafauna_exclusion_radius) + can_spawn = FALSE + break + else + for(var/turf/spawn_turf as anything in spawn_data[CAVE_SPAWN_MOB]) + if (get_dist(spawn_turf, target_turf) <= mob_exclusion_radius) + can_spawn = FALSE + break - // if the random is not a tendril (hopefully meaning it is a mob), avoid spawning if there's another one within 12 tiles - else - var/list/things_in_range = range(12, target_turf) - for(var/mob/living/mob_blocker in things_in_range) - if(ismining(mob_blocker)) - continue + if (!can_spawn) + continue - new picked_mob(target_turf) + if (ispath(picked_mob, /mob/living/basic/mining/tendril)) + spawn_data[CAVE_SPAWN_TENDRIL] += target_turf + else if (is_megafauna) + spawn_data[CAVE_SPAWN_MEGAFAUNA] += target_turf + spawn_data[CAVE_SPAWN_MOB] += target_turf + new picked_mob(target_turf) -/datum/biome/mudlands - turf_type = /turf/open/misc/dirt/jungle/dark - flora_types = list( - /obj/structure/flora/grass/jungle/a/style_random = 1, - /obj/structure/flora/grass/jungle/b/style_random = 1, - /obj/structure/flora/rock/pile/jungle/style_random = 1, - /obj/structure/flora/rock/pile/jungle/large/style_random = 1, - ) - flora_density = 3 + // There can be only one Bubblegum, so don't waste spawns on it + if(ispath(picked_mob, /mob/living/simple_animal/hostile/megafauna/bubblegum)) + megafauna_types.Remove(picked_mob) -/datum/biome/plains - turf_type = /turf/open/misc/grass/jungle - flora_types = list( - /obj/structure/flora/grass/jungle/a/style_random = 1, - /obj/structure/flora/grass/jungle/b/style_random = 1, - /obj/structure/flora/tree/jungle/style_random = 1, - /obj/structure/flora/rock/pile/jungle/style_random = 1, - /obj/structure/flora/bush/jungle/a/style_random = 1, - /obj/structure/flora/bush/jungle/b/style_random = 1, - /obj/structure/flora/bush/jungle/c/style_random = 1, - /obj/structure/flora/bush/large/style_random = 1, - /obj/structure/flora/rock/pile/jungle/large/style_random = 1, - ) - flora_density = 15 - -/datum/biome/jungle - turf_type = /turf/open/misc/grass/jungle - flora_types = list( - /obj/structure/flora/grass/jungle/a/style_random = 1, - /obj/structure/flora/grass/jungle/b/style_random = 1, - /obj/structure/flora/tree/jungle/style_random = 1, - /obj/structure/flora/rock/pile/jungle/style_random = 1, - /obj/structure/flora/bush/jungle/a/style_random = 1, - /obj/structure/flora/bush/jungle/b/style_random = 1, - /obj/structure/flora/bush/jungle/c/style_random = 1, - /obj/structure/flora/bush/large/style_random = 1, - /obj/structure/flora/rock/pile/jungle/large/style_random = 1, - ) - flora_density = 40 - -/datum/biome/jungle/deep - flora_density = 65 - -/datum/biome/wasteland - turf_type = /turf/open/misc/dirt/jungle/wasteland - -/datum/biome/water - turf_type = /turf/open/water/jungle - -/datum/biome/mountain - turf_type = /turf/closed/mineral/random/jungle +#undef CAVE_SPAWN_MOB +#undef CAVE_SPAWN_FEATURE +#undef CAVE_SPAWN_TENDRIL +#undef CAVE_SPAWN_MEGAFAUNA diff --git a/code/datums/mapgen/biomes/jungle.dm b/code/datums/mapgen/biomes/jungle.dm new file mode 100644 index 00000000000..a15bc7fd1f7 --- /dev/null +++ b/code/datums/mapgen/biomes/jungle.dm @@ -0,0 +1,57 @@ +/datum/biome/mudlands + open_turf_type = /turf/open/misc/dirt/jungle/dark + closed_turf_type = /turf/closed/mineral/random/jungle + flora_types = list( + /obj/structure/flora/grass/jungle/a/style_random = 1, + /obj/structure/flora/grass/jungle/b/style_random = 1, + /obj/structure/flora/rock/pile/jungle/style_random = 1, + /obj/structure/flora/rock/pile/jungle/large/style_random = 1, + ) + flora_density = 3 + +/datum/biome/plains + open_turf_type = /turf/open/misc/grass/jungle + closed_turf_type = /turf/closed/mineral/random/jungle + flora_types = list( + /obj/structure/flora/grass/jungle/a/style_random = 1, + /obj/structure/flora/grass/jungle/b/style_random = 1, + /obj/structure/flora/tree/jungle/style_random = 1, + /obj/structure/flora/rock/pile/jungle/style_random = 1, + /obj/structure/flora/bush/jungle/a/style_random = 1, + /obj/structure/flora/bush/jungle/b/style_random = 1, + /obj/structure/flora/bush/jungle/c/style_random = 1, + /obj/structure/flora/bush/large/style_random = 1, + /obj/structure/flora/rock/pile/jungle/large/style_random = 1, + ) + flora_density = 15 + +/datum/biome/jungle + open_turf_type = /turf/open/misc/grass/jungle + closed_turf_type = /turf/closed/mineral/random/jungle + flora_types = list( + /obj/structure/flora/grass/jungle/a/style_random = 1, + /obj/structure/flora/grass/jungle/b/style_random = 1, + /obj/structure/flora/tree/jungle/style_random = 1, + /obj/structure/flora/rock/pile/jungle/style_random = 1, + /obj/structure/flora/bush/jungle/a/style_random = 1, + /obj/structure/flora/bush/jungle/b/style_random = 1, + /obj/structure/flora/bush/jungle/c/style_random = 1, + /obj/structure/flora/bush/large/style_random = 1, + /obj/structure/flora/rock/pile/jungle/large/style_random = 1, + ) + flora_density = 40 + +/datum/biome/jungle/deep + flora_density = 65 + +/datum/biome/wasteland + open_turf_type = /turf/open/misc/dirt/jungle/wasteland + closed_turf_type = /turf/closed/mineral/random/jungle + +/datum/biome/water + open_turf_type = /turf/open/water/jungle + closed_turf_type = /turf/closed/mineral/random/jungle + +/datum/biome/mountain + open_turf_type = /turf/closed/mineral/random/jungle + closed_turf_type = /turf/closed/mineral/random/jungle diff --git a/code/datums/mapgen/biomes/lavaland.dm b/code/datums/mapgen/biomes/lavaland.dm new file mode 100644 index 00000000000..88c907dc23f --- /dev/null +++ b/code/datums/mapgen/biomes/lavaland.dm @@ -0,0 +1,113 @@ +/datum/biome/lavaland + open_turf_type = /turf/open/misc/asteroid/basalt/lava_land_surface + closed_turf_type = /turf/closed/mineral/volcanic + mob_exclusion_radius = 7 + +/datum/biome/lavaland/basalt + closed_turf_type = /turf/closed/mineral/random/volcanic + + fauna_density = 6 + flora_density = 2.5 + feature_density = 0.25 + + // Legions and goliaths, but fewer watchers and no demons + fauna_types = list( + SPAWN_MEGAFAUNA = 2, + /obj/effect/spawner/random/lavaland_mob/goliath = 50, + /obj/effect/spawner/random/lavaland_mob/legion = 40, + /obj/effect/spawner/random/lavaland_mob/watcher = 20, + /mob/living/basic/mining/bileworm = 10, + /mob/living/basic/mining/lobstrosity/lava = 20, + /obj/effect/spawner/random/lavaland_mob/raptor = 15, + /mob/living/basic/mining/goldgrub = 15, + /mob/living/basic/mining/tendril = 7, + ) + + flora_types = list( + /obj/structure/flora/ash/cap_shroom = 3, + /obj/structure/flora/ash/fireblossom = 1, + /obj/structure/flora/ash/stem_shroom = 1, + /obj/structure/flora/rock/style_random = 1, + /obj/structure/flora/rock/pile/style_random = 3, + /obj/structure/flora/rock/volcano = 1, + ) + + feature_types = list( + /obj/structure/geyser/plasma_oxide = 8, + /obj/structure/geyser/protozine = 8, + /obj/structure/geyser/wittel = 8, + /obj/structure/geyser/random = 3, + /obj/structure/ore_vent/boss = 1, + ) + +/datum/biome/lavaland/shale + open_turf_type = /turf/open/misc/asteroid/basalt/smooth/shale/lava_land_surface + closed_turf_type = /turf/closed/mineral/random/volcanic/shale + fauna_density = 6 + flora_density = 5 + feature_density = 0.25 + + // Higher chance of lobstrocities, goldgrubs and brimdemons, but no bileworms + fauna_types = list( + SPAWN_MEGAFAUNA = 2, + /obj/effect/spawner/random/lavaland_mob/goliath = 40, + /obj/effect/spawner/random/lavaland_mob/legion = 20, + /obj/effect/spawner/random/lavaland_mob/watcher = 30, + /mob/living/basic/mining/brimdemon = 40, + /mob/living/basic/mining/lobstrosity/lava = 40, + /obj/effect/spawner/random/lavaland_mob/raptor = 15, + /mob/living/basic/mining/goldgrub = 35, + /mob/living/basic/mining/tendril = 8, + ) + + flora_types = list( + /obj/structure/flora/ash/fireblossom = 2, + /obj/structure/flora/ash/leaf_shroom = 2, + /obj/structure/flora/ash/seraka = 2, + /obj/structure/flora/ash/glowgrowth = 2, + /obj/structure/flora/rock/pile/shale/style_random = 5, + ) + + feature_types = list( + /obj/structure/geyser/hollowwater = 12, + /obj/structure/geyser/plasma_oxide = 12, + /obj/structure/geyser/random = 3, + /obj/structure/ore_vent/boss = 1, + ) + +/datum/biome/lavaland/red_rock + open_turf_type = /turf/open/misc/asteroid/basalt/smooth/siderite/lava_land_surface + closed_turf_type = /turf/closed/mineral/random/volcanic/red_rock + fauna_density = 6 + flora_density = 4 + feature_density = 0.25 + + // Bileworms, raptors and watchers, but few goliaths + fauna_types = list( + SPAWN_MEGAFAUNA = 2, + /obj/effect/spawner/random/lavaland_mob/goliath = 20, + /obj/effect/spawner/random/lavaland_mob/legion = 25, + /obj/effect/spawner/random/lavaland_mob/watcher = 55, + /mob/living/basic/mining/bileworm = 35, + /mob/living/basic/mining/brimdemon = 15, + /mob/living/basic/mining/lobstrosity/lava = 25, + /obj/effect/spawner/random/lavaland_mob/raptor = 20, + /mob/living/basic/mining/goldgrub = 15, + /mob/living/basic/mining/tendril = 6, + ) + + flora_types = list( + /obj/structure/flora/ash/cacti = 2, + /obj/structure/flora/ash/cap_shroom = 1, + /obj/structure/flora/ash/tall_shroom = 2, + /obj/structure/flora/ash/stem_shroom = 2, + /obj/structure/flora/rock/pile/siderite/style_random = 4, + /obj/structure/flora/rock/siderite_growth = 1, + ) + + feature_types = list( + /obj/structure/geyser/protozine = 12, + /obj/structure/geyser/chiral_buffer = 12, + /obj/structure/geyser/random = 3, + /obj/structure/ore_vent/boss = 1, + ) diff --git a/code/datums/martial/_action.dm b/code/datums/martial/_action.dm new file mode 100644 index 00000000000..72d3dadc39b --- /dev/null +++ b/code/datums/martial/_action.dm @@ -0,0 +1,39 @@ +/datum/action/swap_arts + name = "Remember the Basics" //this is dynamic, uses `update_button_name` + desc = "LMB: See your movelist. RMB: Swap artstyle, if you have more than one." + background_icon_state = "bg_martial_arts" + button_icon_state = "martial" + + ///The martial arts currently used for the name & help information. + var/datum/martial_art/current_used_art + +/datum/action/swap_arts/Destroy() + current_used_art = null + return ..() + +/datum/action/swap_arts/New(Target, datum/martial_art/starting_style) + current_used_art = starting_style + return ..() + +/datum/action/swap_arts/update_button_name(atom/movable/screen/movable/action_button/button, force, datum/martial_art/new_art) + if(new_art) + current_used_art = new_art + name = "[current_used_art.help_verb]" + var/mob/living/living_owner = owner + if(LAZYLEN(living_owner.martial_arts) >= 2) + name += "/Swap Style" + return ..() + +/datum/action/swap_arts/Trigger(mob/living/clicker, trigger_flags) + . = ..() + var/mob/living/living_owner = owner + if(trigger_flags & TRIGGER_SECONDARY_ACTION && (LAZYLEN(living_owner.martial_arts) >= 2)) + clicker.cycle_style() + return TRUE + var/help_information = current_used_art.get_style_help() + if(isnull(help_information)) + to_chat(clicker, span_notice("[current_used_art.name] doesn't have any combat information!")) + return TRUE + for(var/info in help_information) + to_chat(clicker, info) + return TRUE diff --git a/code/datums/martial/_martial.dm b/code/datums/martial/_martial.dm index 1281d028b22..53dbaae321d 100644 --- a/code/datums/martial/_martial.dm +++ b/code/datums/martial/_martial.dm @@ -19,7 +19,7 @@ VAR_PRIVATE/datum/weakref/current_target /// Path to verb to display help text for this martial art. - var/help_verb + var/help_verb = "Remember the Basics" /// If TRUE, this martial art smashes tables when performing table slams and head smashes var/smashes_tables = FALSE /// If TRUE, a combo meter will be displayed on the HUD for the current streak @@ -327,9 +327,11 @@ LAZYINSERT(new_holder.martial_arts, 2, src) else LAZYADD(new_holder.martial_arts, src) + + if(LAZYLEN(new_holder.martial_arts) == 1 ? get_style_help() : !(locate(/datum/action/swap_arts) in new_holder.actions)) + var/datum/action/swap_arts/new_action = new(new_holder, src) + new_action.Grant(new_holder) if(LAZYLEN(new_holder.martial_arts) >= 2) - // newly learned martials are preferred to be the active one - add_verb(new_holder, /mob/living/proc/verb_switch_style) // if the active one is locked, this will no-op, which is fine new_holder.switch_style(GET_ACTIVE_MARTIAL_ART(new_holder), src) else if(!active) @@ -369,8 +371,9 @@ UnregisterSignal(old_holder, COMSIG_QDELETING) LAZYREMOVE(old_holder.martial_arts, src) holder = null - if(LAZYLEN(old_holder.martial_arts) <= 1) - remove_verb(old_holder, /mob/living/proc/verb_switch_style) + if(LAZYLEN(old_holder.martial_arts) < 1) //no more arts, we check above to switch style already. + var/datum/action/swap_arts/swap_button = locate() in old_holder.actions + qdel(swap_button) return TRUE /** @@ -379,8 +382,6 @@ /datum/martial_art/proc/activate_style(mob/living/new_holder) SHOULD_CALL_PARENT(TRUE) active = TRUE - if(help_verb) - add_verb(new_holder, help_verb) RegisterSignal(new_holder, COMSIG_LIVING_UNARMED_ATTACK, PROC_REF(unarmed_strike)) RegisterSignal(new_holder, COMSIG_LIVING_GRAB, PROC_REF(attempt_grab)) RegisterSignals(new_holder, list(COMSIG_LIVING_TABLE_SLAMMING, COMSIG_LIVING_TABLE_LIMB_SLAMMING), PROC_REF(smash_table)) @@ -395,8 +396,6 @@ /datum/martial_art/proc/deactivate_style(mob/living/remove_from) SHOULD_CALL_PARENT(TRUE) active = FALSE - if(help_verb) - remove_verb(remove_from, help_verb) UnregisterSignal(remove_from, list(COMSIG_LIVING_UNARMED_ATTACK, COMSIG_LIVING_GRAB, COMSIG_LIVING_TABLE_SLAMMING, COMSIG_LIVING_TABLE_LIMB_SLAMMING)) remove_from.hud_used?.remove_screen_object(HUD_MOB_COMBO) @@ -405,11 +404,7 @@ SIGNAL_HANDLER source.hud_used.add_screen_object(/atom/movable/screen/combo, HUD_MOB_COMBO, HUD_GROUP_INFO, update_screen = TRUE) -/mob/living/proc/verb_switch_style() - set name = "Swap Style" - set desc = "Switch to a different martial arts style." - set category = "IC" - +/mob/living/proc/cycle_style() var/datum/martial_art/current = GET_ACTIVE_MARTIAL_ART(src) var/datum/martial_art/next = GET_NEXT_MARTIAL_ART(src) @@ -417,7 +412,7 @@ to_chat(src, span_warning("You can't stop practicing [current]! It's too ingrained in your muscle memory.")) return - switch_style(GET_ACTIVE_MARTIAL_ART(src), GET_NEXT_MARTIAL_ART(src)) + switch_style(current, next) to_chat(src, span_notice("You stop practicing [current] and start practicing [next].")) /// Deactivates the current martial art and activates the next one. @@ -428,6 +423,9 @@ if(!current_martial.active || next_martial.active) return + var/datum/action/swap_arts/swap_button = locate() in actions + swap_button.current_used_art = next_martial + current_martial.deactivate_style(src) next_martial.activate_style(src) // front of the list with ye @@ -436,3 +434,7 @@ // back of the list with ye LAZYREMOVE(martial_arts, current_martial) LAZYADD(martial_arts, current_martial) + +///To be overwritten for artstyle help. +/datum/martial_art/proc/get_style_help() + return FALSE diff --git a/code/datums/martial/boxing.dm b/code/datums/martial/boxing.dm index 6318b34c4b7..2dc52641649 100644 --- a/code/datums/martial/boxing.dm +++ b/code/datums/martial/boxing.dm @@ -17,7 +17,7 @@ name = "Boxing" id = MARTIALART_BOXING pacifist_style = TRUE - help_verb = /mob/living/proc/boxing_help + help_verb = "Focus on your Form" /// Boolean on whether we are sportsmanlike in our tussling; TRUE means we have restrictions var/honorable_boxer = TRUE /// Can we perform grabs even if it would be dishonorable? @@ -379,22 +379,20 @@ return FALSE return ..() -/mob/living/proc/boxing_help() - set name = "Focus on your Form" - set desc = "You focus on how to make the most of your boxing form." - set category = "Boxing" - to_chat(usr, "You focus on your form, visualizing how best to throw a punch.") +/datum/martial_art/boxing/get_style_help() + . = list() - to_chat(usr, "What moves you perform depend on what mouse buttons you click, and whether the last button clicked matches which hand you have selected when you throw the last punch.") + . += "You focus on your form, visualizing how best to throw a punch." + . += "What moves you perform depend on what mouse buttons you click, and whether the last button clicked matches which hand you have selected when you throw the last punch." - to_chat(usr, "[span_notice("Straight Punch")]: Left Left/Right Right with the matching hand. Regular damage.") - to_chat(usr, "[span_notice("Jab")]: Left Left/Right Right with the opposite hand. Regular damage. If you're blind, you'll make a blind jab instead.") - to_chat(usr, "[span_notice("Left/Right Hook")]: Left Right/Right Left with the matching hand. Does extra damage, but slows your next hit.") - to_chat(usr, "[span_notice("Uppercut")]: Left Right/Right Left with the opposite hand. Has a higher probability to knock out the target, but slows your next hit.") + . += "[span_notice("Straight Punch")]: Left Left/Right Right with the matching hand. Regular damage." + . += "[span_notice("Jab")]: Left Left/Right Right with the opposite hand. Regular damage. If you're blind, you'll make a blind jab instead." + . += "[span_notice("Left/Right Hook")]: Left Right/Right Left with the matching hand. Does extra damage, but slows your next hit." + . += "[span_notice("Uppercut")]: Left Right/Right Left with the opposite hand. Has a higher probability to knock out the target, but slows your next hit." - to_chat(usr, "While in Throw Mode, you can block incoming punches and return a bit of damage back to an attacker. Blocking attacks this way causes you to lose some stamina damage.") - - to_chat(usr, "Your boxing abilities are only able to be used on other boxers.") + . += "While in Throw Mode, you can block incoming punches and return a bit of damage back to an attacker. Blocking attacks this way causes you to lose some stamina damage." + . += "Your boxing abilities are only able to be used on other boxers." + return . // Boxing Variants! @@ -405,25 +403,24 @@ name = "Evil Boxing" id = MARTIALART_EVIL_BOXING pacifist_style = FALSE - help_verb = /mob/living/proc/evil_boxing_help + help_verb = "Focus on Brawling" honorable_boxer = FALSE boxing_traits = list(TRAIT_BOXING_READY, TRAIT_STRENGTH, TRAIT_STIMMED) -/mob/living/proc/evil_boxing_help() - set name = "Focus on Brawling" - set desc = "You ponder how best to rearrange the faces of your enemies." - set category = "Evil Boxing" - to_chat(usr, "You contemplate on the violence ahead, visualizing how best to throw a punch.") +/datum/martial_art/boxing/evil/get_style_help() + . = list() - to_chat(usr, "What moves you perform depend on what mouse buttons you click, and whether the last button clicked matches which hand you have selected when you throw the last punch.") + . += "You contemplate on the violence ahead, visualizing how best to throw a punch." + . += "What moves you perform depend on what mouse buttons you click, and whether the last button clicked matches which hand you have selected when you throw the last punch." - to_chat(usr, "[span_notice("Straight Punch")]: Left Left/Right Right with the matching hand. Regular damage.") - to_chat(usr, "[span_notice("Jab")]: Left Left/Right Right with the opposite hand. Regular damage. If you're blind, you'll make a blind jab instead.") - to_chat(usr, "[span_notice("Left/Right Hook")]: Left Right/Right Left with the matching hand. Does extra damage, but slows your next hit.") - to_chat(usr, "[span_notice("Uppercut")]: Left Right/Right Left with the opposite hand. Has a higher probability to knock out the target, but slows your next hit.") - to_chat(usr, "[span_notice("Sucker Punch")]: Any combination done to a vulnerable target becomes a sucker punch. This could knock them out in one!.") + . += "[span_notice("Straight Punch")]: Left Left/Right Right with the matching hand. Regular damage." + . += "[span_notice("Jab")]: Left Left/Right Right with the opposite hand. Regular damage. If you're blind, you'll make a blind jab instead." + . += "[span_notice("Left/Right Hook")]: Left Right/Right Left with the matching hand. Does extra damage, but slows your next hit." + . += "[span_notice("Uppercut")]: Left Right/Right Left with the opposite hand. Has a higher probability to knock out the target, but slows your next hit." + . += "[span_notice("Sucker Punch")]: Any combination done to a vulnerable target becomes a sucker punch. This could knock them out in one!." - to_chat(usr, "While in Throw Mode, you can block incoming punches and return a bit of damage back to an attacker. Blocking attacks this way causes you to lose some stamina damage.") + . += "While in Throw Mode, you can block incoming punches and return a bit of damage back to an attacker. Blocking attacks this way causes you to lose some stamina damage." + return . /// Hunter Boxing: for the uncaring, completely deranged one-spacer ecological disaster. /// The honor check accepts boxing ready targets, OR various biotypes as valid targets. Uses a special crit effect rather than the standard one (against monsters). @@ -432,7 +429,7 @@ name = "Hunter Boxing" id = MARTIALART_HUNTER_BOXING pacifist_style = FALSE - help_verb = /mob/living/proc/hunter_boxing_help + help_verb = "Focus on the Hunt" default_damage_type = BRUTE boxing_traits = list(TRAIT_BOXING_READY) ignore_grab_restriction = TRUE @@ -442,23 +439,22 @@ var/list/first_word_strike = list("Extinction", "Brutalization", "Explosion", "Adventure", "Thunder", "Lightning", "Sonic", "Atomizing", "Whirlwind", "Tornado", "Shark", "Falcon") var/list/second_word_strike = list(" Punch", " Pawnch", "-punch", " Jab", " Hook", " Fist", " Uppercut", " Straight", " Strike", " Lunge") -/mob/living/proc/hunter_boxing_help() - set name = "Focus on the Hunt" - set desc = "You focus on how to most effectively punch the hell out of another endangered species." - set category = "Hunter Boxing" - to_chat(usr, "You focus on your Fists. You focus on Adventure. You focus on the Hunt.") +/datum/martial_art/boxing/hunter/get_style_help() + . = list() - to_chat(usr, "What moves you perform depend on what mouse buttons you click, and whether the last button clicked matches which hand you have selected when you throw the last punch.") + . += "You focus on your Fists. You focus on Adventure. You focus on the Hunt." + . += "What moves you perform depend on what mouse buttons you click, and whether the last button clicked matches which hand you have selected when you throw the last punch." - to_chat(usr, "[span_notice("Straight Punch")]: Left Left/Right Right with the matching hand. Regular damage.") - to_chat(usr, "[span_notice("Jab")]: Left Left/Right Right with the opposite hand. Regular damage. If you're blind, you'll make a blind jab instead.") - to_chat(usr, "[span_notice("Left/Right Hook")]: Left Right/Right Left with the matching hand. Does extra damage, but slows your next hit.") - to_chat(usr, "[span_notice("Uppercut")]: Left Right/Right Left with the opposite hand. Has a higher probability to critically hit the target, but slows your next hit.") + . += "[span_notice("Straight Punch")]: Left Left/Right Right with the matching hand. Regular damage." + . += "[span_notice("Jab")]: Left Left/Right Right with the opposite hand. Regular damage. If you're blind, you'll make a blind jab instead." + . += "[span_notice("Left/Right Hook")]: Left Right/Right Left with the matching hand. Does extra damage, but slows your next hit." + . += "[span_notice("Uppercut")]: Left Right/Right Left with the opposite hand. Has a higher probability to critically hit the target, but slows your next hit." - to_chat(usr, "While in Throw Mode, you can block incoming punches and return a bit of damage back to an attacker. Blocking attacks this way causes you to lose some stamina damage.") - to_chat(usr, "Stringing together effective combos restores some of your health and deals even more damage.") + . += "While in Throw Mode, you can block incoming punches and return a bit of damage back to an attacker. Blocking attacks this way causes you to lose some stamina damage." + . += "Stringing together effective combos restores some of your health and deals even more damage." - to_chat(usr, "Your hunter boxing abilities are only able to be used on the various flora, fauna and unnatural creatures that reside in this universe. Against normal humanoids, you are just a boxer.") + . += "Your hunter boxing abilities are only able to be used on the various flora, fauna and unnatural creatures that reside in this universe. Against normal humanoids, you are just a boxer." + return . /datum/martial_art/boxing/hunter/honor_check(mob/living/possible_boxer) if(HAS_TRAIT(possible_boxer, TRAIT_BOXING_READY)) diff --git a/code/datums/martial/cqc.dm b/code/datums/martial/cqc.dm index 4e3815a1e5d..46993c93e02 100644 --- a/code/datums/martial/cqc.dm +++ b/code/datums/martial/cqc.dm @@ -7,7 +7,7 @@ /datum/martial_art/cqc name = "CQC" id = MARTIALART_CQC - help_verb = /mob/living/proc/CQC_help + help_verb = "Remember The Basics" smashes_tables = TRUE display_combos = TRUE /// Weakref to a mob we're currently restraining (with grab-grab combo) @@ -342,7 +342,11 @@ if(prob(65) && (defender.stat == CONSCIOUS || !defender.IsParalyzed() || !restraining_mob?.resolve())) var/obj/item/disarmed_item = defender.get_active_held_item() if(disarmed_item && defender.temporarilyRemoveItemFromInventory(disarmed_item)) - attacker.put_in_hands(disarmed_item) + defender.dropItemToGround(disarmed_item) + if(isturf(disarmed_item.loc)) //If it fell on the ground we can take it, otherwise assume it's attached to something. + attacker.put_in_hands(disarmed_item) + else + disarmed_item = null else disarmed_item = null @@ -373,19 +377,19 @@ return MARTIAL_ATTACK_FAIL -/mob/living/proc/CQC_help() - set name = "Remember The Basics" - set desc = "You try to remember some of the basics of CQC." - set category = "CQC" - to_chat(usr, "You try to remember some of the basics of CQC.") +/datum/martial_art/cqc/get_style_help() + . = list() - to_chat(usr, "[span_notice("Slam")]: Grab Punch. Slam opponent into the ground, knocking them down.") - to_chat(usr, "[span_notice("CQC Kick")]: Punch Punch. Knocks opponent away. Knocks out stunned opponents and does stamina damage.") - to_chat(usr, "[span_notice("Restrain")]: Grab Grab. Locks opponents into a restraining position, disarm to knock them out with a chokehold.") - to_chat(usr, "[span_notice("Pressure")]: Shove Grab. Decent stamina damage.") - to_chat(usr, "[span_notice("Consecutive CQC")]: Shove Shove Punch. Mainly offensive move, huge damage and decent stamina damage.") + . += "You try to remember some of the basics of CQC." - to_chat(usr, "In addition, by having your throw mode on when being attacked, you enter an active defense mode where you have a chance to block and sometimes even counter attacks done to you.") + . += "[span_notice("Slam")]: Grab Punch. Slam opponent into the ground, knocking them down." + . += "[span_notice("CQC Kick")]: Punch Punch. Knocks opponent away. Knocks out stunned opponents and does stamina damage." + . += "[span_notice("Restrain")]: Grab Grab. Locks opponents into a restraining position, disarm to knock them out with a chokehold." + . += "[span_notice("Pressure")]: Shove Grab. Decent stamina damage." + . += "[span_notice("Consecutive CQC")]: Shove Shove Punch. Mainly offensive move, huge damage and decent stamina damage." + + . += "In addition, by having your throw mode on when being attacked, you enter an active defense mode where you have a chance to block and sometimes even counter attacks done to you." + return . ///Subtype of CQC. Only used for the chef. /datum/martial_art/cqc/under_siege diff --git a/code/datums/martial/plasma_fist.dm b/code/datums/martial/plasma_fist.dm index ee52fb026b2..d823c3312cf 100644 --- a/code/datums/martial/plasma_fist.dm +++ b/code/datums/martial/plasma_fist.dm @@ -5,7 +5,7 @@ /datum/martial_art/plasma_fist name = "Plasma Fist" id = MARTIALART_PLASMAFIST - help_verb = /mob/living/proc/plasma_fist_help + help_verb = "Recall Teachings" var/nobomb = FALSE var/plasma_power = 1 //starts at a 1, 2, 4 explosion. var/plasma_increment = 1 //how much explosion power gets added per kill (1 = 1, 2, 4. 2 = 2, 4, 8 and so on) @@ -163,18 +163,17 @@ add_to_streak("G", defender) return check_streak(attacker, defender) ? MARTIAL_ATTACK_SUCCESS : MARTIAL_ATTACK_INVALID -/mob/living/proc/plasma_fist_help() - set name = "Recall Teachings" - set desc = "Remember the martial techniques of the Plasma Fist." - set category = "Plasma Fist" +/datum/martial_art/plasma_fist/get_style_help() + . = list() - var/datum/martial_art/plasma_fist/martial = GET_ACTIVE_MARTIAL_ART(src) - to_chat(usr, "You clench your fists and have a flashback of knowledge...") - to_chat(usr, "[span_notice("Tornado Sweep")]: Punch Punch Shove. Repulses opponent and everyone back.") - to_chat(usr, "[span_notice("Throwback")]: Shove Punch Shove. Throws the opponent and an item at them.") - to_chat(usr, "[span_notice("The Plasma Fist")]: Punch Shove Shove Shove Punch. Instantly gibs an opponent.[martial.nobomb ? "" : " Each kill with this grows your [span_notice("Apotheosis")] explosion size."]") + var/datum/martial_art/plasma_fist/martial = GET_ACTIVE_MARTIAL_ART(holder) + . += "You clench your fists and have a flashback of knowledge..." + . += "[span_notice("Tornado Sweep")]: Punch Punch Shove. Repulses opponent and everyone back." + . += "[span_notice("Throwback")]: Shove Punch Shove. Throws the opponent and an item at them." + . += "[span_notice("The Plasma Fist")]: Punch Shove Shove Shove Punch. Instantly gibs an opponent.[martial.nobomb ? "" : " Each kill with this grows your [span_notice("Apotheosis")] explosion size."]" if(!martial.nobomb) - to_chat(usr, "[span_notice("Apotheosis")]: Use [span_notice("The Plasma Fist")] on yourself. Sends you away in a glorious explosion.") + . += "[span_notice("Apotheosis")]: Use [span_notice("The Plasma Fist")] on yourself. Sends you away in a glorious explosion." + return . /obj/effect/temp_visual/plasma_soul diff --git a/code/datums/martial/sleeping_carp.dm b/code/datums/martial/sleeping_carp.dm index b1cb83c8846..589a6975f20 100644 --- a/code/datums/martial/sleeping_carp.dm +++ b/code/datums/martial/sleeping_carp.dm @@ -6,7 +6,7 @@ /datum/martial_art/the_sleeping_carp name = "The Sleeping Carp" id = MARTIALART_SLEEPINGCARP - help_verb = /mob/living/proc/sleeping_carp_help + help_verb = "Recall Teachings" display_combos = TRUE grab_state_modifier = 1 /// List of traits applied to users of this martial art. @@ -374,24 +374,23 @@ return style_factor_points /// Verb added to humans who learn the art of the sleeping carp. -/mob/living/proc/sleeping_carp_help() - set name = "Recall Teachings" - set desc = "Remember the martial techniques of the Sleeping Carp clan." - set category = "Sleeping Carp" +/datum/martial_art/the_sleeping_carp/get_style_help() + . = list() - to_chat(usr, span_info("You retreat inward and recall the teachings of the Sleeping Carp...\n\ - [span_notice("Gnashing Teeth")]: Punch Grab. Violently twists your opponent's arm, dislocating or even shattering bone and forcing them to drop their held items.\n\ - [span_notice("Crashing Wave Kick")]: Punch Shove. Launch your opponent away from you with incredible force!\n\ - [span_notice("Keelhaul")]: Shove Shove. Nonlethally kick an opponent to the floor, knocking them down, discombobulating them and dealing substantial stamina damage. If they're already prone, disarm them as well.\n\ - [span_notice("Kraken Wrack")]: Grab Punch. Deliver a knee jab into the opponent, dealing high stamina damage, as well as briefly stunning them, winding them and making it difficult for them to speak.\n\ - [span_notice("Grabs and Shoves")]: While in combat mode, your typical grab and shove do decent stamina damage, and your grabs harder to break. If you grab someone who has substantial amounts of stamina damage, you knock them out!\n\ - While in combat mode (and not stunned, not a hulk, and not in a mech), you can reflect all projectiles that come your way, sending them back at the people who fired them! \n\ - However, your ability to avoid projectiles is negatively affected when your are burdened by armor, or whenever you are carrying normal-sized or heavier objects in your hands. \n\ - But if you commmit fully to the martial arts lifestyle by wearing martial arts or carp-related regalia, you will feel empowered enough to potentially avoid attacks even from melee weapons or other unarmed combatants. \n\ - Some melee weapons, such as bo starves, spears, short blades, knives, toolboxes, baseball bats and non-blocking small objects are safe to carry without affecting your ability to defend yourself. Exploit this for a tactical advantage. \n\ - Also, you are more resilient against suffering wounds in combat, and your limbs cannot be dismembered. This grants you extra staying power during extended combat, especially against slashing and other bleeding weapons. \n\ - You are not invincible, however- while you may not suffer debilitating wounds often, you must still watch your health and should have appropriate medical supplies for use during downtime. \n\ - In addition, your training has imbued you with a loathing of guns, and you can no longer use them.")) + . += span_info("You retreat inward and recall the teachings of the Sleeping Carp...\n\ + [span_notice("Gnashing Teeth")]: Punch Grab. Violently twists your opponent's arm, dislocating or even shattering bone and forcing them to drop their held items.\n\ + [span_notice("Crashing Wave Kick")]: Punch Shove. Launch your opponent away from you with incredible force!\n\ + [span_notice("Keelhaul")]: Shove Shove. Nonlethally kick an opponent to the floor, knocking them down, discombobulating them and dealing substantial stamina damage. If they're already prone, disarm them as well.\n\ + [span_notice("Kraken Wrack")]: Grab Punch. Deliver a knee jab into the opponent, dealing high stamina damage, as well as briefly stunning them, winding them and making it difficult for them to speak.\n\ + [span_notice("Grabs and Shoves")]: While in combat mode, your typical grab and shove do decent stamina damage, and your grabs harder to break. If you grab someone who has substantial amounts of stamina damage, you knock them out!\n\ + While in combat mode (and not stunned, not a hulk, and not in a mech), you can reflect all projectiles that come your way, sending them back at the people who fired them! \n\ + However, your ability to avoid projectiles is negatively affected when your are burdened by armor, or whenever you are carrying normal-sized or heavier objects in your hands. \n\ + But if you commmit fully to the martial arts lifestyle by wearing martial arts or carp-related regalia, you will feel empowered enough to potentially avoid attacks even from melee weapons or other unarmed combatants. \n\ + Some melee weapons, such as bo starves, spears, short blades, knives, toolboxes, baseball bats and non-blocking small objects are safe to carry without affecting your ability to defend yourself. Exploit this for a tactical advantage. \n\ + Also, you are more resilient against suffering wounds in combat, and your limbs cannot be dismembered. This grants you extra staying power during extended combat, especially against slashing and other bleeding weapons. \n\ + You are not invincible, however- while you may not suffer debilitating wounds often, you must still watch your health and should have appropriate medical supplies for use during downtime. \n\ + In addition, your training has imbued you with a loathing of guns, and you can no longer use them.") + return . /obj/item/staff/bostaff name = "bo staff" diff --git a/code/datums/martial/spiders_bite.dm b/code/datums/martial/spiders_bite.dm index 3ace8bdcb1a..a5d6ddaa369 100644 --- a/code/datums/martial/spiders_bite.dm +++ b/code/datums/martial/spiders_bite.dm @@ -1,7 +1,7 @@ /datum/martial_art/spiders_bite name = "Spider's Bite" id = MARTIALART_SPIDERSBITE - help_verb = /mob/living/proc/spiders_bite_help + help_verb = "Recall Teachings" grab_damage_modifier = 10 grab_escape_chance_modifier = -20 /// REF() to the last mob we kicked @@ -60,13 +60,12 @@ return IS_LEFT_INDEX(martial_artist.active_hand_index) ? BODY_ZONE_L_LEG : BODY_ZONE_R_LEG -/mob/living/proc/spiders_bite_help() - set name = "Recall Teachings" - set desc = "Remember the Spider Bite technique used by the Spider Clan." - set category = "Spider's Bite" +/datum/martial_art/spiders_bite/get_style_help() + . = list() - to_chat(usr, span_info("You retreat inward and recall the Spider Clan's techniques...\n\ + . += span_info("You retreat inward and recall the Spider Clan's techniques...\n\ • Remember, Many Legged Spider: Unarmed attacks against staggered opponents will always be kicks - granting you greater accuracy and damage.\n\ • Remember, Jump and Climb: Right clicking on throw mode will perform a tackle which is far far less likely to fail.\n\ • Remember, Flow of Gravity: Kicking opponents will have a chance to knock their weapons to the floor. The chance increases for each sequential kick.\n\ - • Remember, Wrap in Web: Your grabs will be harder to escape from.")) + • Remember, Wrap in Web: Your grabs will be harder to escape from.") + return . diff --git a/code/datums/material/material_container.dm b/code/datums/material/material_container.dm index 256c1ea4717..927765b0a81 100644 --- a/code/datums/material/material_container.dm +++ b/code/datums/material/material_container.dm @@ -616,7 +616,6 @@ for(var/x in mats) //Loop through all required materials var/wanted = OPTIMAL_COST(mats[x] * coefficient) * multiplier if(!has_enough_of_material(x, wanted))//Not a category, so just check the normal way - testing("didn't have: [x] wanted: [wanted]") return FALSE return TRUE diff --git a/code/datums/materials/_material.dm b/code/datums/materials/_material.dm index 5d34b97c75d..98186d0709f 100644 --- a/code/datums/materials/_material.dm +++ b/code/datums/materials/_material.dm @@ -69,8 +69,10 @@ Simple datum which is instanced once per type and is used for every object of sa var/mat_rust_resistance = RUST_RESISTANCE_ORGANIC /// How likely this mineral is to be found in a boulder during mining. var/mineral_rarity = MATERIAL_RARITY_COMMON - /// How many points per units of ore does this grant? + /// How many points per units of ore does this grant? This is used by ore in the ORM, NOT for boulder machinery due to the automated nature. var/points_per_unit = 1 + /// How many points per unit does this ore grant when processed by a smelter/refinery? + var/points_per_boulder_unit = 1 // Sound/icon stats, not inherited /// Can be used to override the sound items make, lets add some SLOSHing. @@ -218,9 +220,9 @@ Simple datum which is instanced once per type and is used for every object of sa /datum/material/proc/on_throw_impact(obj/item/source, atom/hit_atom, datum/thrownthing/throwing_datum, caught) SIGNAL_HANDLER if (caught) - impact_affect_touch(source, hit_atom, astype(throwing_datum.thrower.resolve(), /mob/living)) + impact_affect_touch(source, hit_atom, astype(throwing_datum.thrower?.resolve(), /mob/living)) else if (!isliving(hit_atom)) // Hit mobs have armor checking - impact_affect_throw_impact(source, hit_atom, astype(throwing_datum.thrower.resolve(), /mob/living)) + impact_affect_throw_impact(source, hit_atom, astype(throwing_datum.thrower?.resolve(), /mob/living)) /datum/material/proc/on_throw_impact_living(obj/item/source, mob/living/target, def_zone, blocked, datum/thrownthing/throwing_datum) SIGNAL_HANDLER @@ -231,7 +233,7 @@ Simple datum which is instanced once per type and is used for every object of sa if (!skin_contact) break - impact_affect_throw_impact(source, target, astype(throwing_datum.thrower.resolve(), /mob/living), def_zone, !!skin_contact) + impact_affect_throw_impact(source, target, astype(throwing_datum.thrower?.resolve(), /mob/living), def_zone, !!skin_contact) /datum/material/proc/impact_affect_touch(obj/item/source, mob/living/user, mob/living/initiator) var/arm_dir = IS_LEFT_INDEX(user.active_hand_index) ? BODY_ZONE_L_ARM : BODY_ZONE_R_ARM diff --git a/code/datums/materials/basemats.dm b/code/datums/materials/basemats.dm index 4284503cede..56c8a4807ba 100644 --- a/code/datums/materials/basemats.dm +++ b/code/datums/materials/basemats.dm @@ -20,6 +20,7 @@ mat_rust_resistance = RUST_RESISTANCE_BASIC mineral_rarity = MATERIAL_RARITY_COMMON points_per_unit = 1 / SHEET_MATERIAL_AMOUNT + points_per_boulder_unit = 1 / SHEET_MATERIAL_AMOUNT minimum_value_override = 0 tradable = TRUE tradable_base_quantity = MATERIAL_QUANTITY_COMMON @@ -57,6 +58,7 @@ tradable_base_quantity = MATERIAL_QUANTITY_COMMON mineral_rarity = MATERIAL_RARITY_COMMON points_per_unit = 1 / SHEET_MATERIAL_AMOUNT + points_per_boulder_unit = 1 / SHEET_MATERIAL_AMOUNT texture_layer_icon_state = "shine" /datum/material/glass/on_accidental_mat_consumption(mob/living/carbon/victim, obj/item/source_item) @@ -99,6 +101,7 @@ tradable_base_quantity = MATERIAL_QUANTITY_UNCOMMON mineral_rarity = MATERIAL_RARITY_SEMIPRECIOUS points_per_unit = 16 / SHEET_MATERIAL_AMOUNT + points_per_boulder_unit = 3.5 / SHEET_MATERIAL_AMOUNT texture_layer_icon_state = "shine" /datum/material/silver/on_accidental_mat_consumption(mob/living/carbon/victim, obj/item/source_item) @@ -130,6 +133,7 @@ tradable_base_quantity = MATERIAL_QUANTITY_RARE mineral_rarity = MATERIAL_RARITY_PRECIOUS points_per_unit = 18 / SHEET_MATERIAL_AMOUNT + points_per_boulder_unit = 4 / SHEET_MATERIAL_AMOUNT texture_layer_icon_state = "shine" /datum/material/gold/on_accidental_mat_consumption(mob/living/carbon/victim, obj/item/source_item) @@ -163,6 +167,7 @@ tradable_base_quantity = MATERIAL_QUANTITY_EXOTIC mineral_rarity = MATERIAL_RARITY_RARE points_per_unit = 50 / SHEET_MATERIAL_AMOUNT + points_per_boulder_unit = 10 / SHEET_MATERIAL_AMOUNT /datum/material/diamond/on_accidental_mat_consumption(mob/living/carbon/victim, obj/item/source_item) . = ..() @@ -195,6 +200,7 @@ tradable_base_quantity = MATERIAL_QUANTITY_RARE mineral_rarity = MATERIAL_RARITY_SEMIPRECIOUS points_per_unit = 30 / SHEET_MATERIAL_AMOUNT + points_per_boulder_unit = 3.5 / SHEET_MATERIAL_AMOUNT /// Adds firestacks on hit (Still needs support to turn into gas on destruction) /datum/material/plasma @@ -219,6 +225,7 @@ value_per_unit = 200 / SHEET_MATERIAL_AMOUNT mineral_rarity = MATERIAL_RARITY_PRECIOUS points_per_unit = 15 / SHEET_MATERIAL_AMOUNT + points_per_boulder_unit = 2 / SHEET_MATERIAL_AMOUNT /datum/material/plasma/on_applied(atom/source, mat_amount, multiplier, from_slot) . = ..() @@ -257,6 +264,7 @@ value_per_unit = 300 / SHEET_MATERIAL_AMOUNT mineral_rarity = MATERIAL_RARITY_RARE points_per_unit = 50 / SHEET_MATERIAL_AMOUNT + points_per_boulder_unit = 10 / SHEET_MATERIAL_AMOUNT tradable = TRUE tradable_base_quantity = MATERIAL_QUANTITY_EXOTIC texture_layer_icon_state = "shine" @@ -305,6 +313,7 @@ value_per_unit = 1000 / SHEET_MATERIAL_AMOUNT mineral_rarity = MATERIAL_RARITY_UNDISCOVERED points_per_unit = 60 / SHEET_MATERIAL_AMOUNT + points_per_boulder_unit = 15 / SHEET_MATERIAL_AMOUNT /datum/material/bananium/on_applied(atom/source, mat_amount, multiplier, from_slot) . = ..() @@ -360,6 +369,7 @@ sheet_type = /obj/item/stack/sheet/mineral/titanium ore_type = /obj/item/stack/ore/titanium value_per_unit = 125 / SHEET_MATERIAL_AMOUNT + points_per_boulder_unit = 3 / SHEET_MATERIAL_AMOUNT tradable = TRUE tradable_base_quantity = MATERIAL_QUANTITY_UNCOMMON mat_rust_resistance = RUST_RESISTANCE_TITANIUM @@ -390,6 +400,7 @@ value_per_unit = 600 / SHEET_MATERIAL_AMOUNT mineral_rarity = MATERIAL_RARITY_UNDISCOVERED points_per_unit = 100 / SHEET_MATERIAL_AMOUNT + points_per_boulder_unit = 20 / SHEET_MATERIAL_AMOUNT /datum/material/runite/on_applied(atom/source, mat_amount, multiplier, from_slot) . = ..() @@ -429,6 +440,7 @@ value_per_unit = 25 / SHEET_MATERIAL_AMOUNT mineral_rarity = MATERIAL_RARITY_UNDISCOVERED // Nobody's found oil on lavaland yet. points_per_unit = 4 / SHEET_MATERIAL_AMOUNT + points_per_boulder_unit = 4 / SHEET_MATERIAL_AMOUNT /// Force decrease and mushy sound effect. (Not yet implemented) /datum/material/biomass @@ -483,6 +495,7 @@ value_per_unit = 500 / SHEET_MATERIAL_AMOUNT mineral_rarity = MATERIAL_RARITY_UNDISCOVERED // Doesn't naturally spawn on lavaland. points_per_unit = 100 / SHEET_MATERIAL_AMOUNT + points_per_boulder_unit = 20 / SHEET_MATERIAL_AMOUNT // If it ever needs it, we'll give it /datum/material/adamantine/on_applied(atom/source, mat_amount, multiplier, from_slot) . = ..() @@ -521,6 +534,7 @@ value_per_unit = 1500 / SHEET_MATERIAL_AMOUNT mineral_rarity = MATERIAL_RARITY_UNDISCOVERED // Doesn't naturally spawn on lavaland. points_per_unit = 100 / SHEET_MATERIAL_AMOUNT + points_per_boulder_unit = 20 / SHEET_MATERIAL_AMOUNT /datum/material/mythril/on_applied(atom/source, mat_amount, multiplier, from_slot) . = ..() @@ -926,3 +940,19 @@ // Oops, all chainsawfish! challenge.register_reward_signals(GLOB.preset_fish_sources[/datum/fish_source/portal/syndicate]) +/datum/material/rock + name = "rock" + desc = "Marble maybe?" + color = "#919191" + mat_flags = MATERIAL_BASIC_RECIPES | MATERIAL_CLASS_RIGID + mat_properties = list( + MATERIAL_DENSITY = 2, + MATERIAL_HARDNESS = 4, + MATERIAL_FLEXIBILITY = 0, + MATERIAL_REFLECTIVITY = 0, + MATERIAL_ELECTRICAL = 0, + MATERIAL_THERMAL = 1, + MATERIAL_CHEMICAL = 0, + MATERIAL_BEAUTY = 0.8, + ) + texture_layer_icon_state = "sand" diff --git a/code/datums/materials/material_slots/generic.dm b/code/datums/materials/material_slots/generic.dm index 971ae28b612..cae828555e9 100644 --- a/code/datums/materials/material_slots/generic.dm +++ b/code/datums/materials/material_slots/generic.dm @@ -61,7 +61,7 @@ /datum/material_slot/weapon_head/proc/on_throw_impact(obj/item/source, atom/hit_atom, datum/thrownthing/throwing_datum, caught) SIGNAL_HANDLER if (!caught && !isliving(hit_atom)) - affect_throw_impact(source, hit_atom, astype(throwing_datum.thrower.resolve(), /mob/living)) + affect_throw_impact(source, hit_atom, astype(throwing_datum.thrower?.resolve(), /mob/living)) /datum/material_slot/weapon_head/proc/on_item_attack(obj/item/source, atom/movable/target, mob/living/user) SIGNAL_HANDLER @@ -89,7 +89,7 @@ if (!skin_contact) break - affect_throw_impact(source, target, astype(throwing_datum.thrower.resolve(), /mob/living), def_zone, !!skin_contact) + affect_throw_impact(source, target, astype(throwing_datum.thrower?.resolve(), /mob/living), def_zone, !!skin_contact) /datum/material_slot/weapon_head/proc/affect_target(obj/item/source, atom/target, mob/living/user, def_zone, skin_contact = TRUE) var/datum/material/source_mat = source.get_material_from_slot(type) @@ -185,7 +185,7 @@ /datum/material_slot/handle/proc/on_throw_impact(obj/item/source, atom/hit_atom, datum/thrownthing/throwing_datum, caught) SIGNAL_HANDLER if (caught) - affect_user(source, hit_atom, astype(throwing_datum.thrower.resolve(), /mob/living)) + affect_user(source, hit_atom, astype(throwing_datum.thrower?.resolve(), /mob/living)) /datum/material_slot/handle/proc/affect_user(obj/item/source, mob/living/user, mob/living/initiator) var/datum/material/source_mat = source.get_material_from_slot(type) diff --git a/code/datums/materials/requirements/_requirement.dm b/code/datums/materials/requirements/_requirement.dm index d23e11c3fb9..3d953098927 100644 --- a/code/datums/materials/requirements/_requirement.dm +++ b/code/datums/materials/requirements/_requirement.dm @@ -3,6 +3,8 @@ abstract_type = /datum/material_requirement /// Flags which materials need to have to pass var/required_flags = NONE + /// Flags which materials need to not have in order to pass + var/blacklisted_flags = NONE /// Minimum property values that materials need to have to pass var/list/property_minimums = null /// Maximum property values that materials need to have to pass @@ -13,6 +15,8 @@ var/list/flag_strings = list() for (var/flag in bitfield_to_list(required_flags)) flag_strings += GLOB.material_flags_to_string[flag] + for (var/flag in bitfield_to_list(blacklisted_flags)) + flag_strings += "not [GLOB.material_flags_to_string[flag]]" if (!length(property_minimums) && !length(property_maximums)) return "[capitalize(english_list(flag_strings, and_text = " or "))] material" @@ -29,37 +33,28 @@ return "[capitalize(english_list(flag_strings, and_text = " or "))] material with [english_list(prop_reqs)]" /datum/material_requirement/proc/valid_material(datum/material/material) - if (required_flags > 0 && !(material.mat_flags & required_flags)) + if (required_flags && !(material.mat_flags & required_flags)) return FALSE - if (required_flags < 0 && (material.mat_flags & (-required_flags))) + if (blacklisted_flags && (material.mat_flags & blacklisted_flags)) return FALSE for (var/prop_id, min_val in property_minimums) if (material.get_property(prop_id) < min_val) return FALSE + for (var/prop_id, max_val in property_maximums) if (material.get_property(prop_id) > max_val) return FALSE + return TRUE // Actual requirement datums /datum/material_requirement/armor_material required_flags = ITEM_MATERIAL_CLASSES - property_minimums = list( - MATERIAL_HARDNESS = 2, - ) - property_maximums = list( - MATERIAL_FLEXIBILITY = 5, - ) /datum/material_requirement/solid_material - property_minimums = list( - MATERIAL_HARDNESS = 2, - ) - property_maximums = list( - MATERIAL_FLEXIBILITY = 5, - ) + blacklisted_flags = MATERIAL_CLASS_AMORPHOUS /datum/material_requirement/rigid_material required_flags = MATERIAL_CLASS_RIGID diff --git a/code/datums/mind/_mind.dm b/code/datums/mind/_mind.dm index 24a27afa051..8b31bd676ef 100644 --- a/code/datums/mind/_mind.dm +++ b/code/datums/mind/_mind.dm @@ -490,6 +490,7 @@ if(G.can_reenter_corpse || even_if_they_cant_reenter) return G break + return null /datum/mind/proc/grab_ghost(force) var/mob/dead/observer/G = get_ghost(even_if_they_cant_reenter = force) diff --git a/code/datums/mind/antag.dm b/code/datums/mind/antag.dm index 312f6838577..579bc02bc10 100644 --- a/code/datums/mind/antag.dm +++ b/code/datums/mind/antag.dm @@ -114,18 +114,21 @@ * * antag_datum: the antag datum of the uplink owner, for storing it in antag memory. optional! */ /datum/mind/proc/give_uplink(silent = FALSE, datum/antagonist/antag_datum) - if(isnull(current)) + if(!isliving(current)) return var/mob/living/carbon/human/traitor_mob = current if (!istype(traitor_mob)) - return + var/datum/status_effect/shapechange_mob/shapeshift = current.has_status_effect(/datum/status_effect/shapechange_mob) + if (!ishuman(shapeshift?.caster_mob)) + return + traitor_mob = shapeshift.caster_mob var/obj/item/uplink_loc - var/uplink_spawn_location = traitor_mob.client?.prefs?.read_preference(/datum/preference/choiced/uplink_location) + var/uplink_spawn_location = current.client?.prefs?.read_preference(/datum/preference/choiced/uplink_location) var/cant_speak = (HAS_TRAIT(traitor_mob, TRAIT_MUTE) || is_mime_job(assigned_role)) if(uplink_spawn_location == UPLINK_RADIO && cant_speak) if(!silent) - to_chat(traitor_mob, span_warning("You have been deemed ineligible for a radio uplink. Supplying standard uplink instead.")) + to_chat(current, span_warning("You have been deemed ineligible for a radio uplink. Supplying standard uplink instead.")) uplink_spawn_location = UPLINK_PDA if(uplink_spawn_location != UPLINK_IMPLANT) @@ -137,7 +140,7 @@ var/obj/item/implant/uplink/starting/new_implant = new(traitor_mob) new_implant.implant(traitor_mob, null, silent = TRUE) if(!silent) - to_chat(traitor_mob, span_boldnotice("Your Syndicate Uplink has been cunningly implanted in you, for a small TC fee. Simply trigger the uplink to access it.")) + to_chat(current, span_boldnotice("Your Syndicate Uplink has been cunningly implanted in you, for a small TC fee. Simply trigger the uplink to access it.")) add_memory(/datum/memory/key/traitor_uplink/implant, uplink_loc = "implant") return new_implant @@ -147,7 +150,7 @@ if(!new_uplink) CRASH("Uplink creation failed.") new_uplink.setup_unlock_code() - new_uplink.uplink_handler.owner = traitor_mob.mind + new_uplink.uplink_handler.owner = src new_uplink.uplink_handler.assigned_role = traitor_mob.mind.assigned_role.title new_uplink.uplink_handler.assigned_species = traitor_mob.dna.species.id @@ -167,7 +170,7 @@ new_uplink.unlock_text = unlock_text if(!silent) - to_chat(traitor_mob, span_boldnotice(unlock_text)) + to_chat(current, span_boldnotice(unlock_text)) if(antag_datum) antag_datum.antag_memory += new_uplink.unlock_note + "
" return . @@ -185,6 +188,7 @@ var/datum/antagonist/nukeop/converter = creator.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE) var/datum/antagonist/nukeop/N = new() N.send_to_spawnpoint = FALSE + N.give_bonus_tc = FALSE N.nukeop_outfit = null add_antag_datum(N,converter.nuke_team) diff --git a/code/datums/mocking/client.dm b/code/datums/mocking/client.dm index 5c684f08521..79611ef0e9d 100644 --- a/code/datums/mocking/client.dm +++ b/code/datums/mocking/client.dm @@ -83,7 +83,7 @@ /datum/client_interface/proc/get_award_status(achievement_type, mob/user, value = 1) return FALSE -/datum/client_interface/proc/set_fullscreen(logging_in = FALSE) +/datum/client_interface/proc/set_fullscreen() return TRUE /datum/client_interface/proc/check_drag_proximity(atom/dragging, atom/over, src_location, over_location, src_control, over_control, params) diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm index 665857195f1..60f6b09aed1 100644 --- a/code/datums/mood_events/generic_negative_events.dm +++ b/code/datums/mood_events/generic_negative_events.dm @@ -655,3 +655,8 @@ description = "Man, getting jabbed with that thing really sucked." mood_change = -4 timeout = 5 MINUTES + +/datum/mood_event/gizmo_negative + description = "I hear a voice whispering, and I don't like what it says." + mood_change = -3 + timeout = 30 SECONDS diff --git a/code/datums/mood_events/generic_positive_events.dm b/code/datums/mood_events/generic_positive_events.dm index ab581040bf9..7364493f853 100644 --- a/code/datums/mood_events/generic_positive_events.dm +++ b/code/datums/mood_events/generic_positive_events.dm @@ -701,3 +701,8 @@ description = "What a night! I can't wait to do it all again!" mood_change = 2 timeout = 10 MINUTES + +/datum/mood_event/gizmo_positive + description = "I hear a voice whispering kind words in my ear!" + mood_change = 3 + timeout = 30 SECONDS diff --git a/code/datums/move_manager.dm b/code/datums/move_manager.dm index 23ddcbecdb7..8b74eb1fe14 100644 --- a/code/datums/move_manager.dm +++ b/code/datums/move_manager.dm @@ -88,7 +88,7 @@ GLOBAL_DATUM_INIT(move_manager, /datum/move_manager, new) return //Give up if(existing_loop?.compare_loops(arglist(args.Copy(2)))) - return //it already exists stop trying to make the same moveloop + return existing_loop //it already exists stop trying to make the same moveloop var/datum/move_loop/new_loop = new loop_type(src, subsystem, parent, priority, flags, extra_info) //Pass the mob to move and ourselves in via new var/list/arguments = args.Copy(6) //Just send the args we've not already dealt with diff --git a/code/datums/mutations/_mutations.dm b/code/datums/mutations/_mutations.dm index 4f47db0b487..48155e0804c 100644 --- a/code/datums/mutations/_mutations.dm +++ b/code/datums/mutations/_mutations.dm @@ -89,9 +89,8 @@ var/list/valid_chrom_list = list() /// List of traits that are added or removed by the mutation with GENETIC_TRAIT source. var/list/mutation_traits - -/datum/mutation/New() - . = ..() + /// if TRUE admins get alerted when someone force-injects someone else with this mutation + var/warn_admins_on_inject = FALSE /datum/mutation/Destroy() power_path = null diff --git a/code/datums/mutations/body.dm b/code/datums/mutations/body.dm index 66a2cf8d7e5..f587e85dd60 100644 --- a/code/datums/mutations/body.dm +++ b/code/datums/mutations/body.dm @@ -269,6 +269,7 @@ instability = NEGATIVE_STABILITY_MAJOR // mmmonky remove_on_aheal = FALSE locked = TRUE //Species specific, keep out of actual gene pool + warn_admins_on_inject = TRUE var/datum/species/original_species = /datum/species/human var/original_name @@ -556,6 +557,7 @@ difficulty = 12 //pretty good for traitors quality = NEGATIVE //holy shit no eyes or tongue or ears text_gain_indication = span_warning("Something feels off.") + warn_admins_on_inject = TRUE /datum/mutation/headless/on_acquiring() . = ..() diff --git a/code/datums/mutations/touch.dm b/code/datums/mutations/touch.dm index 7a91cc390e8..8ce75e746c5 100644 --- a/code/datums/mutations/touch.dm +++ b/code/datums/mutations/touch.dm @@ -88,8 +88,8 @@ quality = POSITIVE locked = FALSE difficulty = 16 - text_gain_indication = span_notice("Your hand feels blessed!") - text_lose_indication = span_notice("Your hand feels secular once more.") + text_gain_indication = span_notice("Your hands feel blessed!") + text_lose_indication = span_notice("Your hands no longer feel blessed.") power_path = /datum/action/cooldown/spell/touch/lay_on_hands instability = POSITIVE_INSTABILITY_MAJOR energy_coeff = 1 @@ -124,7 +124,7 @@ hand_path = /obj/item/melee/touch_attack/lay_on_hands draw_message = span_notice("You ready your hand to transfer injuries to yourself.") drop_message = span_notice("You lower your hand.") - /// Multiplies the amount healed. + /// Multiplies the amount healed (or damage dealt, in the case of a smite). var/heal_multiplier = 1 /// Multiplies the incoming pain from healing. (Halved with synchronizer chromosome) var/pain_multiplier = 1 @@ -140,7 +140,7 @@ if(!.) return . var/obj/item/bodypart/transfer_limb = cast_on.get_active_hand() - if(IS_ROBOTIC_LIMB(transfer_limb)) + if(!IS_ORGANIC_LIMB(transfer_limb)) to_chat(cast_on, span_notice("You fail to channel your mending powers through your inorganic hand.")) return FALSE @@ -255,43 +255,45 @@ // Did the transfer work? . = FALSE - // Get the hurtguy's limbs and the mendicant's limbs to attempt a 1-1 transfer. - var/list/hurt_limbs = hurtguy.get_damaged_bodyparts(1, 1, BODYTYPE_ORGANIC) + hurtguy.get_wounded_bodyparts(BODYTYPE_ORGANIC) - var/list/mendicant_organic_limbs = list() - for(var/obj/item/bodypart/possible_limb in mendicant.get_bodyparts()) - if(IS_ORGANIC_LIMB(possible_limb)) - mendicant_organic_limbs += possible_limb - - // If we have no organic available limbs just give up. - if(!length(mendicant_organic_limbs)) - mendicant.balloon_alert(mendicant, "no organic limbs!") - return . - if(!length(hurt_limbs)) - hurtguy.balloon_alert(mendicant, "no damaged organic limbs!") - return . // Counter to make sure we don't take too much from separate limbs - var/total_damage_healed = 0 - // Transfer damage from one limb to the mendicant's counterpart. - for(var/obj/item/bodypart/affected_limb as anything in hurt_limbs) + var/healing_budget = 35 * heal_multiplier + // Transfer damage from each limb to the mendicant's counterpart. + for(var/obj/item/bodypart/affected_limb as anything in hurtguy.get_bodyparts()) + if(!(affected_limb.bodytype & BODYTYPE_ORGANIC)) + continue var/obj/item/bodypart/mendicant_transfer_limb = mendicant.get_bodypart(affected_limb.body_zone) - // If the compared limb isn't organic, skip it and pick a random one. - if(!(mendicant_transfer_limb in mendicant_organic_limbs)) - mendicant_transfer_limb = pick(mendicant_organic_limbs) - - // Transfer at most 35 damage, by default. - var/brute_damage = min(affected_limb.brute_dam, 35 * heal_multiplier) - // no double dipping - var/burn_damage = min(affected_limb.burn_dam, (35 * heal_multiplier) - brute_damage) - if((brute_damage || burn_damage) && total_damage_healed < (35 * heal_multiplier)) - total_damage_healed += brute_damage + burn_damage + var/list/mendicant_organic_limbs = list() + for(var/obj/item/bodypart/possible_limb in mendicant.get_bodyparts(include_stumps = TRUE)) // Keeping this here in case stumps can store damage in the future + if(IS_ORGANIC_LIMB(possible_limb) && !IS_STUMP(possible_limb)) // No stumps are currently organic, this is futureproofing. + mendicant_organic_limbs += possible_limb + // Spread the healing between brute and burn + var/affected_limb_damage = affected_limb.brute_dam + affected_limb.burn_dam + var/brute_damage = 0 + var/burn_damage = 0 + if(healing_budget >= affected_limb_damage) + healing_budget -= affected_limb_damage + brute_damage = affected_limb.brute_dam + burn_damage = affected_limb.burn_dam + else + if(affected_limb.brute_dam > affected_limb.burn_dam) + burn_damage = min(affected_limb.burn_dam, healing_budget/2) + brute_damage = healing_budget - burn_damage + else + brute_damage = min(affected_limb.burn_dam, healing_budget/2) + burn_damage = healing_budget - brute_damage + healing_budget = 0 + if((brute_damage || burn_damage)) . = TRUE var/brute_taken = brute_damage * pain_multiplier var/burn_taken = burn_damage * pain_multiplier // Heal! affected_limb.heal_damage(brute_damage, burn_damage, required_bodytype = BODYTYPE_ORGANIC) // Hurt! - mendicant_transfer_limb.receive_damage(brute_taken, burn_taken, forced = TRUE, wound_bonus = CANT_WOUND) + if((mendicant_transfer_limb in mendicant_organic_limbs)) + mendicant_transfer_limb.receive_damage(brute_taken, burn_taken, forced = TRUE, wound_bonus = CANT_WOUND) + else // spread damage if we're trying to heal a bodypart we have no organic parallel of + mendicant.take_overall_damage(brute_damage, burn_damage, required_bodytype = BODYTYPE_ORGANIC) // Force light wounds onto you. for(var/datum/wound/iter_wound as anything in affected_limb.wounds) @@ -300,21 +302,26 @@ if(prob(50 * heal_multiplier)) continue if(WOUND_SEVERITY_CRITICAL) - if(heal_multiplier < 1.5) // need buffs to transfer crit wounds + if(heal_multiplier < 1.5 && prob(30 * heal_multiplier)) // need buffs to transfer crit wounds continue . = TRUE iter_wound.remove_wound() iter_wound.apply_wound(mendicant_transfer_limb) + if(!healing_budget) + break + if(!CAN_HAVE_BLOOD(mendicant) || !CAN_HAVE_BLOOD(hurtguy)) return . // 10% base var/max_blood_transfer = (BLOOD_VOLUME_NORMAL * 0.10) * heal_multiplier + var/hurtguy_blood = hurtguy.get_blood_volume() // Too little blood - if(hurtguy.get_blood_volume() < BLOOD_VOLUME_NORMAL) + if(hurtguy_blood < BLOOD_VOLUME_NORMAL) + var/amount_to_transfer = min(max_blood_transfer, BLOOD_VOLUME_NORMAL - hurtguy_blood) // We ignore incompatibility here. - var/blood_transferred = mendicant.transfer_blood_to(hurtguy, max_blood_transfer, ignore_low_blood = TRUE, ignore_incompatibility = TRUE) + var/blood_transferred = mendicant.transfer_blood_to(hurtguy, amount_to_transfer, ignore_low_blood = TRUE, ignore_incompatibility = TRUE) if(!blood_transferred) return @@ -329,11 +336,12 @@ to_chat(hurtguy, span_notice("Your veins feel thicker!")) return - if(hurtguy.get_blood_volume() < BLOOD_VOLUME_EXCESS) + if(hurtguy_blood < BLOOD_VOLUME_MAXIMUM) return + var/amount_to_receive = min(max_blood_transfer, hurtguy_blood - BLOOD_VOLUME_MAXIMUM) // We ignore incompatibility here. - var/blood_received = hurtguy.transfer_blood_to(mendicant, hurtguy.get_blood_volume() - BLOOD_VOLUME_EXCESS, ignore_incompatibility = TRUE) + var/blood_received = hurtguy.transfer_blood_to(mendicant, amount_to_receive, ignore_incompatibility = TRUE) if(!blood_received) return @@ -346,6 +354,8 @@ to_chat(mendicant, span_notice("Your veins swell and itch!")) else to_chat(mendicant, span_notice("Your veins swell!")) + if(!.) + mendicant.balloon_alert(hurtguy, "no damaged organic limbs!") /datum/action/cooldown/spell/touch/lay_on_hands/proc/determine_if_this_hurts_instead(mob/living/carbon/mendicant, mob/living/hurtguy) diff --git a/code/datums/mutations/void_magnet.dm b/code/datums/mutations/void_magnet.dm index 122fab4e198..aef24d19629 100644 --- a/code/datums/mutations/void_magnet.dm +++ b/code/datums/mutations/void_magnet.dm @@ -60,7 +60,7 @@ /datum/action/cooldown/spell/void/cursed/proc/on_life(mob/living/source, seconds_per_tick) SIGNAL_HANDLER - if(!isliving(source) || HAS_TRAIT(source, TRAIT_STASIS) || source.stat == DEAD || HAS_TRAIT(source, TRAIT_NO_TRANSFORM)) + if(HAS_TRAIT(source, TRAIT_STASIS) || source.stat == DEAD) return if(!is_valid_target(source)) diff --git a/code/datums/quirks/negative_quirks/addict.dm b/code/datums/quirks/negative_quirks/addict.dm index f2dc41e84a2..843dc492866 100644 --- a/code/datums/quirks/negative_quirks/addict.dm +++ b/code/datums/quirks/negative_quirks/addict.dm @@ -95,11 +95,11 @@ associated_typepath = /datum/quirk/item_quirk/addict/junkie customization_options = list(/datum/preference/choiced/junkie) -/datum/quirk/item_quirk/addict/junkie/add_unique(client/client_source) - - var/addiction = client_source?.prefs.read_preference(/datum/preference/choiced/junkie) - if(addiction && (addiction != "Random")) - reagent_type = GLOB.possible_junkie_addictions[addiction] +/datum/quirk/item_quirk/addict/junkie/add_to_holder(mob/living/new_holder, quirk_transfer = FALSE, client/client_source, unique = TRUE, announce = TRUE) + if(!quirk_transfer) + var/addiction = client_source?.prefs.read_preference(/datum/preference/choiced/junkie) + if(addiction && (addiction != "Random")) + reagent_type = GLOB.possible_junkie_addictions[addiction] return ..() /datum/quirk/item_quirk/addict/remove() diff --git a/code/datums/quirks/negative_quirks/asthma.dm b/code/datums/quirks/negative_quirks/asthma.dm index 1c4e53640f9..31532b2a3fe 100644 --- a/code/datums/quirks/negative_quirks/asthma.dm +++ b/code/datums/quirks/negative_quirks/asthma.dm @@ -84,10 +84,7 @@ /datum/quirk/item_quirk/asthma/proc/on_life(mob/living/source, seconds_per_tick) SIGNAL_HANDLER - if (quirk_holder.stat == DEAD) - return - - if (HAS_TRAIT(quirk_holder, TRAIT_STASIS) || HAS_TRAIT(quirk_holder, TRAIT_NO_TRANSFORM)) + if (quirk_holder.stat == DEAD || HAS_TRAIT(quirk_holder, TRAIT_STASIS)) return var/obj/item/organ/lungs/holder_lungs = quirk_holder.get_organ_slot(ORGAN_SLOT_LUNGS) diff --git a/code/datums/quirks/negative_quirks/limper.dm b/code/datums/quirks/negative_quirks/limper.dm new file mode 100644 index 00000000000..e272bd2c712 --- /dev/null +++ b/code/datums/quirks/negative_quirks/limper.dm @@ -0,0 +1,30 @@ +/datum/quirk/item_quirk/limper + name = "Limper" + desc = "You have a pronounced limp when you walk. This will slow you down considerably. Good thing you brought your cane." + icon = FA_ICON_PERSON_CANE + gain_text = span_danger("Your leg feels a bit weak.") + lose_text = span_notice("Your legs feel normal again.") + medical_record_text = "Patient appears to suffer from a weakness in the leg." + value = -6 + hardcore_value = 3 + quirk_flags = QUIRK_HUMAN_ONLY + + mail_goodies = list( + /obj/item/cane, + /obj/item/cane/crutch, + /obj/item/cane/white, + ) + +/datum/quirk/item_quirk/limper/add_unique(client/client_source) + give_item_to_holder(new /obj/item/cane(get_turf(quirk_holder)), list( + LOCATION_HANDS, + LOCATION_BACKPACK, + )) + return + +/datum/quirk/item_quirk/limper/add(client/client_source) + quirk_holder.apply_status_effect(/datum/status_effect/limp/quirk) + +/datum/quirk/item_quirk/limper/remove(client/client_source) + quirk_holder.remove_status_effect(/datum/status_effect/limp/quirk) + diff --git a/code/datums/quirks/positive_quirks/spacer.dm b/code/datums/quirks/positive_quirks/spacer.dm index c448244e7c7..d41f6e5536c 100644 --- a/code/datums/quirks/positive_quirks/spacer.dm +++ b/code/datums/quirks/positive_quirks/spacer.dm @@ -1,5 +1,6 @@ #define LAST_STATE_PLANET "on_planet" #define LAST_STATE_SPACE "in_space" +#define LAST_STATE_NOGRAV "in_nograv" /datum/quirk/spacer_born name = "Spacer" @@ -17,7 +18,7 @@ /obj/item/reagent_containers/applicator/pill/gravitum, ) /// How high spacers get bumped up to - var/modded_height = HUMAN_HEIGHT_TALLER + var/modded_height = HUMAN_HEIGHT_TALLEST /// How long on a planet before we get averse effects var/planet_period = 3 MINUTES /// TimerID for time spend on a planet @@ -26,9 +27,14 @@ var/recover_period = 1 MINUTES /// TimerID for time spend in space VAR_FINAL/recovering_timer - /// Determines the last state we were in ([LAST_STATE_PLANET] or [LAST_STATE_SPACE]) + /// Determines the last state we were in ([LAST_STATE_PLANET], [LAST_STATE_SPACE], or [LAST_STATE_NOGRAV]) VAR_FINAL/last_state + /// Modifier to damage taken from pressure/cold + VAR_FINAL/damage_mod = 0.66 + /// Modifier to drift speed in zero G + VAR_FINAL/drift_mod = 0.75 + /datum/quirk/spacer_born/add(client/client_source) if(isdummy(quirk_holder)) return @@ -38,19 +44,20 @@ // It won't really make sense to walk 3 feet and then suddenly gain / lose gravity sickness. // If I'm proven wrong, swap this to use Moved. RegisterSignal(quirk_holder, COMSIG_MOVABLE_Z_CHANGED, PROC_REF(spacer_moved)) + RegisterSignal(quirk_holder, COMSIG_LIVING_GRAVITY_CHANGED, PROC_REF(spacer_grav)) // Yes, it's assumed for planetary maps that you start at gravity sickness. - check_z(quirk_holder, skip_timers = TRUE) + update_effects(quirk_holder, skip_timers = TRUE) // drift slightly faster through zero G - quirk_holder.inertia_move_multiplier *= 0.8 + quirk_holder.inertia_move_multiplier_passive *= drift_mod var/mob/living/carbon/human/human_quirker = quirk_holder //BUBBER EDIT REMOVAL START //human_quirker.set_mob_height(modded_height) //BUBBER EDIT REMOVAL END - human_quirker.physiology.pressure_mod *= 0.8 - human_quirker.physiology.cold_mod *= 0.8 + human_quirker.physiology.pressure_mod *= damage_mod + human_quirker.physiology.cold_mod *= damage_mod /datum/quirk/spacer_born/post_add() var/on_a_planet = SSmapping.is_planetary() @@ -71,11 +78,12 @@ /datum/quirk/spacer_born/remove() UnregisterSignal(quirk_holder, COMSIG_MOVABLE_Z_CHANGED) + UnregisterSignal(quirk_holder, COMSIG_LIVING_GRAVITY_CHANGED) if(QDELING(quirk_holder)) return - quirk_holder.inertia_move_multiplier /= 0.8 + quirk_holder.inertia_move_multiplier_passive /= drift_mod quirk_holder.clear_mood_event("spacer") quirk_holder.remove_movespeed_modifier(/datum/movespeed_modifier/spacer) quirk_holder.remove_status_effect(/datum/status_effect/spacer) @@ -84,14 +92,20 @@ //BUBBER EDIT REMOVAL START //human_quirker.set_mob_height(HUMAN_HEIGHT_MEDIUM) //BUBBER EDIT REMOVAL END - human_quirker.physiology.pressure_mod /= 0.8 - human_quirker.physiology.cold_mod /= 0.8 + human_quirker.physiology.pressure_mod /= damage_mod + human_quirker.physiology.cold_mod /= damage_mod /// Check on Z change whether we should start or stop timers /datum/quirk/spacer_born/proc/spacer_moved(mob/living/source, turf/old_turf, turf/new_turf, same_z_layer) SIGNAL_HANDLER - check_z(source) + update_effects(source) + +/// Check on gravity change whether we should start or stop timers +/datum/quirk/spacer_born/proc/spacer_grav(mob/living/source, new_gravity, old_gravity) + SIGNAL_HANDLER + + update_effects(source) /** * Used to check if we should start or stop timers based on the quirk holder's location. @@ -99,9 +113,12 @@ * * afflicted - the mob arriving / same as quirk holder * * skip_timers - if TRUE, this is being done instantly / should not have feedback (such as in init) */ -/datum/quirk/spacer_born/proc/check_z(mob/living/spacer, skip_timers = FALSE) +/datum/quirk/spacer_born/proc/update_effects(mob/living/spacer, skip_timers = FALSE) if(is_on_a_planet(spacer)) - on_planet(spacer, skip_timers) + if(spacer.has_gravity()) + on_planet(spacer, skip_timers) + else + has_nograv(spacer, skip_timers) else in_space(spacer, skip_timers) @@ -172,9 +189,10 @@ deltimer(planetside_timer) planetside_timer = null + var/was_nograv = last_state == LAST_STATE_NOGRAV last_state = LAST_STATE_SPACE - if(skip_timers) + if(skip_timers || was_nograv) comfortably_in_space(afflicted, TRUE) return @@ -185,7 +203,7 @@ to_chat(afflicted, span_green("You start feeling better now that you're back in space.")) /** - * Ran when living back in space for a long enough period. + * Ran when living back in space, or just no-grav in general, for a long enough period. * * * afflicted - the mob arriving / same as quirk holder * * skip_timers - if TRUE, this is being done instantly / should not have feedback (such as in init) @@ -201,5 +219,33 @@ if(!skip_timers) to_chat(afflicted, span_green("You feel better.")) +// On a planet but has no gravity + +/** + * Ran when we are on a planet while having no gravity. + * + * * afflicted - the mob arriving / same as quirk holder + * * skip_timers - if TRUE, this is being done instantly / should not have feedback (such as in init) + */ +/datum/quirk/spacer_born/proc/has_nograv(mob/living/afflicted, skip_timers = FALSE) + if(last_state == LAST_STATE_NOGRAV) + return + if(planetside_timer) + deltimer(planetside_timer) + planetside_timer = null + if(recovering_timer) + deltimer(recovering_timer) + recovering_timer = null + + var/was_in_space = last_state == LAST_STATE_SPACE + last_state = LAST_STATE_NOGRAV + + afflicted.apply_status_effect(/datum/status_effect/spacer/gravity_wellness) + afflicted.add_mood_event("spacer", /datum/mood_event/spacer/on_planet/low_grav) + afflicted.add_movespeed_modifier(/datum/movespeed_modifier/spacer/in_space) + if(!skip_timers && !was_in_space) + to_chat(afflicted, span_green("You feel like you're back in space!")) + #undef LAST_STATE_PLANET #undef LAST_STATE_SPACE +#undef LAST_STATE_NOGRAV diff --git a/code/datums/records/crime.dm b/code/datums/records/crime.dm index 729b85c56b8..a403923ab80 100644 --- a/code/datums/records/crime.dm +++ b/code/datums/records/crime.dm @@ -19,7 +19,7 @@ src.author = author src.details = details src.name = name - src.time = station_time_timestamp() + src.time = round_timestamp() /datum/crime/citation /// Fine for the crime diff --git a/code/datums/records/manifest.dm b/code/datums/records/manifest.dm index 00c41459b48..4b399dbe0f4 100644 --- a/code/datums/records/manifest.dm +++ b/code/datums/records/manifest.dm @@ -133,7 +133,7 @@ GLOBAL_DATUM_INIT(manifest, /datum/manifest, new) character_appearance = character_appearance, dna_string = record_dna.unique_enzymes, fingerprint = md5(record_dna.unique_identity), - gender = person_gender, + gender = person.gender, initial_rank = assignment, name = person.real_name, rank = chosen_assignment, // SKYRAT EDIT - Alt job titles - ORIGINAL: rank = assignment, diff --git a/code/datums/records/record.dm b/code/datums/records/record.dm index 04f3205a755..c34ac664a10 100644 --- a/code/datums/records/record.dm +++ b/code/datums/records/record.dm @@ -159,7 +159,7 @@ character_appearance, dna_string = "Unknown", fingerprint = "?????", - gender = "Other", + gender = "neuter", initial_rank = "Unassigned", name = "Unknown", rank = "Unassigned", diff --git a/code/datums/request_message.dm b/code/datums/request_message.dm index 18feada06cb..c88433e5ca9 100644 --- a/code/datums/request_message.dm +++ b/code/datums/request_message.dm @@ -21,7 +21,7 @@ /datum/request_message/New(data) sender_department = data["sender_department"] - received_time = station_time_timestamp() + received_time = round_timestamp() content = data["message"] message_verified_by = data["verified"] message_stamped_by = data["stamped"] diff --git a/code/datums/ruins/icemoon.dm b/code/datums/ruins/icemoon.dm index 94c269792a1..bf0b661d6f6 100644 --- a/code/datums/ruins/icemoon.dm +++ b/code/datums/ruins/icemoon.dm @@ -86,6 +86,15 @@ description = "A manufacturing and packaging facility producing insulated gloves." suffix = "icemoon_surface_gloves.dmm" +/datum/map_template/ruin/icemoon/shoe_facotry + name = "Ice-Ruin Shoe Factory" + id = "shoe_factory" + description = "An abandoned shoe factory." + prefix = "_maps/RandomRuins/AnywhereRuins/" + suffix = "shoe_factory.dmm" + allow_duplicates = FALSE + cost = 10 + // above and below ground together /datum/map_template/ruin/icemoon/entemology diff --git a/code/datums/ruins/lavaland.dm b/code/datums/ruins/lavaland.dm index 299cbf6cdf9..e19158a5c6d 100644 --- a/code/datums/ruins/lavaland.dm +++ b/code/datums/ruins/lavaland.dm @@ -334,3 +334,12 @@ description = "They launched too early" suffix = "lavaland_surface_crashsite.dmm" allow_duplicates = FALSE + +/datum/map_template/ruin/lavaland/shoe_facotry + name = "Lava-Ruin Shoe Factory" + id = "shoe_factory" + description = "An abandoned shoe factory." + prefix = "_maps/RandomRuins/AnywhereRuins/" + suffix = "shoe_factory.dmm" + allow_duplicates = FALSE + cost = 10 diff --git a/code/datums/sprite_accessories.dm b/code/datums/sprite_accessories.dm index acc125d1208..22b7c850b74 100644 --- a/code/datums/sprite_accessories.dm +++ b/code/datums/sprite_accessories.dm @@ -998,7 +998,7 @@ GLOBAL_LIST_EMPTY(blended_hair_icons_cache) /datum/sprite_accessory/gradient/none name = SPRITE_ACCESSORY_NONE - icon_state = "none" + icon_state = SPRITE_ACCESSORY_NONE /datum/sprite_accessory/gradient/full name = "Full" @@ -1245,10 +1245,11 @@ GLOBAL_LIST_EMPTY(blended_hair_icons_cache) /datum/sprite_accessory/facial_hair/shaved name = "Shaved" - icon_state = null + icon_state = SPRITE_ACCESSORY_NONE gender = NEUTER /datum/sprite_accessory/clothing + abstract_type = /datum/sprite_accessory/clothing /// Allows you to specify a greyscale config var/greyscale_config /// Icon state in the digitigrade template file to use if the wearer is digitigrade. @@ -1257,6 +1258,14 @@ GLOBAL_LIST_EMPTY(blended_hair_icons_cache) /// Color pallete for static colored underwear, like hearts. /// Used so greyscale copies can have the same palette. var/greyscale_colors = "#FFFFFF#FFFFFF#FFFFFF" + /// The layer this sprite accessory should render on + var/layer = BODY_LAYER + /// What kind of gender shaping this sprite accessory should use (in case your sprite gets a weird missing pixel in the center) + var/female_sprite_flags = FEMALE_UNIFORM_FULL + +/// Override to return a different icon state given a bodytype or physique +/datum/sprite_accessory/clothing/proc/get_icon_state(physique, bodyshape) + return icon_state /** * Generate an appearance from this clothing datum @@ -1267,18 +1276,22 @@ GLOBAL_LIST_EMPTY(blended_hair_icons_cache) */ /datum/sprite_accessory/clothing/proc/make_appearance(color = COLOR_WHITE, physique = MALE, bodyshape = BODYSHAPE_HUMANOID) var/static/list/cached_icons = list() - var/use_female = physique == FEMALE + var/use_female = physique == FEMALE && female_sprite_flags var/use_digi = digi_icon_state && (bodyshape & BODYSHAPE_DIGITIGRADE) + var/female_sprite_flags_to_use = female_sprite_flags + var/icon_state_to_use = get_icon_state(physique, bodyshape) + if(use_digi && female_sprite_flags_to_use) + female_sprite_flags_to_use = FEMALE_UNIFORM_TOP_ONLY // No bottom gender shaping for the digi legs - var/key = "[icon_state]-[greyscale_config || "ng"]-[use_female]-[use_digi]-[greyscale_colors]" + var/key = "[icon_state_to_use]-[greyscale_config || "ng"]-[use_female]-[use_digi]-[greyscale_colors]" var/mutable_appearance/result if(cached_icons[key]) // it's already cached result = mutable_appearance(icon(cached_icons[key])) else if(greyscale_config || use_female || use_digi) // icon ops ahead - var/icon/created = icon(greyscale_config ? SSgreyscale.GetColoredIconByType(greyscale_config, greyscale_colors) : icon, icon_state) + var/icon/created = icon(greyscale_config ? SSgreyscale.GetColoredIconByType(greyscale_config, greyscale_colors) : icon, icon_state_to_use) if(use_female) - created = wear_female_version(icon_state, icon, FEMALE_UNIFORM_FULL) + created = wear_female_version(icon_state_to_use, icon, female_sprite_flags_to_use) if(use_digi) var/icon/replacement = icon(SSgreyscale.GetColoredIconByType(/datum/greyscale_config/digitigrade_underwear, greyscale_colors), digi_icon_state) created = replace_icon_legs(created, replacement) @@ -1289,7 +1302,7 @@ GLOBAL_LIST_EMPTY(blended_hair_icons_cache) else // no caching necessary result = mutable_appearance(icon, icon_state) - result.layer = -BODY_LAYER + result.layer = -layer result.color = use_static ? null : color return result @@ -1303,6 +1316,7 @@ GLOBAL_LIST_EMPTY(blended_hair_icons_cache) icon = 'icons/mob/clothing/underwear.dmi' use_static = FALSE em_block = TRUE + abstract_type = /datum/sprite_accessory/clothing/underwear //MALE UNDERWEAR /datum/sprite_accessory/clothing/underwear/nude @@ -1500,6 +1514,7 @@ GLOBAL_LIST_EMPTY(blended_hair_icons_cache) /datum/sprite_accessory/clothing/undershirt icon = 'icons/mob/clothing/underwear.dmi' em_block = TRUE + abstract_type = /datum/sprite_accessory/clothing/undershirt /datum/sprite_accessory/clothing/undershirt/nude name = "Nude" @@ -1790,6 +1805,7 @@ GLOBAL_LIST_EMPTY(blended_hair_icons_cache) /datum/sprite_accessory/clothing/socks icon = 'icons/mob/clothing/underwear.dmi' em_block = TRUE + abstract_type = /datum/sprite_accessory/clothing/socks /datum/sprite_accessory/clothing/socks/nude name = "Nude" diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm index c3734662080..b8730620c2d 100644 --- a/code/datums/status_effects/buffs.dm +++ b/code/datums/status_effects/buffs.dm @@ -732,3 +732,24 @@ /datum/status_effect/rev_resilience/on_remove() to_chat(owner, span_notice("You feel your surge of revolutionary zeal fade. You hope you don't get shot in the foot...")) owner.remove_traits(list(TRAIT_HARDLY_WOUNDED,TRAIT_ANALGESIA,TRAIT_FEARLESS), TRAIT_STATUS_EFFECT(id)) + +//status effect granted when taking attack damage while metabolizing synthpax +/datum/status_effect/synthpax_immunity + id = "synthpax_immune" + duration = 5 SECONDS + status_type = STATUS_EFFECT_REFRESH + alert_type = null + +/datum/status_effect/synthpax_immunity/on_creation(mob/living/new_owner, duration = 5 SECONDS) + src.duration = duration + return ..() + +/datum/status_effect/synthpax_immunity/on_apply() + ADD_TRAIT(owner, TRAIT_SYNTHPAX_IMMUNE, TRAIT_STATUS_EFFECT(id)) + REMOVE_TRAIT(owner, TRAIT_PACIFISM, METABOLIZATION_TRAIT(/datum/reagent/pax/peaceborg)) + return TRUE + +/datum/status_effect/synthpax_immunity/on_remove() + REMOVE_TRAIT(owner, TRAIT_SYNTHPAX_IMMUNE, TRAIT_STATUS_EFFECT(id)) + if(owner.reagents.has_reagent(/datum/reagent/pax/peaceborg)) + ADD_TRAIT(owner, TRAIT_PACIFISM, METABOLIZATION_TRAIT(/datum/reagent/pax/peaceborg)) diff --git a/code/datums/status_effects/cuffed_item.dm b/code/datums/status_effects/cuffed_item.dm index 4711af1cb01..297666efc75 100644 --- a/code/datums/status_effects/cuffed_item.dm +++ b/code/datums/status_effects/cuffed_item.dm @@ -14,47 +14,80 @@ var/obj/item/cuffed ///Reference to the pair of handcuffs used to bind the item var/obj/item/restraints/handcuffs/cuffs + ///Reference to the bodypart we're cuffed to + var/obj/item/bodypart/arm/cuffed_to + ///Reference to the component managing the link between the mob and the item + VAR_PRIVATE/datum/component/chained_together/link_effect /datum/status_effect/cuffed_item/on_creation(mob/living/new_owner, obj/item/cuffed, obj/item/restraints/handcuffs/cuffs) src.cuffed = cuffed src.cuffs = cuffs . = ..() //throws the alert and all + if(QDELETED(src)) + return linked_alert.update_appearance(UPDATE_OVERLAYS) /datum/status_effect/cuffed_item/on_apply() - if(HAS_TRAIT_FROM(cuffed, TRAIT_NODROP, CUFFED_ITEM_TRAIT)) - qdel(src) - return FALSE owner.temporarilyRemoveItemFromInventory(cuffs, force = TRUE) - if(!owner.is_holding(cuffed) && !owner.put_in_hands(cuffed)) + cuffed_to = owner.get_inactive_hand() + if(isnull(cuffed_to) || !update_link()) owner.put_in_hands(cuffs) qdel(src) return FALSE - ADD_TRAIT(cuffed, TRAIT_NODROP, CUFFED_ITEM_TRAIT) - - RegisterSignals(cuffed, list(COMSIG_ITEM_DROPPED, COMSIG_MOVABLE_MOVED, COMSIG_QDELETING), PROC_REF(on_displaced)) + RegisterSignals(cuffed, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED, COMSIG_MOVABLE_MOVED), PROC_REF(check_for_link)) + RegisterSignal(cuffed, COMSIG_QDELETING, PROC_REF(cleanup_effect)) RegisterSignal(cuffed, COMSIG_ATOM_UPDATE_APPEARANCE, PROC_REF(on_item_update_appearance)) RegisterSignal(cuffed, COMSIG_ATOM_EXAMINE, PROC_REF(cuffed_reminder)) RegisterSignal(cuffed, COMSIG_TOPIC, PROC_REF(topic_handler)) RegisterSignal(cuffed, COMSIG_ITEM_GET_STRIPPABLE_ALT_ACTIONS, PROC_REF(get_strippable_action)) RegisterSignal(cuffed, COMSIG_ITEM_STRIPPABLE_ALT_ACTION, PROC_REF(do_strippable_action)) + RegisterSignal(cuffed, COMSIG_ITEM_PRE_STORAGE_INSERTION, PROC_REF(block_storage_insert)) + RegisterSignal(cuffed, COMSIG_ITEM_PRE_CUFFED_TO_MOB, PROC_REF(block_item_cuff)) - RegisterSignals(cuffs, list(COMSIG_ITEM_EQUIPPED, COMSIG_MOVABLE_MOVED, COMSIG_QDELETING), PROC_REF(on_displaced)) + RegisterSignals(cuffs, list(COMSIG_ITEM_EQUIPPED, COMSIG_QDELETING, COMSIG_MOVABLE_MOVED), PROC_REF(cleanup_effect)) RegisterSignal(cuffs, COMSIG_ATOM_UPDATE_APPEARANCE, PROC_REF(on_item_update_appearance)) + cuffed_to.set_speed_modifiers(cuffed_to.interaction_modifier + 0.25, cuffed_to.click_cd_modifier + 0.25) + RegisterSignal(cuffed_to, COMSIG_QDELETING, PROC_REF(cleanup_effect)) + RegisterSignal(cuffed_to, COMSIG_BODYPART_REMOVED, PROC_REF(cuffed_to_removed)) + RegisterSignal(owner, COMSIG_ATOM_EXAMINE_MORE, PROC_REF(on_examine_more)) - owner.log_message("bound [src] to themselves with restraints", LOG_GAME) + owner.log_message("bound [cuffed] to [owner.p_themselves()] with restraints", LOG_GAME) + SSblackbox.record_feedback("tally", "cuffed_item", 1, cuffed.type) return TRUE /datum/status_effect/cuffed_item/on_remove() //Prevent possible recursions from these signals - UnregisterSignal(cuffed, list(COMSIG_ITEM_DROPPED, COMSIG_MOVABLE_MOVED, COMSIG_QDELETING)) - UnregisterSignal(cuffs, list(COMSIG_ITEM_EQUIPPED, COMSIG_MOVABLE_MOVED, COMSIG_QDELETING)) - - REMOVE_TRAIT(cuffed, TRAIT_NODROP, CUFFED_ITEM_TRAIT) + UnregisterSignal(cuffed, list( + COMSIG_ATOM_EXAMINE, + COMSIG_ATOM_UPDATE_APPEARANCE, + COMSIG_ITEM_PRE_CUFFED_TO_MOB, + COMSIG_ITEM_DROPPED, + COMSIG_ITEM_EQUIPPED, + COMSIG_ITEM_GET_STRIPPABLE_ALT_ACTIONS, + COMSIG_ITEM_PRE_STORAGE_INSERTION, + COMSIG_ITEM_STRIPPABLE_ALT_ACTION, + COMSIG_MOVABLE_MOVED, + COMSIG_QDELETING, + COMSIG_TOPIC, + )) + UnregisterSignal(cuffs, list( + COMSIG_ATOM_UPDATE_APPEARANCE, + COMSIG_ITEM_EQUIPPED, + COMSIG_MOVABLE_MOVED, + COMSIG_QDELETING, + )) + UnregisterSignal(cuffed_to, list( + COMSIG_BODYPART_REMOVED, + COMSIG_QDELETING, + )) + UnregisterSignal(owner, list( + COMSIG_ATOM_EXAMINE_MORE, + COMSIG_CARBON_POST_ATTACH_LIMB, + )) cuffed = null if(!QDELETED(cuffs)) @@ -63,14 +96,117 @@ cuffs.forceMove(owner.drop_location()) cuffs = null + cuffed_to.set_speed_modifiers(cuffed_to.interaction_modifier - 0.25, cuffed_to.click_cd_modifier - 0.25) + cuffed_to = null + + break_leash() + ///Called when someone examines the owner twice, so they can know if someone has a cuffed item /datum/status_effect/cuffed_item/proc/on_examine_more(datum/source, mob/user, list/examine_list) SIGNAL_HANDLER - examine_list += span_warning("[cuffed.examine_title(user)] is bound to [owner.p_their()] [owner.get_held_index_name(owner.get_held_index_of_item(cuffed))] by [cuffs.examine_title(user)]") + examine_list += span_warning("There's [cuffed.examine_title(user)] bound to [owner.p_their()] \ + [cuffed_to.plaintext_zone] by [cuffs.examine_title(user)].") + +/// What happens if the limb we're cuffed to is removed? +/datum/status_effect/cuffed_item/proc/cuffed_to_removed(datum/source, mob/living/carbon/owner, special) + SIGNAL_HANDLER + // if special we will just wait for the new limb + if(special) + UnregisterSignal(cuffed_to, list(COMSIG_QDELETING, COMSIG_BODYPART_REMOVED)) + cuffed_to.set_speed_modifiers(cuffed_to.interaction_modifier - 0.25, cuffed_to.click_cd_modifier - 0.25) + cuffed_to = null + RegisterSignal(owner, COMSIG_CARBON_POST_ATTACH_LIMB, PROC_REF(new_cuffed_to_attached)) + return + // otherwise we wipe the effect + qdel(src) + +/// Specifically if our cuffed limb is removed "specially", change it to the newly applied arm +/datum/status_effect/cuffed_item/proc/new_cuffed_to_attached(datum/source, obj/item/bodypart/limb, special) + SIGNAL_HANDLER + + if(!istype(limb, /obj/item/bodypart/arm)) + return + + cuffed_to = limb + cuffed_to.set_speed_modifiers(cuffed_to.interaction_modifier + 0.25, cuffed_to.click_cd_modifier + 0.25) + RegisterSignal(cuffed_to, COMSIG_QDELETING, PROC_REF(cleanup_effect)) + RegisterSignal(cuffed_to, COMSIG_BODYPART_REMOVED, PROC_REF(cuffed_to_removed)) + UnregisterSignal(owner, COMSIG_CARBON_POST_ATTACH_LIMB) + +/// Check if we need to spawn the tether effect or not +/datum/status_effect/cuffed_item/proc/check_for_link(...) + SIGNAL_HANDLER + if(!update_link()) + qdel(src) + +/// Updates our link and beam effect based on our state +/// Returns TRUE if we are in a valid link state, FALSE otherwise +/datum/status_effect/cuffed_item/proc/update_link() + // when held, we need no tether + if(cuffed.loc == owner) + return break_leash() + + // when on the ground, init a tether between item <-> owner + if(isturf(cuffed.loc)) + return init_leash(cuffed) + + // when being picked up by something else, init a tether between grabber <-> owner + if(ismovable(cuffed.loc) && isturf(cuffed.loc.loc)) + return init_leash(cuffed.loc) + + // we have no idea where it is... + return FALSE + +/// Inits the leash and beam effect to the given target, cleaning up old ones if necessary +/datum/status_effect/cuffed_item/proc/init_leash(atom/movable/leash_to) + if(link_effect) + if(link_effect.parent == leash_to) + return TRUE + break_leash() + + link_effect = leash_to.AddComponentFrom(REF(src), /datum/component/chained_together, chained_to = owner) + if(!QDELETED(link_effect)) + return TRUE + + // chain component failed to apply + if(ismob(leash_to)) + var/mob/leash_to_mob = leash_to + addtimer(CALLBACK(src, PROC_REF(eject_item), leash_to_mob), 1) + return TRUE + + return FALSE + +/datum/status_effect/cuffed_item/proc/break_leash() + link_effect?.parent.RemoveComponentSource(REF(src), /datum/component/chained_together) + if(QDELETED(link_effect)) + link_effect = null + return TRUE + +// Delayed unequip after an invalid pickup. This sucks but I can't think of a better way around due to move order shenanigans +/datum/status_effect/cuffed_item/proc/eject_item(mob/leash_to_mob) + if(QDELETED(src) || cuffed.loc != leash_to_mob) + return + if(!leash_to_mob.dropItemToGround(cuffed)) + qdel(src) + return + to_chat(leash_to_mob, span_warning("[cuffs] binding [cuffed] to [owner] tugs it out of your grasp!")) + +/// Stops it from being stored anywhere +/datum/status_effect/cuffed_item/proc/block_storage_insert(obj/item/source, atom/target_storage, mob/user, force, messages) + SIGNAL_HANDLER + if(messages) + target_storage.balloon_alert(user, "can't store [source.name] while cuffed!") + return BLOCK_STORAGE_INSERT + +/// Stops double cuff +/datum/status_effect/cuffed_item/proc/block_item_cuff(obj/item/source, mob/cuffer, obj/item/cuffs) + SIGNAL_HANDLER + source.balloon_alert(cuffer, "cuffed to someone else!") + return BLOCK_ITEM_CUFF ///What happens if one of the items is moved away from the mob -/datum/status_effect/cuffed_item/proc/on_displaced(datum/source) +/datum/status_effect/cuffed_item/proc/cleanup_effect(datum/source) SIGNAL_HANDLER qdel(src) @@ -128,9 +264,10 @@ log_combat(user, owner, "removed restraints binding [cuffed] to") var/obj/item/restraints/handcuffs/ref_cuffs = cuffs + var/mob/living/ref_owner = owner ref_cuffs.forceMove(owner.drop_location()) //This will cause the status effect to delete itself, which unsets the 'cuffs' var user.put_in_hands(ref_cuffs) - owner.balloon_alert(user, "cuffs removed from item") + ref_owner.balloon_alert(user, "cuffs removed from item") return TRUE @@ -162,3 +299,55 @@ if(.) var/datum/status_effect/cuffed_item/effect = attached_effect effect?.try_remove_cuffs(owner) + +// Chains two movable to be adjacent to each other. YMMV using this +/datum/component/chained_together + dupe_mode = COMPONENT_DUPE_SOURCES + /// Weakref to the thing we're chained to + var/datum/weakref/chained_to_weakref + // Tracks the various things we apply to whatever we are cuffed to for cleanup + VAR_PRIVATE/datum/component/leash/link_effect + VAR_PRIVATE/datum/component/tug_towards/tug_effect + VAR_PRIVATE/datum/beam/beam_effect + +/datum/component/chained_together/on_source_add(source, atom/movable/chained_to) + // more sources are only allowed if they're chaining to the same thing + // having something linked to two different things is not supported now, and will break horribly + return chained_to_weakref?.resolve() == chained_to ? ..() : COMPONENT_REDUNDANT + +/datum/component/chained_together/Initialize(atom/movable/chained_to) + if(!ismovable(parent) || !ismovable(chained_to)) + return COMPONENT_INCOMPATIBLE + + chained_to_weakref = WEAKREF(chained_to) + var/atom/movable/movable_parent = parent + link_effect = movable_parent.AddComponent(/datum/component/leash, owner = chained_to, distance = 1) + tug_effect = movable_parent.AddComponent(/datum/component/tug_towards, tugging_to = chained_to, strength = 0.66) + beam_effect = movable_parent.Beam(chained_to, "chain") + RegisterSignal(link_effect, COMSIG_QDELETING, PROC_REF(delete_self)) + RegisterSignal(tug_effect, COMSIG_QDELETING, PROC_REF(delete_self)) + RegisterSignal(beam_effect, COMSIG_QDELETING, PROC_REF(recreate_beam)) + +/datum/component/chained_together/Destroy() + UnregisterSignal(beam_effect, COMSIG_QDELETING) + UnregisterSignal(link_effect, COMSIG_QDELETING) + UnregisterSignal(tug_effect, COMSIG_QDELETING) + if(!QDELETED(link_effect)) + QDEL_NULL(link_effect) + if(!QDELETED(tug_effect)) + QDEL_NULL(tug_effect) + if(!QDELETED(beam_effect)) + QDEL_NULL(beam_effect) + return ..() + +/datum/component/chained_together/proc/recreate_beam(datum/beam/source) + SIGNAL_HANDLER + + UnregisterSignal(beam_effect, COMSIG_QDELETING) + var/atom/movable/movable_parent = parent + beam_effect = movable_parent.Beam(chained_to_weakref.resolve(), "chain") + RegisterSignal(beam_effect, COMSIG_QDELETING, PROC_REF(recreate_beam)) + +/datum/component/chained_together/proc/delete_self(datum/source) + SIGNAL_HANDLER + qdel(src) diff --git a/code/datums/status_effects/debuffs/debuffs.dm b/code/datums/status_effects/debuffs/debuffs.dm index 53fefde4dc4..59d76c40a67 100644 --- a/code/datums/status_effects/debuffs/debuffs.dm +++ b/code/datums/status_effects/debuffs/debuffs.dm @@ -289,7 +289,7 @@ var/delta = world.time - last_dead_time var/new_timeofdeath = owner.timeofdeath + delta owner.timeofdeath = new_timeofdeath - owner.station_timestamp_timeofdeath = station_time_timestamp(wtime=new_timeofdeath) + owner.station_timestamp_timeofdeath = round_timestamp(wtime=new_timeofdeath) last_dead_time = null if(owner.stat == DEAD) last_dead_time = world.time diff --git a/code/datums/status_effects/debuffs/dna_transformation.dm b/code/datums/status_effects/debuffs/dna_transformation.dm index 76f6cdd9fb0..1ec9848322b 100644 --- a/code/datums/status_effects/debuffs/dna_transformation.dm +++ b/code/datums/status_effects/debuffs/dna_transformation.dm @@ -5,10 +5,12 @@ tick_interval = STATUS_EFFECT_NO_TICK duration = 1 MINUTES // set in on creation, this just needs to be any value to process alert_type = null + /// Flags used to determine what all we're copying over + VAR_PROTECTED/copy_dna_flags = COPY_DNA_SPECIES /// A reference to a COPY of the DNA that the mob will be transformed into. - var/datum/dna/new_dna + VAR_PRIVATE/datum/dna/new_dna /// A reference to a COPY of the DNA of the mob prior to transformation. - var/datum/dna/old_dna + VAR_PRIVATE/datum/dna/old_dna /datum/status_effect/temporary_transformation/Destroy() . = ..() // parent must be called first, so we clear DNA refs AFTER transforming back... yeah i know @@ -16,10 +18,14 @@ QDEL_NULL(old_dna) /datum/status_effect/temporary_transformation/on_creation(mob/living/new_owner, new_duration = 1 MINUTES, datum/dna/dna_to_copy) + if(!iscarbon(new_owner) || isnull(dna_to_copy)) + qdel(src) + return + src.duration = new_duration src.new_dna = new() src.old_dna = new() - dna_to_copy.copy_dna(new_dna) + init_dna(new_owner, dna_to_copy) return ..() /datum/status_effect/temporary_transformation/on_apply() @@ -30,16 +36,8 @@ if(!transforming.has_dna()) return FALSE - // Save the old DNA - transforming.dna.copy_dna(old_dna) - // Makes them into the new DNA - transforming.visual_only_organs = TRUE // SKYRAT EDIT ADDITION - Customization - new_dna.copy_dna(transforming.dna, COPY_DNA_SPECIES) - transforming.visual_only_organs = initial(transforming.visual_only_organs) // SKYRAT EDIT ADDITION - Customization - transforming.real_name = new_dna.real_name - transforming.name = transforming.get_visible_name() - transforming.updateappearance(mutcolor_update = TRUE) - transforming.domutcheck() + save_dna() + apply_dna() return TRUE /datum/status_effect/temporary_transformation/on_remove() @@ -47,7 +45,7 @@ if(!QDELING(owner)) // Don't really need to do appearance stuff if we're being deleted transforming.visual_only_organs = TRUE // SKYRAT EDIT ADDITION - Customization - old_dna.copy_dna(transforming.dna, COPY_DNA_SPECIES) + old_dna.copy_dna(transforming.dna, copy_dna_flags) transforming.visual_only_organs = initial(transforming.visual_only_organs) // SKYRAT EDIT ADDITION - Customization transforming.updateappearance(mutcolor_update = TRUE) transforming.domutcheck() @@ -55,6 +53,24 @@ transforming.real_name = old_dna.real_name // Name is fine though transforming.name = transforming.get_visible_name() +/// Called when initializing the DNA that the mob is transforming into +/datum/status_effect/temporary_transformation/proc/init_dna(mob/living/carbon/new_owner, datum/dna/dna_to_copy) + dna_to_copy.copy_dna(new_dna, copy_dna_flags) + +/// Called when saving the mob's DNA before transformation +/datum/status_effect/temporary_transformation/proc/save_dna() + var/mob/living/carbon/transforming = owner + transforming.dna.copy_dna(old_dna, copy_dna_flags) + +/// Applies the DNA to the mob +/datum/status_effect/temporary_transformation/proc/apply_dna() + var/mob/living/carbon/transforming = owner + new_dna.copy_dna(transforming.dna, copy_dna_flags) + transforming.real_name = new_dna.real_name + transforming.name = transforming.get_visible_name() + transforming.updateappearance(mutcolor_update = TRUE) + transforming.domutcheck() + /datum/status_effect/temporary_transformation/trans_sting /// Tracks the time left on the effect when the owner last died. Used to pause the effect. var/time_before_pause = -1 @@ -93,3 +109,35 @@ else if(time_before_pause != -1) duration = time_before_pause time_before_pause = -1 + +/datum/status_effect/temporary_transformation/dna_injector + id = "temp_dna_injector_transformation" + status_type = STATUS_EFFECT_MULTIPLE + copy_dna_flags = NONE // no touching species or mutations + +// when initting dna, any unset fields are copied from the mob's dna (so nothing changes effectively) +/datum/status_effect/temporary_transformation/dna_injector/init_dna(mob/living/carbon/new_owner, datum/dna/dna_to_copy) + . = ..() + new_dna.real_name ||= new_owner.dna.real_name + new_dna.unique_enzymes ||= new_owner.dna.unique_enzymes + new_dna.unique_features ||= new_owner.dna.unique_features + new_dna.unique_identity ||= new_owner.dna.unique_identity + new_dna.blood_type ||= new_owner.dna.blood_type + // just to put something there, it'll get updated if UF does anyways + new_dna.features = new_owner.dna.features.Copy() + +// ensure secondary transformation make a copy of the original dna (to prevent latter effects that expire earlier from returning to the wrong dna) +/datum/status_effect/temporary_transformation/dna_injector/save_dna() + for(var/datum/status_effect/temporary_transformation/dna_injector/other_effect in owner.status_effects) + other_effect.old_dna.copy_dna(src.old_dna, copy_dna_flags) + return + + return ..() + +// when the effect ends, see if there's any other active effects, and re-apply them if necessary +/datum/status_effect/temporary_transformation/dna_injector/on_remove() + . = ..() + if(QDELING(owner)) + return + for(var/datum/status_effect/temporary_transformation/dna_injector/other_effect in owner.status_effects) + other_effect.apply_dna() diff --git a/code/datums/status_effects/debuffs/slime/slime_leech.dm b/code/datums/status_effects/debuffs/slime/slime_leech.dm index 0df86b15130..5c7b7567d55 100644 --- a/code/datums/status_effects/debuffs/slime/slime_leech.dm +++ b/code/datums/status_effects/debuffs/slime/slime_leech.dm @@ -41,7 +41,10 @@ our_slime = null /datum/status_effect/slime_leech/tick(seconds_between_ticks) - if(our_slime.stat != CONSCIOUS) + if(QDELETED(our_slime)) + qdel(src) + return + if(our_slime.stat != CONSCIOUS || !owner) our_slime.stop_feeding(silent = TRUE) return diff --git a/code/datums/status_effects/debuffs/spacer.dm b/code/datums/status_effects/debuffs/spacer.dm index 6f970eafac9..7fa342370e2 100644 --- a/code/datums/status_effects/debuffs/spacer.dm +++ b/code/datums/status_effects/debuffs/spacer.dm @@ -18,33 +18,58 @@ // The good side (being in space) /datum/status_effect/spacer/gravity_wellness alert_type = null - tick_interval = 3 SECONDS + tick_interval = 1 SECONDS /// How much disgust to heal per tick - var/disgust_healing_per_tick = 1.5 - /// How much of stamina damage to heal per tick when we've been in nograv for a while - var/stamina_heal_per_tick = 3 + var/disgust_healing_per_second = 0.5 + /// How much of stamina damage to heal per tick when we've been in nograv for a while. + var/stamina_heal_per_second = 4 /// How many seconds of stuns to reduce per tick when we've been in nograv for a while - var/stun_heal_per_tick = 3 SECONDS + var/stun_heal_per_second = 2 SECONDS + /// How much to reduce incoming knockdown effects while in nograv for a while + var/knockdown_multiplier = 0.75 /// Tracks how long we've been in no gravity VAR_FINAL/seconds_in_nograv = 0 SECONDS + /// Tracks if we've applied knockdown modifier reduction to the mob + VAR_FINAL/knockdown_mod_applied = FALSE /datum/status_effect/spacer/gravity_wellness/tick(seconds_between_ticks) var/in_nograv = !owner.has_gravity() - var/nograv_mod = in_nograv ? 1 : 0.5 - owner.adjust_disgust(-1 * disgust_healing_per_tick * nograv_mod) + var/nograv_mod = in_nograv ? 2 : 0.5 + owner.adjust_disgust(-1 * nograv_mod * disgust_healing_per_second * seconds_between_ticks) if(!in_nograv) seconds_in_nograv = 0 SECONDS + if(knockdown_mod_applied) + remove_knockdown_mod() return seconds_in_nograv += (seconds_between_ticks * 0.1) - if(seconds_in_nograv >= 3 MINUTES) - // This has some interesting side effects with gravitum or similar negating effects that may be worth nothing - owner.adjust_stamina_loss(-1 * stamina_heal_per_tick) - owner.AdjustAllImmobility(-1 * stun_heal_per_tick) - // For comparison: Ephedrine heals 4 stamina per tick / 2 per second - // and Nicotine heals 5 seconds of stun per tick / 2.5 per second + if(seconds_in_nograv >= 1 MINUTES) + // With 4 stamina healing per second you'd get out of stamcrit in 6 seconds instead of the usual 10 + owner.adjust_stamina_loss(-1 * stamina_heal_per_second * seconds_between_ticks) + if(seconds_in_nograv >= 10 SECONDS) + owner.AdjustAllImmobility(-1 * stun_heal_per_second * seconds_between_ticks) + if(!knockdown_mod_applied) + apply_knockdown_mod() + +/datum/status_effect/spacer/gravity_wellness/on_remove() + . = ..() + remove_knockdown_mod() + +/datum/status_effect/spacer/gravity_wellness/proc/apply_knockdown_mod() + if(knockdown_mod_applied || !ishuman(owner)) + return + var/mob/living/carbon/human/the_spacer = owner + the_spacer.physiology.knockdown_mod *= knockdown_multiplier + knockdown_mod_applied = TRUE + +/datum/status_effect/spacer/gravity_wellness/proc/remove_knockdown_mod() + if(!knockdown_mod_applied || !ishuman(owner)) + return + var/mob/living/carbon/human/the_spacer = owner + the_spacer.physiology.knockdown_mod /= knockdown_multiplier + knockdown_mod_applied = FALSE // The bad side (being on a planet) /datum/status_effect/spacer/gravity_sickness @@ -105,13 +130,27 @@ description = "I'm stationed on a planet. I'd love to be back in space." mood_change = -3 +/datum/mood_event/spacer/on_planet/low_grav + description = "This feels like I'm back home!" + mood_change = 3 + +/datum/mood_event/spacer/on_planet/low_grav/add_effects(...) + . = ..() + addtimer(CALLBACK(src, PROC_REF(lower_mood_bonus)), 5 MINUTES, TIMER_DELETE_ME) + +/datum/mood_event/spacer/on_planet/low_grav/proc/lower_mood_bonus() + mood_change -= 1 + owner.mob_mood.update_mood() + if(mood_change > 1) + addtimer(CALLBACK(src, PROC_REF(lower_mood_bonus)), 5 MINUTES, TIMER_DELETE_ME) + /datum/movespeed_modifier/spacer id = "spacer" /datum/movespeed_modifier/spacer/in_space movetypes = FLOATING blacklisted_movetypes = FLYING - multiplicative_slowdown = -0.1 + multiplicative_slowdown = -0.15 /datum/movespeed_modifier/spacer/on_planet movetypes = GROUND|FLYING @@ -122,4 +161,4 @@ multiplicative_slowdown = 0.5 /datum/movespeed_modifier/spacer/on_planet/nerfed - multiplicative_slowdown = 0.25 + multiplicative_slowdown = 0.15 diff --git a/code/datums/status_effects/neutral.dm b/code/datums/status_effects/neutral.dm index d5989f91a7e..9ccc6e3d333 100644 --- a/code/datums/status_effects/neutral.dm +++ b/code/datums/status_effects/neutral.dm @@ -891,3 +891,28 @@ owner.add_mood_event("[id]_[moodlet_type]", moodlet_type) else owner.clear_mood_event("[id]_[moodlet_type]") + +/datum/status_effect/admin_esp + id = "admin_esp" + duration = STATUS_EFFECT_PERMANENT + tick_interval = STATUS_EFFECT_NO_TICK + status_type = STATUS_EFFECT_UNIQUE + alert_type = null + /// What the mob's see_invisible should be once this status effect is removed + VAR_PRIVATE/real_invis_see + +/datum/status_effect/admin_esp/on_apply() + real_invis_see = owner.see_invisible + owner.set_invis_see(SEE_INVISIBLE_ADMIN) + RegisterSignal(owner, COMSIG_MOB_SEE_INVIS_CHANGE, PROC_REF(on_invis_changed)) + return TRUE + +/datum/status_effect/admin_esp/on_remove() + UnregisterSignal(owner, COMSIG_MOB_SEE_INVIS_CHANGE) + owner.set_invis_see(real_invis_see) // restore our 'real' invis_see + +/// Whenever our invis_see updates from some other source, keep real_invis_see up to date +/datum/status_effect/admin_esp/proc/on_invis_changed(datum/source, see_invis, old_invis) + SIGNAL_HANDLER + + real_invis_see = see_invis diff --git a/code/datums/status_effects/wound_effects.dm b/code/datums/status_effects/wound_effects.dm index 1fd6c53e8c1..5ea0be0b256 100644 --- a/code/datums/status_effects/wound_effects.dm +++ b/code/datums/status_effects/wound_effects.dm @@ -79,17 +79,22 @@ // less limping while we have determination still var/determined_mod = owner.has_status_effect(/datum/status_effect/determined) ? 0.5 : 1 + var/limp_chance + var/limp_slowdown + if(next_leg == left) + limp_chance = limp_chance_left + limp_slowdown = slowdown_left + next_leg = right + else + limp_chance = limp_chance_right + limp_slowdown = slowdown_right + next_leg = left + if(SEND_SIGNAL(owner, COMSIG_CARBON_LIMPING) & COMPONENT_CANCEL_LIMP) return - if(next_leg == left) - if(prob(limp_chance_left * determined_mod)) - owner.client.move_delay += slowdown_left * determined_mod - next_leg = right - else - if(prob(limp_chance_right * determined_mod)) - owner.client.move_delay += slowdown_right * determined_mod - next_leg = left + if(prob(limp_chance * determined_mod)) + owner.client.move_delay += limp_slowdown * determined_mod /// We need to make sure that we properly clear these refs if one of the owner's limbs gets deleted /datum/status_effect/limp/proc/on_limb_removed(datum/source, obj/item/bodypart/limb_lost, special, dismembered) @@ -137,6 +142,31 @@ carbon_mob.remove_status_effect(src) return +//Quirk variant of limping. Will always be applied as long as you have a leg to stand on. +/datum/status_effect/limp/quirk + id = "limp_quirk" + alert_type = null + +/datum/status_effect/limp/quirk/update_limp(datum/source) + var/mob/living/carbon/carbon_mob = owner + left = carbon_mob.get_bodypart(BODY_ZONE_L_LEG) + right = carbon_mob.get_bodypart(BODY_ZONE_R_LEG) + + slowdown_left = 0 + slowdown_right = 0 + limp_chance_left = 0 + limp_chance_right = 0 + + + if(left) + slowdown_left = 7 //Same as compound fracture + limp_chance_left = 70 + + else if(right) + slowdown_right = 7 + limp_chance_right = 70 + + ///////////////////////// //////// WOUNDS ///////// ///////////////////////// diff --git a/code/datums/storage/storage.dm b/code/datums/storage/storage.dm index ab6b1d03f05..b468f40b7d8 100644 --- a/code/datums/storage/storage.dm +++ b/code/datums/storage/storage.dm @@ -489,6 +489,8 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) return FALSE if(SEND_SIGNAL(parent, COMSIG_ATOM_PRE_STORED_ITEM, to_insert, user, force, messages) & BLOCK_STORAGE_INSERT) return FALSE + if(SEND_SIGNAL(to_insert, COMSIG_ITEM_PRE_STORAGE_INSERTION, parent, user, force, messages) & BLOCK_STORAGE_INSERT) + return FALSE SEND_SIGNAL(parent, COMSIG_ATOM_STORED_ITEM, to_insert, user, force) SEND_SIGNAL(src, COMSIG_STORAGE_STORED_ITEM, to_insert, user, force) @@ -499,7 +501,8 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) to_insert.forceMove(real_location) if(get(real_location, /mob) != user) to_insert.do_pickup_animation(real_location, user) - item_insertion_feedback(user, to_insert, override) + if (messages) + item_insertion_feedback(user, to_insert, override) parent.update_appearance() return TRUE @@ -1071,10 +1074,10 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) if(to_show.active_storage != src && (to_show.stat == CONSCIOUS)) for(var/obj/item/thing in real_location) if(thing.on_found(to_show)) - to_show.active_storage.hide_contents(to_show) + to_show.active_storage?.hide_contents(to_show) + return FALSE - if(to_show.active_storage) - to_show.active_storage.hide_contents(to_show) + to_show.active_storage?.hide_contents(to_show) to_show.active_storage = src diff --git a/code/datums/storage/storage_interface.dm b/code/datums/storage/storage_interface.dm index 1f358af00ef..2e42e34a6ea 100644 --- a/code/datums/storage/storage_interface.dm +++ b/code/datums/storage/storage_interface.dm @@ -112,7 +112,7 @@ for(var/obj/item as anything in storage_contents) item.mouse_opacity = MOUSE_OPACITY_OPAQUE - item.screen_loc = "[current_x]:[screen_pixel_x],[current_y]:[screen_pixel_y]" + item.screen_loc = "[current_x]:[screen_pixel_x + item.base_pixel_x],[current_y]:[screen_pixel_y + item.base_pixel_y]" if(parent_storage.numerical_stacking) item.maptext = storage_contents[item] SET_PLANE(item, ABOVE_HUD_PLANE, our_turf) diff --git a/code/datums/verbs.dm b/code/datums/verbs.dm deleted file mode 100644 index 9fed14c20c8..00000000000 --- a/code/datums/verbs.dm +++ /dev/null @@ -1,102 +0,0 @@ -/datum/verbs - var/name - var/list/children - var/datum/verbs/parent - var/list/verblist - var/abstract = FALSE - -//returns the master list for verbs of a type -/datum/verbs/proc/GetList() - CRASH("Abstract verblist for [type]") - -//do things for each entry in Generate_list -//return value sets Generate_list[verbpath] -/datum/verbs/proc/HandleVerb(list/entry, procpath/verbpath, ...) - return entry - -/datum/verbs/New() - var/mainlist = GetList() - var/ourentry = mainlist[type] - children = list() - verblist = list() - if (ourentry) - if (!islist(ourentry)) //some of our childern already loaded - qdel(src) - CRASH("Verb double load: [type]") - Add_children(ourentry) - - mainlist[type] = src - - Load_verbs(type, typesof("[type]/verb")) - - var/datum/verbs/parent = mainlist[parent_type] - if (!parent) - mainlist[parent_type] = list(src) - else if (islist(parent)) - parent += src - else - parent.Add_children(list(src)) - -/datum/verbs/proc/Set_parent(datum/verbs/_parent) - parent = _parent - if (abstract) - parent.Add_children(children) - var/list/verblistoftypes = list() - for(var/thing in verblist) - LAZYADD(verblistoftypes[verblist[thing]], thing) - - for(var/verbparenttype in verblistoftypes) - parent.Load_verbs(verbparenttype, verblistoftypes[verbparenttype]) - -/datum/verbs/proc/Add_children(list/kids) - if (abstract && parent) - parent.Add_children(kids) - return - - for(var/thing in kids) - var/datum/verbs/item = thing - item.Set_parent(src) - if (!item.abstract) - children += item - -/datum/verbs/proc/Load_verbs(verb_parent_type, list/verbs) - if (abstract && parent) - parent.Load_verbs(verb_parent_type, verbs) - return - - for (var/verbpath in verbs) - verblist[verbpath] = verb_parent_type - -/datum/verbs/proc/Generate_list(...) - . = list() - if (length(children)) - for (var/thing in children) - var/datum/verbs/child = thing - var/list/childlist = child.Generate_list(arglist(args)) - if (childlist) - var/childname = "[child]" - if (childname == "[child.type]") - var/list/tree = splittext(childname, "/") - childname = tree[tree.len] - .[child.type] = "parent=[url_encode("[type]")];name=[childname]" - . += childlist - - for (var/thing in verblist) - var/procpath/verbpath = thing - if (!verbpath) - stack_trace("Bad VERB in [type] verblist: [english_list(verblist)]") - var/list/entry = list() - entry["parent"] = "[type]" - entry["name"] = verbpath.desc - if (verbpath.name[1] == "@") - entry["command"] = copytext(verbpath.name, length(verbpath.name[1]) + 1) - else - entry["command"] = replacetext(verbpath.name, " ", "-") - - .[verbpath] = HandleVerb(arglist(list(entry, verbpath) + args)) - -/world/proc/LoadVerbs(verb_type) - if(!ispath(verb_type, /datum/verbs) || verb_type == /datum/verbs) - CRASH("Invalid verb_type: [verb_type]") - for (var/typepath in subtypesof(verb_type)) - new typepath() diff --git a/code/datums/view.dm b/code/datums/view.dm index 7559e204b90..ce0cccd5d99 100644 --- a/code/datums/view.dm +++ b/code/datums/view.dm @@ -45,16 +45,16 @@ SEND_SIGNAL(chief.mob, COMSIG_VIEWDATA_UPDATE, getView()) /datum/view_data/proc/assertFormat()//T-Pose - winset(chief, "mapwindow.map", "zoom=0") + winset(chief, SKIN_MAPWINDOW_MAP, "zoom=0") zoom = 0 /datum/view_data/proc/resetFormat()//Cuck zoom = chief?.prefs.read_preference(/datum/preference/numeric/pixel_size) - winset(chief, "mapwindow.map", "zoom=[zoom]") + winset(chief, SKIN_MAPWINDOW_MAP, "zoom=[zoom]") chief?.attempt_auto_fit_viewport() // If you change zoom mode, fit the viewport /datum/view_data/proc/setZoomMode() - winset(chief, "mapwindow.map", "zoom-mode=[chief?.prefs.read_preference(/datum/preference/choiced/scaling_method)]") + winset(chief, SKIN_MAPWINDOW_MAP, "zoom-mode=[chief?.prefs.read_preference(/datum/preference/choiced/scaling_method)]") /datum/view_data/proc/isZooming() return (width || height) diff --git a/code/datums/wires/big_manipulator.dm b/code/datums/wires/big_manipulator.dm index 4d56f5470e1..9ad7dbeb3a2 100644 --- a/code/datums/wires/big_manipulator.dm +++ b/code/datums/wires/big_manipulator.dm @@ -23,8 +23,7 @@ var/list/status = list() status += "The big light bulb [holder_manipulator.power_access_wire_cut ? "is off" : "is glowing [holder_manipulator.on ? "green" : "red"]"]." status += "The small light bulb [holder_manipulator.held_object ? "is glowing bright green" : "is off"]." - status += "The green number on the display shows [length(holder_manipulator.pickup_points)]." - status += "The red number on the display shows [length(holder_manipulator.dropoff_points)]." + status += "The number on the display shows [length(holder_manipulator.tasks)]." return status /datum/wires/big_manipulator/on_pulse(wire) diff --git a/code/datums/wounds/_wounds.dm b/code/datums/wounds/_wounds.dm index 1654670e504..9b03a328382 100644 --- a/code/datums/wounds/_wounds.dm +++ b/code/datums/wounds/_wounds.dm @@ -405,6 +405,9 @@ var/obj/item/bodypart/cached_limb = limb // remove_wound() nulls limb so we have to track it locally remove_wound(replaced=TRUE) new_wound.apply_wound(cached_limb, old_wound = src, smited = smited, attack_direction = attack_direction, wound_source = wound_source, replacing = TRUE) + if(HAS_TRAIT(src, TRAIT_WOUND_SCANNED) && severity > new_wound.severity) + for(var/trait_source in GET_TRAIT_SOURCES(src, TRAIT_WOUND_SCANNED)) + ADD_TRAIT(new_wound, TRAIT_WOUND_SCANNED, trait_source) . = new_wound qdel(src) diff --git a/code/datums/wounds/pierce.dm b/code/datums/wounds/pierce.dm index 2ccf49d293f..e13fd79e935 100644 --- a/code/datums/wounds/pierce.dm +++ b/code/datums/wounds/pierce.dm @@ -39,8 +39,8 @@ /// When hit on this bodypart, we have this chance of losing some blood + the incoming damage var/internal_bleeding_chance - /// If we let off blood when hit, the max blood lost is this * the incoming damage - var/internal_bleeding_coefficient + /// A multiplier applied to how much blood is lost from damage to the wounded limb + var/internal_bleeding_coefficient = 1 /// If TRUE we are ready to be mended in surgery VAR_FINAL/mend_state = FALSE @@ -51,37 +51,37 @@ return ..() -/datum/wound/pierce/bleed/receive_damage(wounding_type, wounding_dmg, wound_bonus) - if(victim.stat == DEAD || (wounding_dmg < 5) || !limb.can_bleed() || !victim.get_blood_volume() || !prob(internal_bleeding_chance + wounding_dmg)) +/datum/wound/pierce/bleed/receive_damage(wounding_type, wounding_dmg, wound_bonus, attack_direction, damage_source) + if(victim.stat == DEAD || wounding_dmg < 5 || !limb.can_bleed() || !victim.get_blood_volume() || !prob(internal_bleeding_chance + wounding_dmg)) return - var/blood_bled = rand(1, limb.get_splint_factor() * internal_bleeding_coefficient) // 12 brute toolbox can cause up to 15/18/21 bloodloss on mod/sev/crit + // 20 force attack ~= 5-16 blood loss ~= 1%-3% of blood volume + // 30 force attack ~= 6-20 blood loss ~= 1%-4% of blood volume + var/blood_bled = sqrt(wounding_dmg) * internal_bleeding_coefficient * limb.get_splint_factor() * pick(0.75, 1, 1.25, 1.5) switch(blood_bled) - if(1 to 6) - victim.bleed(blood_bled, TRUE) - if(7 to 13) + if(8 to 12) victim.visible_message( span_smalldanger("Blood droplets fly from the hole in [victim]'s [limb.plaintext_zone]."), span_danger("You cough up a bit of blood from the blow to your [limb.plaintext_zone]."), vision_distance = COMBAT_MESSAGE_RANGE, + visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE, ) - victim.bleed(blood_bled, TRUE) - if(14 to 19) + if(12 to 18) victim.visible_message( span_smalldanger("A small stream of blood spurts from the hole in [victim]'s [limb.plaintext_zone]!"), span_danger("You spit out a string of blood from the blow to your [limb.plaintext_zone]!"), vision_distance = COMBAT_MESSAGE_RANGE, + visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE, ) - victim.create_splatter(victim.dir) - victim.bleed(blood_bled) - if(20 to INFINITY) + if(18 to INFINITY) victim.visible_message( span_danger("A spray of blood streams from the gash in [victim]'s [limb.plaintext_zone]!"), span_bolddanger("You choke up on a spray of blood from the blow to your [limb.plaintext_zone]!"), vision_distance = COMBAT_MESSAGE_RANGE, + visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE, ) - victim.bleed(blood_bled) - victim.create_splatter(victim.dir) - victim.add_splatter_floor(get_step(victim.loc, victim.dir)) + victim.bleed(blood_bled) + if(blood_bled >= 18) + victim.spray_blood(attack_direction) /datum/wound/pierce/bleed/get_bleed_rate_of_change() //basically if a species doesn't bleed, the wound is stagnant and will not heal on its own (nor get worse) @@ -169,7 +169,7 @@ playsound(user, 'sound/items/handling/surgery/cautery2.ogg', 75, TRUE) - var/bleeding_wording = (!limb.can_bleed() ? "holes" : "bleeding") + var/bleeding_wording = (limb.can_bleed() ? "bleeding" : "holes") user.visible_message(span_green("[user] cauterizes some of the [bleeding_wording] on [victim]."), span_green("You cauterize some of the [bleeding_wording] on [victim].")) victim.apply_damage(2 + severity, BURN, limb, wound_bonus = CANT_WOUND) if(prob(30)) @@ -206,7 +206,7 @@ gauzed_clot_rate = 0.75 clot_rate = 0.03 internal_bleeding_chance = 30 - internal_bleeding_coefficient = 1.25 + internal_bleeding_coefficient = 1.5 series_threshold_penalty = 20 status_effect_type = /datum/status_effect/wound/pierce/moderate scar_keyword = "piercemoderate" @@ -240,7 +240,6 @@ gauzed_clot_rate = 0.1 clot_rate = 0.03 // will close quickly on its own internal_bleeding_chance = 0 - internal_bleeding_coefficient = 1 threshold_penalty = 5 /datum/wound_pregen_data/flesh_pierce/open_puncture/pinprick @@ -285,7 +284,7 @@ gauzed_clot_rate = 0.5 clot_rate = 0.02 internal_bleeding_chance = 60 - internal_bleeding_coefficient = 1.5 + internal_bleeding_coefficient = 2 series_threshold_penalty = 35 status_effect_type = /datum/status_effect/wound/pierce/severe scar_keyword = "piercesevere" @@ -397,7 +396,7 @@ initial_flow = 2.5 gauzed_clot_rate = 0.3 internal_bleeding_chance = 80 - internal_bleeding_coefficient = 1.75 + internal_bleeding_coefficient = 2.5 threshold_penalty = 15 status_effect_type = /datum/status_effect/wound/pierce/critical scar_keyword = "piercecritical" diff --git a/code/datums/wounds/slash.dm b/code/datums/wounds/slash.dm index 856a54f8631..e0ac7b30ddc 100644 --- a/code/datums/wounds/slash.dm +++ b/code/datums/wounds/slash.dm @@ -276,7 +276,7 @@ playsound(user, 'sound/items/handling/surgery/cautery2.ogg', 75, TRUE) - var/bleeding_wording = (!limb.can_bleed() ? "cuts" : "bleeding") + var/bleeding_wording = (limb.can_bleed() ? "bleeding" : "cuts") user.visible_message(span_green("[user] cauterizes some of the [bleeding_wording] on [victim]."), span_green("You cauterize some of the [bleeding_wording] on [victim].")) victim.apply_damage(2 + severity, BURN, limb, wound_bonus = CANT_WOUND) if(prob(30)) diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index c9692021a01..87104b8cd47 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -117,8 +117,13 @@ /// Wire assignment for airlocks in this area var/airlock_wires = /datum/wires/airlock - ///This datum, if set, allows terrain generation behavior to be ran on Initialize() + /// Should we actually be running our mapgen if one is set? + /// FALSE here with a set map_generator allows the area to probe from shared generators without actually generating its' turfs + var/use_mapgen = TRUE + /// Datum that would be used in terrain generation behavior var/datum/map_generator/map_generator + /// Should the map_generator be shared with all other willing areas on our z_level? + var/share_map_generator = TRUE ///Used to decide what kind of reverb the area makes sound have var/sound_environment = SOUND_ENVIRONMENT_NONE @@ -220,27 +225,56 @@ GLOBAL_LIST_EMPTY(teleportlocs) /// Generate turfs, including cool cave wall gen /area/proc/RunTerrainGeneration() - if(map_generator) - map_generator = new map_generator() - var/list/turfs = list() - for(var/turf/T in contents) - turfs += T - map_generator.generate_terrain(turfs, src) + if (!use_mapgen || !map_generator) + return + map_generator = get_generator() + var/list/turfs = list() + for(var/turf/T in contents) + turfs += T + map_generator.generate_terrain(turfs, src) /// Populate the previously generated terrain with mobs and objects /area/proc/RunTerrainPopulation() - if(map_generator) - var/list/turfs = list() - for(var/turf/T in contents) - turfs += T - map_generator.populate_terrain(turfs, src) + if (!use_mapgen || !map_generator) + return + map_generator = get_generator() + var/list/turfs = list() + for(var/turf/T in contents) + turfs += T + map_generator.populate_terrain(turfs, src) /area/proc/test_gen() - if(map_generator) - var/list/turfs = list() - for(var/turf/T in contents) - turfs += T - map_generator.generate_terrain(turfs, src) + if (!use_mapgen || !map_generator) + return + map_generator = get_generator() + var/list/turfs = list() + for(var/turf/T in contents) + turfs += T + map_generator.generate_terrain(turfs, src) + +/// Gets own, or shared, map generator +/area/proc/get_generator() + RETURN_TYPE(/datum/map_generator) + if (!map_generator) + return + + if (istype(map_generator)) + return map_generator + + if (!share_map_generator) + map_generator = new map_generator() + return map_generator + + var/list/z_generators = GLOB.map_generators_by_z["[z]"] + if (z_generators && z_generators[map_generator]) + map_generator = z_generators[map_generator] + + if (!istype(map_generator)) + var/new_generator = new map_generator() + LAZYSET(GLOB.map_generators_by_z["[z]"], map_generator, new_generator) + map_generator = new_generator + + return map_generator /// Returns the highest zlevel that this area contains turfs for /area/proc/get_highest_zlevel() diff --git a/code/game/area/areas/mining.dm b/code/game/area/areas/mining.dm index 3d97da72c39..af047a00698 100644 --- a/code/game/area/areas/mining.dm +++ b/code/game/area/areas/mining.dm @@ -137,6 +137,8 @@ sound_environment = SOUND_AREA_LAVALAND ambient_buzz = 'sound/ambience/lavaland/magma.ogg' allow_shuttle_docking = TRUE + map_generator = /datum/map_generator/cave_generator/lavaland + use_mapgen = FALSE /area/lavaland/surface name = "Lavaland" @@ -167,7 +169,7 @@ icon_state = "unexplored" area_flags = VALID_TERRITORY area_flags_mapping = UNIQUE_AREA | CAVES_ALLOWED | FLORA_ALLOWED | MOB_SPAWN_ALLOWED - map_generator = /datum/map_generator/cave_generator/lavaland + use_mapgen = TRUE /area/lavaland/surface/outdoors/unexplored/danger //megafauna will also spawn here icon_state = "danger" diff --git a/code/game/area/areas/ruins/icemoon.dm b/code/game/area/areas/ruins/icemoon.dm index 7adcf57cb57..549fab5e846 100644 --- a/code/game/area/areas/ruins/icemoon.dm +++ b/code/game/area/areas/ruins/icemoon.dm @@ -28,6 +28,10 @@ name = "\improper Listening Post" sound_environment = SOUND_ENVIRONMENT_CITY +/area/ruin/comms_agent/Initialize(mapload) + . = ..() + AddElement(/datum/element/block_area_power_fail) + /area/ruin/comms_agent/maint name = "\improper Listening Post Maintenance" sound_environment = SOUND_AREA_TUNNEL_ENCLOSED diff --git a/code/game/area/areas/station/ai.dm b/code/game/area/areas/station/ai.dm index ff12a728f28..faa717845b3 100644 --- a/code/game/area/areas/station/ai.dm +++ b/code/game/area/areas/station/ai.dm @@ -45,6 +45,10 @@ icon_state = "ai_chamber" annoying_ambience = null +/area/station/ai/satellite/chamber/Initialize(mapload) + . = ..() + AddElement(/datum/element/block_area_power_fail) + /area/station/ai/satellite/exterior name = "\improper AI Satellite Exterior" secure = FALSE diff --git a/code/game/area/areas/station/engineering.dm b/code/game/area/areas/station/engineering.dm index 1193404c975..9ad25f233cb 100644 --- a/code/game/area/areas/station/engineering.dm +++ b/code/game/area/areas/station/engineering.dm @@ -16,6 +16,10 @@ name = "Engineering" icon_state = "engine" +/area/station/engineering/main/Initialize(mapload) + . = ..() + AddElement(/datum/element/block_area_power_fail) + /area/station/engineering/hallway name = "Engineering Hallway" icon_state = "engine_hallway" @@ -69,6 +73,10 @@ icon_state = "atmos_engine" area_flags = BLOBS_ALLOWED | CULT_PERMITTED +/area/station/engineering/atmospherics_engine/Initialize(mapload) + . = ..() + AddElement(/datum/element/block_area_power_fail) + /area/station/engineering/lobby name = "\improper Engineering Lobby" icon_state = "engi_lobby" @@ -79,6 +87,10 @@ area_flags = BLOBS_ALLOWED | CULT_PERMITTED sound_environment = SOUND_AREA_SMALL_ENCLOSED +/area/station/engineering/supermatter/Initialize(mapload) + . = ..() + AddElement(/datum/element/block_area_power_fail) + /area/station/engineering/supermatter/waste name = "\improper Supermatter Waste Chamber" icon_state = "engine_sm_waste" diff --git a/code/game/atom/atom_materials.dm b/code/game/atom/atom_materials.dm index 05a1801ee6f..1f787d217bd 100644 --- a/code/game/atom/atom_materials.dm +++ b/code/game/atom/atom_materials.dm @@ -343,6 +343,7 @@ ///Apply material effects of a single material. /atom/proc/apply_single_mat_effect(datum/material/material, amount, multiplier) SHOULD_CALL_PARENT(TRUE) + SEND_SIGNAL(src, COMSIG_ATOM_SINGLE_MATERIAL_EFFECT_APPLY, material, amount, multiplier) // Derived and not optional, so this needs to be on base and not in the property code itself var/beauty_modifier = material.get_property(MATERIAL_BEAUTY) @@ -432,6 +433,7 @@ ///Remove material effects of a single material. /atom/proc/remove_single_mat_effect(datum/material/material, amount, multiplier) SHOULD_CALL_PARENT(TRUE) + SEND_SIGNAL(src, COMSIG_ATOM_SINGLE_MATERIAL_EFFECT_REMOVE, material, amount, multiplier) var/beauty_modifier = material.get_property(MATERIAL_BEAUTY) if(beauty_modifier) diff --git a/code/game/atom/atom_vv.dm b/code/game/atom/atom_vv.dm index 85d7ed011c7..d5a4b5ccd9d 100644 --- a/code/game/atom/atom_vv.dm +++ b/code/game/atom/atom_vv.dm @@ -11,6 +11,7 @@ if(curturf) . += "Jump To" VV_DROPDOWN_OPTION(VV_HK_MODIFY_TRANSFORM, "Modify Transform") + VV_DROPDOWN_OPTION(VV_HK_DEBUG_APPEARANCE, "Debug Appearance") VV_DROPDOWN_OPTION(VV_HK_SPIN_ANIMATION, "SpinAnimation") VV_DROPDOWN_OPTION(VV_HK_STOP_ALL_ANIMATIONS, "Stop All Animations") VV_DROPDOWN_OPTION(VV_HK_SHOW_HIDDENPRINTS, "Show Hiddenprint log") diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 3e9a8361a22..fbab282ef5e 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -36,9 +36,13 @@ var/speech_span ///Are we moving with inertia? Mostly used as an optimization var/inertia_moving = FALSE - ///Multiplier for inertia based movement in space - var/inertia_move_multiplier = 1 - ///Object "weight", higher weight reduces acceleration applied to the object + /// Multiplies speed the movable drifts when unaffected by gravity. + /// "Passive" is used for referring "base drift speed" - only the smaller of the two are used. + var/inertia_move_multiplier_passive = 1 + /// Multiplies speed the movable drifts when unaffected by gravity. + /// "Active" is used for referring to things boosting our drift speed, like jetpacks - only the smaller of the two are used. + var/inertia_move_multiplier_active = 1 + /// Object "weight", higher weight reduces acceleration applied to the object var/inertia_force_weight = 1 ///The last time we pushed off something ///This is a hack to get around dumb him him me scenarios diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm index f16d3367770..6a7ff67445f 100644 --- a/code/game/data_huds.dm +++ b/code/game/data_huds.dm @@ -44,7 +44,7 @@ hud_icons = list(FAN_HUD) /datum/atom_hud/data/diagnostic - hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_TRACK_HUD, DIAG_CAMERA_HUD, DIAG_AIRLOCK_HUD, DIAG_LAUNCHPAD_HUD, BIG_MANIP_HUD, DIAG_NANITE_FULL_HUD) // BUBBER EDIT ADDITION - NANITE_HUD + hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_TRACK_HUD, DIAG_CAMERA_HUD, DIAG_AIRLOCK_HUD, DIAG_LAUNCHPAD_HUD, DIAG_NANITE_FULL_HUD) // BUBBER EDIT ADDITION - NANITE_HUD /datum/atom_hud/data/bot_path hud_icons = list(DIAG_PATH_HUD) @@ -62,7 +62,7 @@ . = ..() if(!new_viewer || hud_users_all_z_levels.len != 1) return - for(var/mob/eye/camera/ai/eye as anything in GLOB.camera_eyes) + for(var/mob/eye/camera/ai/eye in GLOB.camera_eyes) eye.update_ai_detect_hud() /datum/atom_hud/data/malf_apc diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm index 171086b06b6..002ec4787a6 100644 --- a/code/game/gamemodes/events.dm +++ b/code/game/gamemodes/events.dm @@ -23,7 +23,7 @@ continue if(!station_area.requires_power || station_area.always_unpowered ) continue - if(GLOB.typecache_powerfailure_safe_areas[station_area.type]) + if(HAS_TRAIT(station_area, TRAIT_AREA_BLOCK_POWER_FAIL)) continue station_area.power_light = FALSE @@ -34,7 +34,7 @@ for(var/obj/machinery/power/apc/C as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/power/apc)) if(C.cell && is_station_level(C.z)) var/area/A = C.area - if(GLOB.typecache_powerfailure_safe_areas[A.type]) + if(HAS_TRAIT(A, TRAIT_AREA_BLOCK_POWER_FAIL)) continue C.cell.charge = 0 diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 70f2fb76470..70cb1811034 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -185,12 +185,15 @@ if(occupant_typecache) occupant_typecache = typecacheof(occupant_typecache) - if((resistance_flags & INDESTRUCTIBLE) && component_parts){ // This is needed to prevent indestructible machinery still blowing up. If an explosion occurs on the same tile as the indestructible machinery without the PREVENT_CONTENTS_EXPLOSION_1 flag, /datum/controller/subsystem/explosions/proc/propagate_blastwave will call ex_act on all movable atoms inside the machine, including the circuit board and component parts. However, if those parts get deleted, the entire machine gets deleted, allowing for INDESTRUCTIBLE machines to be destroyed. (See #62164 for more info) + if((resistance_flags & INDESTRUCTIBLE) && component_parts) // This is needed to prevent indestructible machinery still blowing up. If an explosion occurs on the same tile as the indestructible machinery without the PREVENT_CONTENTS_EXPLOSION_1 flag, /datum/controller/subsystem/explosions/proc/propagate_blastwave will call ex_act on all movable atoms inside the machine, including the circuit board and component parts. However, if those parts get deleted, the entire machine gets deleted, allowing for INDESTRUCTIBLE machines to be destroyed. (See #62164 for more info) flags_1 |= PREVENT_CONTENTS_EXPLOSION_1 - } + + if(critical_machine) + AddElement(/datum/element/block_area_power_fail) if(HAS_TRAIT(SSstation, STATION_TRAIT_MACHINES_GLITCHED) && mapload) randomize_language_if_on_station() + SEND_GLOBAL_SIGNAL(COMSIG_GLOB_NEW_MACHINE, src) return INITIALIZE_HINT_LATELOAD @@ -1289,8 +1292,18 @@ set_machine_stat(vval) datum_flags |= DF_VAR_EDITED return TRUE + if(vname == NAMEOF(src, critical_machine)) + if(critical_machine == !!vval) // boolean cast in case a badmin tries to set it to 2 for some reason + return FALSE + critical_machine = !!vval + if(critical_machine) + AddElement(/datum/element/block_area_power_fail) + else + RemoveElement(/datum/element/block_area_power_fail) + datum_flags |= DF_VAR_EDITED + return TRUE - return ..() + . = ..() /** * Alerts the AI that a hack is in progress. diff --git a/code/game/machinery/big_manipulator/_defines.dm b/code/game/machinery/big_manipulator/_defines.dm index 362831bd8e7..b04d1b90bb6 100644 --- a/code/game/machinery/big_manipulator/_defines.dm +++ b/code/game/machinery/big_manipulator/_defines.dm @@ -18,32 +18,17 @@ #define MAX_SPEED_MULTIPLIER_TIER_3 5 #define MAX_SPEED_MULTIPLIER_TIER_4 6 -#define MAX_INTERACTION_POINTS_TIER_1 2 -#define MAX_INTERACTION_POINTS_TIER_2 3 -#define MAX_INTERACTION_POINTS_TIER_3 4 -#define MAX_INTERACTION_POINTS_TIER_4 6 +#define MAX_TASKS_TIER_1 6 +#define MAX_TASKS_TIER_2 12 +#define MAX_TASKS_TIER_3 24 +#define MAX_TASKS_TIER_4 32 -#define CURRENT_TASK_NONE "NO TASK" // manipulator is off -#define CURRENT_TASK_IDLE "IDLE" // manipulator is skipping a cycle because it has nothing to do -#define CURRENT_TASK_MOVING_PICKUP "MOVING TO PICKUP POINT" -#define CURRENT_TASK_MOVING_DROPOFF "MOVING TO DROPOFF POINT" -#define CURRENT_TASK_INTERACTING "INTERACTING" -#define CURRENT_TASK_STOPPING "STOPPING" // How should the worker interact with the point #define WORKER_SINGLE_USE "SINGLE TIME" #define WORKER_EMPTY_USE "EMPTY HAND" #define WORKER_NORMAL_USE "NORMAL" -// The tasking schedules the manipulator uses to iterate through points -#define TASKING_ROUND_ROBIN "Round Robin" // 1 - 2 - 3 - 2 - 3 -#define TASKING_STRICT_ROBIN "Strict Robin" // 1 - 2 - 3 - (waiting for 1) - 1 - 2 -#define TASKING_PREFER_FIRST "Prefer First" // 1 - 2 - 1 - 2 - 3 - 2 - 1 - 3 (first availiable) - -// Defines if this point is a pickup or a dropoff point -#define TRANSFER_TYPE_PICKUP "PICK UP" -#define TRANSFER_TYPE_DROPOFF "DROP OFF" - #define BASE_POWER_USAGE 0.2 #define BASE_INTERACTION_TIME 0.3 SECONDS @@ -62,6 +47,16 @@ #define POST_INTERACTION_DROP_NEXT_FITTING "AT ANY FITTING" #define POST_INTERACTION_WAIT "CONTINUE" -// Some macros for interaction checks -#define IS_STOPPING (current_task == CURRENT_TASK_STOPPING) -#define IS_BUSY (current_task != CURRENT_TASK_NONE) + +#define PICKUP_EAGER "Always Pick Up" +#define PICKUP_CAN_WAIT "Wait For Suiting" + +#define TASK_TYPE_PICKUP "pickup" +#define TASK_TYPE_DROP "drop" +#define TASK_TYPE_THROW "throw" +#define TASK_TYPE_USE "use" +#define TASK_TYPE_INTERACT "interact" +#define TASK_TYPE_WAIT "wait" + +#define TASKING_SEQUENTIAL "Sequential" +#define TASKING_STRICT "Strict order" diff --git a/code/game/machinery/big_manipulator/big_manipulator.dm b/code/game/machinery/big_manipulator/big_manipulator.dm index 3a9e9d83d35..83ab74f9a03 100644 --- a/code/game/machinery/big_manipulator/big_manipulator.dm +++ b/code/game/machinery/big_manipulator/big_manipulator.dm @@ -8,7 +8,6 @@ circuit = /obj/item/circuitboard/machine/big_manipulator greyscale_colors = "#d8ce13" greyscale_config = /datum/greyscale_config/big_manipulator - hud_possible = list(BIG_MANIP_HUD) /// Is the manipulator turned on? var/on = FALSE @@ -17,13 +16,8 @@ /// How quickly the manipulator will process it's actions. var/speed_multiplier = 1 - var/min_speed_multiplier = MIN_SPEED_MULTIPLIER_TIER_1 - var/max_speed_multiplier = MAX_SPEED_MULTIPLIER_TIER_1 - - /// The current task. - var/current_task = CURRENT_TASK_NONE - var/current_task_start_time = 0 - var/current_task_duration = 0 + var/min_speed_multiplier = MIN_SPEED_MULTIPLIER_TIER_1 + var/max_speed_multiplier = MAX_SPEED_MULTIPLIER_TIER_1 /// The object inside the manipulator. var/datum/weakref/held_object = null @@ -31,112 +25,88 @@ var/datum/weakref/monkey_worker = null /// Weakref to the ID that locked this manipulator. var/datum/weakref/id_lock = null + /// Inserted manipulator task disk. + var/obj/item/disk/manipulator/task_disk = null /// The manipulator's arm. var/obj/effect/big_manipulator_arm/manipulator_arm = null /// Is the power access wire cut? Disables the power button if `TRUE`. var/power_access_wire_cut = FALSE - /// How many interaction points of each kind can we have? - var/interaction_point_limit = MAX_INTERACTION_POINTS_TIER_1 - /// List of pickup points. - var/list/pickup_points = list() - /// List of dropoff points. - var/list/dropoff_points = list() + /// How many tasks total we can have. + var/interaction_point_limit = MAX_TASKS_TIER_1 - /// Which tasking scenario we use for pickup points? - var/pickup_tasking = TASKING_ROUND_ROBIN - /// Which tasking scenario we use for dropoff points? - var/dropoff_tasking = TASKING_ROUND_ROBIN + /// A list of tasks for the manipulator. + var/list/tasks = list() + /// The task we're currently working on. + var/datum/manipulator_task/current_task - /// List of all HUD icons resembling interaction points. - var/list/hud_points = list() + /// Is the manipulator in the process of stopping? + var/stopping = FALSE + /// Is the manipulator waiting for a turf signal to retry? + var/waiting_for_signal = FALSE + /// Turfs we registered enter/exit signals on while waiting. + var/list/signal_turfs = list() - /// Pickup strategy for tasking. - var/datum/tasking_strategy/pickup_strategy - /// Dropoff strategy for tasking. - var/datum/tasking_strategy/dropoff_strategy + /// Which tasking scenario we use for iterating tasks. + var/tasking_strategy = TASKING_SEQUENTIAL + /// Tasking strategy instance. + var/datum/tasking_strategy/master_tasking -/// Re-creates hud images for the points -/obj/machinery/big_manipulator/proc/update_hud() - LAZYCLEARLIST(hud_points) - - var/image/main_hud = hud_list[BIG_MANIP_HUD] - if(!main_hud) - return - - main_hud.loc = get_turf(src) - main_hud.appearance = mutable_appearance('icons/effects/interaction_points.dmi', null, ABOVE_ALL_MOB_LAYER, src, GAME_PLANE) - - main_hud.overlays.Cut() - var/list/point_overlays = list() - - for(var/i in 1 to length(pickup_points)) - var/datum/interaction_point/point = pickup_points[i] - var/turf/target_turf = point.interaction_turf - if(target_turf) - var/mutable_appearance/point_appearance = mutable_appearance('icons/effects/interaction_points.dmi', "pickup_[i]", ABOVE_ALL_MOB_LAYER, src, GAME_PLANE) - var/turf/manip_turf = get_turf(src) - point_appearance.pixel_x = (target_turf.x - manip_turf.x) * 32 - point_appearance.pixel_y = (target_turf.y - manip_turf.y) * 32 - point_overlays += point_appearance - - for(var/i in 1 to length(dropoff_points)) - var/datum/interaction_point/point = dropoff_points[i] - var/turf/target_turf = point.interaction_turf - if(target_turf) - var/mutable_appearance/point_appearance = mutable_appearance('icons/effects/interaction_points.dmi', "dropoff_[i]", ABOVE_ALL_MOB_LAYER, src, GAME_PLANE) - var/turf/manip_turf = get_turf(src) - point_appearance.pixel_x = (target_turf.x - manip_turf.x) * 32 - point_appearance.pixel_y = (target_turf.y - manip_turf.y) * 32 - point_overlays += point_appearance - - main_hud.overlays += point_overlays - hud_points += main_hud - set_hud_image_active(BIG_MANIP_HUD) - -/// Attempts to find a suitable turf near the manipulator +/// Attempts to find a suitable turf near the manipulator for creating a cargo task. /obj/machinery/big_manipulator/proc/find_suitable_turf() - var/turf/center = get_turf(src) - - for(var/turf/checked_turf in orange(center, 1)) + var/turf/base = get_turf(src) + for(var/turf/checked_turf in orange(base, 1)) if(!isclosedturf(checked_turf)) return checked_turf - - // didn't find any :boowomp: return null -/// Attempts to create a new interaction point and assign it to the correct list. -/obj/machinery/big_manipulator/proc/create_new_interaction_point(mob/user, turf/new_turf, list/new_filters, new_filters_status, new_interaction_mode, transfer_type) - if(!new_turf || !isturf(new_turf)) - new_turf = find_suitable_turf() - if(!new_turf) - balloon_alert(user, "no suitable turfs found!") - return FALSE - - var/list/current_points = (transfer_type == TRANSFER_TYPE_PICKUP) ? pickup_points : dropoff_points - var/point_type = (transfer_type == TRANSFER_TYPE_PICKUP) ? "pickup" : "dropoff" - - if(length(current_points) + 1 > interaction_point_limit) - balloon_alert(user, "[point_type] point limit reached!") +/// Attempts to create a new task and assign it to the list. +/obj/machinery/big_manipulator/proc/create_new_task(mob/user, task_type, turf/new_turf) + if(length(tasks) >= interaction_point_limit) + balloon_alert(user, "task limit reached!") return FALSE var/datum/stock_part/servo/locate_servo = locate() in component_parts var/manipulator_tier = locate_servo ? locate_servo.tier : 1 - var/datum/interaction_point/new_interaction_point = new(new_turf, new_filters, new_filters_status, new_interaction_mode, manipulator_tier) + var/datum/manipulator_task/new_task + var/needs_turf = task_type in list(TASK_TYPE_PICKUP, TASK_TYPE_DROP, TASK_TYPE_THROW, TASK_TYPE_USE, TASK_TYPE_INTERACT) - if(QDELETED(new_interaction_point)) // if something STILL somehow went wrong + if(needs_turf) + if(!new_turf) + new_turf = find_suitable_turf() + if(!new_turf) + return FALSE + + switch(task_type) + if(TASK_TYPE_PICKUP) + new_task = new /datum/manipulator_task/cargo/pickup(new_turf, manipulator_tier) + if(TASK_TYPE_DROP) + new_task = new /datum/manipulator_task/cargo/dropoff_base/drop(new_turf, manipulator_tier) + if(TASK_TYPE_THROW) + new_task = new /datum/manipulator_task/cargo/dropoff_base/throw(new_turf, manipulator_tier) + if(TASK_TYPE_USE) + new_task = new /datum/manipulator_task/cargo/dropoff_base/use(new_turf, manipulator_tier) + if(TASK_TYPE_INTERACT) + new_task = new /datum/manipulator_task/cargo/interact(new_turf, manipulator_tier) + if(TASK_TYPE_WAIT) + new_task = new /datum/manipulator_task/simple/wait() + + if(QDELETED(new_task)) return FALSE - current_points += new_interaction_point + tasks += new_task - if(obj_flags & EMAGGED) - new_interaction_point.type_filters += /mob/living + if(istype(new_task, /datum/manipulator_task/cargo)) + var/datum/manipulator_task/cargo/cargo_task = new_task + cargo_task.offset_dx = new_turf.x - x + cargo_task.offset_dy = new_turf.y - y - if(is_operational) - update_hud() + if((obj_flags & EMAGGED) && istype(new_task, /datum/manipulator_task/cargo)) + var/datum/manipulator_task/cargo/cargo_task = new_task + cargo_task.type_filters += /mob/living - return new_interaction_point + return new_task /obj/machinery/big_manipulator/Initialize(mapload) . = ..() @@ -147,11 +117,6 @@ set_wires(new /datum/wires/big_manipulator(src)) register_context() - for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds) - diag_hud.add_atom_to_hud(src) - - prepare_huds() - update_hud() update_strategies() /// Checks the component tiers, adjusting the properties of the manipulator. @@ -165,35 +130,32 @@ if(-INFINITY to 1) min_speed_multiplier = MIN_SPEED_MULTIPLIER_TIER_1 max_speed_multiplier = MAX_SPEED_MULTIPLIER_TIER_1 - interaction_point_limit = MAX_INTERACTION_POINTS_TIER_1 + interaction_point_limit = MAX_TASKS_TIER_1 set_greyscale(COLOR_YELLOW) manipulator_arm?.set_greyscale(COLOR_YELLOW) if(2) min_speed_multiplier = MIN_SPEED_MULTIPLIER_TIER_2 max_speed_multiplier = MAX_SPEED_MULTIPLIER_TIER_2 - interaction_point_limit = MAX_INTERACTION_POINTS_TIER_2 + interaction_point_limit = MAX_TASKS_TIER_2 set_greyscale(COLOR_ORANGE) manipulator_arm?.set_greyscale(COLOR_ORANGE) if(3) min_speed_multiplier = MIN_SPEED_MULTIPLIER_TIER_3 max_speed_multiplier = MAX_SPEED_MULTIPLIER_TIER_3 - interaction_point_limit = MAX_INTERACTION_POINTS_TIER_3 + interaction_point_limit = MAX_TASKS_TIER_3 set_greyscale(COLOR_RED) manipulator_arm?.set_greyscale(COLOR_RED) if(4 to INFINITY) min_speed_multiplier = MIN_SPEED_MULTIPLIER_TIER_4 max_speed_multiplier = MAX_SPEED_MULTIPLIER_TIER_4 - interaction_point_limit = MAX_INTERACTION_POINTS_TIER_4 + interaction_point_limit = MAX_TASKS_TIER_4 set_greyscale(COLOR_PURPLE) manipulator_arm?.set_greyscale(COLOR_PURPLE) active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * BASE_POWER_USAGE * manipulator_tier - for(var/datum/interaction_point/each_point in pickup_points) - each_point.interaction_priorities = each_point.fill_priority_list(manipulator_tier) - - for(var/datum/interaction_point/each_point in dropoff_points) - each_point.interaction_priorities = each_point.fill_priority_list(manipulator_tier) + for(var/datum/manipulator_task/cargo/cargo_task in tasks) + cargo_task.interaction_priorities = cargo_task.fill_priority_list(manipulator_tier) /obj/machinery/big_manipulator/examine(mob/user) . = ..() @@ -205,10 +167,15 @@ try_press_on(user) return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN +/obj/machinery/big_manipulator/click_alt(mob/user) + eject_task_disk(user) + return CLICK_ACTION_SUCCESS + /obj/machinery/big_manipulator/add_context(atom/source, list/context, obj/item/held_item, mob/user) . = ..() context[SCREENTIP_CONTEXT_RMB] = "Toggle" + context[SCREENTIP_CONTEXT_ALT_LMB] = "Eject disk" if(isnull(held_item)) context[SCREENTIP_CONTEXT_LMB] = panel_open ? "Interact with wires" : "Open UI" @@ -228,16 +195,23 @@ context[SCREENTIP_CONTEXT_LMB] = "Interact with wires" return CONTEXTUAL_SCREENTIP_SET -/obj/machinery/big_manipulator/Destroy(force) - remove_all_huds() - for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds) - diag_hud.remove_atom_from_hud(src) - +/obj/machinery/big_manipulator/atom_deconstruct(disassembled) + if(task_disk) + task_disk.forceMove(drop_location()) + task_disk = null + unregister_task_turf_signals() QDEL_NULL(manipulator_arm) - // QDEL_NULL(monkey_worker.resolve()) - // QDEL_NULL(held_object.resolve()) + QDEL_LIST(tasks) id_lock = null - . = ..() + return ..() + +/obj/machinery/big_manipulator/Destroy(force) + unregister_task_turf_signals() + QDEL_NULL(task_disk) + QDEL_NULL(manipulator_arm) + QDEL_LIST(tasks) + id_lock = null + return ..() /obj/machinery/big_manipulator/Exited(atom/movable/gone, direction) . = ..() @@ -252,90 +226,13 @@ poor_monkey.remove_offsets(type) monkey_worker = null -/obj/machinery/big_manipulator/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change) - . = ..() - if(!old_loc || !isturf(old_loc)) +/// Removes an invalid task from the list. +/obj/machinery/big_manipulator/proc/remove_invalid_task(datum/manipulator_task/task) + if(!task) return - - var/turf/old_turf = old_loc - var/turf/new_turf = get_turf(src) - if(!new_turf || old_turf == new_turf) - return - - var/dx = new_turf.x - old_turf.x - var/dy = new_turf.y - old_turf.y - - if(dx == 0 && dy == 0) // if we rotated for instance - return - - for(var/datum/interaction_point/point in pickup_points) - update_point_position(point, dx, dy) - - for(var/datum/interaction_point/point in dropoff_points) - update_point_position(point, dx, dy) - - if(is_operational) - update_hud() - -/// Updates a single interaction point's position by the given offset -/obj/machinery/big_manipulator/proc/update_point_position(datum/interaction_point/point, dx, dy) - if(!point || !point.interaction_turf) - return - - var/turf/old_turf = point.interaction_turf - if(!old_turf) - return - - var/turf/manipulator_turf = get_turf(src) - if(!manipulator_turf) - return - - var/turf/new_turf = locate(old_turf.x + dx, old_turf.y + dy, manipulator_turf.z) - - // if manipulator is not anchored, allow points to be anywhere (even in walls) to not mess up your stuff when moving it - if(!anchored) - if(new_turf) - point.interaction_turf = new_turf - return - - if(!new_turf || isclosedturf(new_turf)) - new_turf = find_suitable_turf_near(new_turf || old_turf) - if(!new_turf) - remove_invalid_point(point) - return - - if(new_turf == old_turf) - return - - point.interaction_turf = new_turf - -/// Finds a suitable turf near the given location -/obj/machinery/big_manipulator/proc/find_suitable_turf_near(turf/center) - if(!center) - return null - - var/turf/manipulator_turf = get_turf(src) - if(!manipulator_turf) - return null - - for(var/turf/each in orange(1, src)) - if(!isclosedturf(each)) - return each - - return null - -/// Removes an invalid interaction point from the lists. -/obj/machinery/big_manipulator/proc/remove_invalid_point(datum/interaction_point/point) - if(!point) - return - - pickup_points.Remove(point) - dropoff_points.Remove(point) - - qdel(point) - if(is_operational) - update_hud() + tasks -= task + qdel(task) /obj/machinery/big_manipulator/emag_act(mob/user, obj/item/card/emag/emag_card) . = ..() @@ -345,10 +242,8 @@ balloon_alert(user, "overloaded") obj_flags |= EMAGGED - for(var/datum/interaction_point/pickup_point in pickup_points) - pickup_point.type_filters += /mob/living - for(var/datum/interaction_point/dropoff_point in dropoff_points) - dropoff_point.type_filters += /mob/living + for(var/datum/manipulator_task/cargo/cargo_task in tasks) + cargo_task.type_filters += /mob/living return TRUE @@ -358,7 +253,7 @@ return ITEM_INTERACT_SUCCESS /obj/machinery/big_manipulator/can_be_unfasten_wrench(mob/user, silent) - if(current_task != CURRENT_TASK_NONE || on) + if(on || stopping) to_chat(user, span_warning("[src] is activated!")) return FAILED_UNFASTEN return ..() @@ -366,11 +261,8 @@ /obj/machinery/big_manipulator/default_unfasten_wrench(mob/user, obj/item/wrench, time) . = ..() if(. == SUCCESSFUL_UNFASTEN) - if(anchored) // on anchoring, validate all points and remove invalid ones - validate_all_points() - update_hud() - else - remove_all_huds() + if(anchored) + validate_all_tasks() /obj/machinery/big_manipulator/screwdriver_act(mob/living/user, obj/item/tool) return default_deconstruction_screwdriver(user, tool) @@ -381,6 +273,21 @@ /obj/machinery/big_manipulator/item_interaction(mob/living/user, obj/item/tool, list/modifiers) if(user.combat_mode) return NONE + + if(istype(tool, /obj/item/disk/manipulator)) + if(on || stopping) + balloon_alert(user, "turn it off first!") + return ITEM_INTERACT_BLOCKING + if(task_disk) + task_disk.forceMove(drop_location()) + task_disk = null + if(!user.transferItemToLoc(tool, src)) + return ITEM_INTERACT_BLOCKING + task_disk = tool + balloon_alert(user, "disk inserted") + SStgui.update_uis(src) + return ITEM_INTERACT_SUCCESS + if(!panel_open || !is_wire_tool(tool)) return NONE wires.interact(user) @@ -391,7 +298,7 @@ process_upgrades() /obj/machinery/big_manipulator/mouse_drop_dragged(atom/drop_point, mob/user, src_location, over_location, params) - if(current_task != CURRENT_TASK_NONE) + if(on || stopping) balloon_alert(user, "turn it off first!") return @@ -409,7 +316,7 @@ poor_monkey.forceMove(drop_point) /obj/machinery/big_manipulator/mouse_drop_receive(atom/monkey, mob/user, params) - if(current_task != CURRENT_TASK_NONE) + if(on || stopping) balloon_alert(user, "turn it off first!") return @@ -470,8 +377,6 @@ if(!user) on = newly_on - if(!on) - remove_all_huds() return if(newly_on) @@ -483,7 +388,7 @@ balloon_alert(user, "anchor first!") return - validate_all_points() + validate_all_tasks() on = newly_on SStgui.update_uis(src) @@ -493,28 +398,21 @@ drop_held_atom() on = newly_on next_cycle_scheduled = FALSE - // Set stopping task instead of ending current task immediately - if(current_task != CURRENT_TASK_NONE && current_task != CURRENT_TASK_STOPPING) - start_task(CURRENT_TASK_STOPPING, 0) - // Schedule automatic completion of stopping task + if(current_task != null && !stopping) + stopping = TRUE addtimer(CALLBACK(src, PROC_REF(complete_stopping_task)), 1 SECONDS) else - end_current_task() + stopping = FALSE + unregister_task_turf_signals() + waiting_for_signal = FALSE SStgui.update_uis(src) -/obj/machinery/big_manipulator/proc/validate_all_points() - for(var/datum/interaction_point/point in pickup_points) - if(!point.is_valid()) - pickup_points -= point - qdel(point) - - for(var/datum/interaction_point/point in dropoff_points) - if(!point.is_valid()) - dropoff_points -= point - qdel(point) - - if(is_operational) - update_hud() +/// Validates all cargo tasks, removing those on closed turfs. +/obj/machinery/big_manipulator/proc/validate_all_tasks() + for(var/datum/manipulator_task/cargo/cargo_task in tasks) + if(!cargo_task.is_valid()) + tasks -= cargo_task + qdel(cargo_task) /// Attempts to press the power button. /obj/machinery/big_manipulator/proc/try_press_on(mob/living/carbon/human/user) @@ -522,8 +420,7 @@ balloon_alert(user, "unresponsive!") return - // Reject activation during stopping task - if(current_task == CURRENT_TASK_STOPPING) + if(stopping) balloon_alert(user, "stopping in progress!") return @@ -533,14 +430,6 @@ else balloon_alert(user, "deactivated") -/// Drop the held atom. -/obj/machinery/big_manipulator/proc/drop_held_atom() - if(isnull(held_object)) - return - var/obj/obj_resolve = held_object?.resolve() - obj_resolve?.forceMove(get_turf(obj_resolve)) - finish_manipulation(TRANSFER_TYPE_DROPOFF) // MCBALAAM TODO - /obj/machinery/big_manipulator/ui_interact(mob/user, datum/tgui/ui) if(id_lock) to_chat(user, span_warning("[src] is locked behind ID authentication!")) @@ -558,78 +447,105 @@ /obj/machinery/big_manipulator/ui_data(mob/user) var/list/data = list() data["active"] = on - data["current_task"] = current_task - data["current_task_duration"] = current_task_duration + data["stopping"] = stopping + data["current_task"] = current_task ? REF(current_task) : null data["speed_multiplier"] = speed_multiplier data["min_speed_multiplier"] = min_speed_multiplier data["max_speed_multiplier"] = max_speed_multiplier data["manipulator_position"] = "[x],[y]" - data["pickup_tasking"] = pickup_tasking - data["dropoff_tasking"] = dropoff_tasking + data["tasking_strategy"] = tasking_strategy + data["has_monkey"] = !isnull(monkey_worker?.resolve()) + data["disk_inserted"] = !isnull(task_disk) + data["disk_read_only"] = task_disk?.read_only + data["disk_task_count"] = length(task_disk?.tasks_data) - var/list/pickup_points_data = list() - for(var/datum/interaction_point/point in pickup_points) - var/list/point_data = list() - point_data["name"] = point.name - point_data["id"] = REF(point) - var/turf/resolved_turf = point.interaction_turf - point_data["turf"] = resolved_turf ? "[resolved_turf.x],[resolved_turf.y]" : "0,0" - point_data["mode"] = "PICK" - var/list/filter_names = list() - for(var/obj/item/some_path as anything in point.atom_filters) - filter_names += some_path::name - point_data["item_filters"] = filter_names - point_data["filters_status"] = point.should_use_filters - point_data["filtering_mode"] = point.filtering_mode - point_data["worker_interaction"] = point.worker_interaction - point_data["overflow_status"] = point.overflow_status - point_data["worker_use_rmb"] = point.worker_use_rmb - point_data["worker_combat_mode"] = point.worker_combat_mode - point_data["throw_range"] = point.throw_range + var/list/tasks_data = list() + for(var/datum/manipulator_task/task in tasks) + var/list/td = list() + td["name"] = task.name + td["id"] = REF(task) - var/list/settings_list_pick = list() - for(var/datum/manipulator_priority/pr_pick in point.interaction_priorities) - var/list/entry_pick = list() - entry_pick["name"] = pr_pick.name - entry_pick["active"] = pr_pick.active - settings_list_pick += list(entry_pick) - point_data["settings_list"] = settings_list_pick - pickup_points_data += list(point_data) - data["pickup_points"] = pickup_points_data + if(istype(task, /datum/manipulator_task/cargo/pickup)) + td["task_type"] = TASK_TYPE_PICKUP + var/datum/manipulator_task/cargo/pickup/t = task + td["turf"] = "[t.offset_dx],[t.offset_dy]" + td["filters_status"] = t.should_use_filters + td["filtering_mode"] = t.filtering_mode + td["item_filters"] = _collect_filter_names(t.atom_filters) + td["settings_list"] = _collect_priorities(t.interaction_priorities) + td["pickup_eagerness"] = t.pickup_eagerness - var/list/dropoff_points_data = list() - for(var/datum/interaction_point/point in dropoff_points) - var/list/point_data = list() - point_data["name"] = point.name - point_data["id"] = REF(point) - var/turf/resolved_turf = point.interaction_turf - point_data["turf"] = resolved_turf ? "[resolved_turf.x],[resolved_turf.y]" : "0,0" - point_data["mode"] = point.interaction_mode - var/list/filter_names = list() - for(var/obj/item/some_path as anything in point.atom_filters) - filter_names += some_path::name - point_data["item_filters"] = filter_names - point_data["filters_status"] = point.should_use_filters - point_data["filtering_mode"] = point.filtering_mode - point_data["worker_interaction"] = point.worker_interaction - point_data["overflow_status"] = point.overflow_status - point_data["worker_use_rmb"] = point.worker_use_rmb - point_data["worker_combat_mode"] = point.worker_combat_mode - point_data["throw_range"] = point.throw_range - point_data["use_post_interaction"] = point.use_post_interaction + else if(istype(task, /datum/manipulator_task/cargo/dropoff_base/drop)) + td["task_type"] = TASK_TYPE_DROP + var/datum/manipulator_task/cargo/dropoff_base/drop/t = task + td["turf"] = "[t.offset_dx],[t.offset_dy]" + td["filters_status"] = t.should_use_filters + td["filtering_mode"] = t.filtering_mode + td["item_filters"] = _collect_filter_names(t.atom_filters) + td["settings_list"] = _collect_priorities(t.interaction_priorities) + td["overflow_status"] = t.overflow_status - var/list/settings_list_drop = list() - for(var/datum/manipulator_priority/pr_drop in point.interaction_priorities) - var/list/entry_drop = list() - entry_drop["name"] = pr_drop.name - entry_drop["active"] = pr_drop.active - settings_list_drop += list(entry_drop) - point_data["settings_list"] = settings_list_drop - dropoff_points_data += list(point_data) - data["dropoff_points"] = dropoff_points_data + else if(istype(task, /datum/manipulator_task/cargo/dropoff_base/throw)) + td["task_type"] = TASK_TYPE_THROW + var/datum/manipulator_task/cargo/dropoff_base/throw/t = task + td["turf"] = "[t.offset_dx],[t.offset_dy]" + td["filters_status"] = t.should_use_filters + td["filtering_mode"] = t.filtering_mode + td["item_filters"] = _collect_filter_names(t.atom_filters) + td["settings_list"] = _collect_priorities(t.interaction_priorities) + td["throw_range"] = t.throw_range + else if(istype(task, /datum/manipulator_task/cargo/dropoff_base/use)) + td["task_type"] = TASK_TYPE_USE + var/datum/manipulator_task/cargo/dropoff_base/use/t = task + td["turf"] = "[t.offset_dx],[t.offset_dy]" + td["filters_status"] = t.should_use_filters + td["filtering_mode"] = t.filtering_mode + td["item_filters"] = _collect_filter_names(t.atom_filters) + td["settings_list"] = _collect_priorities(t.interaction_priorities) + td["worker_interaction"] = t.worker_interaction + td["use_post_interaction"] = t.use_post_interaction + td["worker_use_rmb"] = t.worker_use_rmb + td["worker_combat_mode"] = t.worker_combat_mode + + else if(istype(task, /datum/manipulator_task/cargo/interact)) + td["task_type"] = TASK_TYPE_INTERACT + var/datum/manipulator_task/cargo/interact/t = task + td["turf"] = "[t.offset_dx],[t.offset_dy]" + td["filters_status"] = t.should_use_filters + td["filtering_mode"] = t.filtering_mode + td["item_filters"] = _collect_filter_names(t.atom_filters) + td["settings_list"] = _collect_priorities(t.interaction_priorities) + td["worker_interaction"] = t.worker_interaction + td["use_post_interaction"] = t.use_post_interaction + td["worker_use_rmb"] = t.worker_use_rmb + td["worker_combat_mode"] = t.worker_combat_mode + + else if(istype(task, /datum/manipulator_task/simple/wait)) + td["task_type"] = TASK_TYPE_WAIT + var/datum/manipulator_task/simple/wait/t = task + td["time"] = t.time_seconds + + tasks_data += list(td) + + data["tasks_data"] = tasks_data return data +/obj/machinery/big_manipulator/proc/_collect_filter_names(list/filters) + var/list/names = list() + for(var/atom/f as anything in filters) + names += initial(f.name) + return names + +/obj/machinery/big_manipulator/proc/_collect_priorities(list/priorities) + var/list/out = list() + for(var/datum/manipulator_priority/pr in priorities) + var/list/entry = list() + entry["name"] = pr.name + entry["active"] = pr.active + out += list(entry) + return out + /obj/machinery/big_manipulator/ui_act(action, params, datum/tgui/ui) . = ..() if(.) @@ -644,41 +560,29 @@ drop_held_atom() return TRUE - if("create_pickup_point") - create_new_interaction_point(ui.user, null, list(), FALSE, null, TRANSFER_TYPE_PICKUP) + if("create_task") + create_new_task(ui.user, params["task_type"]) + maybe_wake() return TRUE - if("create_dropoff_point") - create_new_interaction_point(ui.user, null, list(), FALSE, INTERACT_DROP, TRANSFER_TYPE_DROPOFF) + if("reset_tasking_index") + master_tasking.current_index = 1 + balloon_alert(ui.user, "tasking index reset") + maybe_wake() return TRUE - if("reset_tasking_Pickup Points") - pickup_strategy.current_index = 1 - balloon_alert(ui.user, "index reset") - return TRUE - - if("reset_tasking_Dropoff Points") - dropoff_strategy.current_index = 1 - balloon_alert(ui.user, "index reset") - return TRUE - - if("cycle_tasking_schedule") - var/new_schedule = params["new_schedule"] - - if(new_schedule in list(TASKING_ROUND_ROBIN, TASKING_STRICT_ROBIN, TASKING_PREFER_FIRST)) - var/is_pickup = params["is_pickup"] - if(is_pickup) - pickup_tasking = new_schedule - else - dropoff_tasking = new_schedule + if("cycle_tasking_strategy") + var/new_strategy = params["new_strategy"] + if(new_strategy in list(TASKING_SEQUENTIAL, TASKING_STRICT)) + tasking_strategy = new_strategy update_strategies() + maybe_wake() return TRUE if("adjust_interaction_speed") var/new_speed = text2num(params["new_speed"]) if(isnull(new_speed)) return FALSE - speed_multiplier = clamp(new_speed, min_speed_multiplier, max_speed_multiplier) return TRUE @@ -687,163 +591,331 @@ monkey_worker = null return TRUE - if("adjust_point_param") - return adjust_param_for_point(params["pointId"], params["param"], params["value"], ui.user) + if("adjust_task_param") + var/success = adjust_param_for_task(params["taskId"], params["param"], params["value"], ui.user) + if(success) + maybe_wake() + return success -/obj/machinery/big_manipulator/proc/adjust_param_for_point(point_ref, param, value, mob/user) - if(!param) // there may be no value if we're resetting stuff + if("disk_eject") + return eject_task_disk(ui.user) + + if("disk_read") + if(read_disk_tasks(ui.user)) + maybe_wake() + return TRUE + + if("disk_write") + return write_disk_tasks(ui.user) + + if("disk_clear") + return clear_disk_tasks(ui.user) + + +/obj/machinery/big_manipulator/proc/eject_task_disk(mob/user) + if(on || stopping) + balloon_alert(user, "turn it off first!") + return FALSE + if(!task_disk) + return FALSE + var/obj/item/disk/manipulator/ejectable_disk = task_disk + task_disk = null + if(istype(user) && user.put_in_hands(ejectable_disk)) + balloon_alert(user, "disk ejected") + else + ejectable_disk.forceMove(drop_location()) + balloon_alert(user, "disk dropped") + SStgui.update_uis(src) + return TRUE + +/obj/machinery/big_manipulator/proc/clear_disk_tasks(mob/user) + if(on || stopping) + balloon_alert(user, "turn it off first!") + return FALSE + if(!task_disk) + return FALSE + if(task_disk.read_only) + balloon_alert(user, "disk protected") + return FALSE + task_disk.set_tasks(list()) + balloon_alert(user, "cleared") + SStgui.update_uis(src) + return TRUE + +/obj/machinery/big_manipulator/proc/write_disk_tasks(mob/user) + if(on || stopping) + balloon_alert(user, "turn it off first!") + return FALSE + if(!task_disk) + return FALSE + if(task_disk.read_only) + balloon_alert(user, "disk protected") return FALSE - var/datum/interaction_point/target_point = locate(point_ref) in (pickup_points + dropoff_points) - if(!target_point) + var/list/out = list() + for(var/datum/manipulator_task/task as anything in tasks) + out += list(task.serialize()) + + task_disk.set_tasks(out) + balloon_alert(user, "written") + SStgui.update_uis(src) + return TRUE + +/obj/machinery/big_manipulator/proc/read_disk_tasks(mob/user) + if(on || stopping) + balloon_alert(user, "turn it off first!") + return FALSE + if(!task_disk) + return FALSE + + QDEL_LIST(tasks) + tasks = list() + current_task = null + + var/turf/base = get_turf(src) + var/datum/stock_part/servo/locate_servo = locate() in component_parts + var/manipulator_tier = locate_servo ? locate_servo.tier : 1 + + for(var/list/task_data as anything in task_disk.tasks_data) + if(length(tasks) >= interaction_point_limit) + break + if(!islist(task_data)) + continue + var/task_type = task_data["type"] + if(!ispath(task_type, /datum/manipulator_task)) + continue + var/datum/manipulator_task/new_task + if(ispath(task_type, /datum/manipulator_task/cargo)) + if(!base) + continue + var/list/offset = task_data["offset"] + if(!islist(offset)) + continue + var/dx = offset["dx"] + var/dy = offset["dy"] + if(!isnum(dx) || !isnum(dy)) + continue + if(dx < -1 || dx > 1 || dy < -1 || dy > 1) + continue + if(dx == 0 && dy == 0) + continue + var/turf/target_turf = locate(base.x + dx, base.y + dy, base.z) + if(!target_turf || isclosedturf(target_turf)) + continue + new_task = new task_type(target_turf, manipulator_tier, serialized_data = task_data) + if(istype(new_task, /datum/manipulator_task/cargo)) + var/datum/manipulator_task/cargo/c = new_task + c.offset_dx = dx + c.offset_dy = dy + else + new_task = new task_type(serialized_data = task_data) + if(!new_task || QDELETED(new_task)) + continue + tasks += new_task + + process_upgrades() + validate_all_tasks() + balloon_alert(user, "loaded") + SStgui.update_uis(src) + return TRUE + +/obj/machinery/big_manipulator/proc/adjust_param_for_task(task_ref, param, value, mob/user) + if(!param) + return FALSE + + var/datum/manipulator_task/target_task = locate(task_ref) in tasks + if(!target_task) return FALSE switch(param) if("set_name") - target_point.name = sanitize_name(value, allow_numbers = TRUE) - return TRUE - - if("toggle_priority") - return target_point.tick_priority_by_index(value) - - if("remove_point") - pickup_points.Remove(target_point) - dropoff_points.Remove(target_point) // one'll hit for sure - update_hud() - qdel(target_point) - return TRUE - - if("reset_atom_filters") - target_point.atom_filters = list() - return TRUE - - if("cycle_dropoff_point_interaction") - target_point.interaction_mode = cycle_value(target_point.interaction_mode, monkey_worker ? list(INTERACT_DROP, INTERACT_THROW, INTERACT_USE) : list(INTERACT_DROP, INTERACT_THROW)) - var/datum/stock_part/servo/locate_servo = locate() in component_parts - var/manipulator_tier = locate_servo ? locate_servo.tier : 1 - target_point.interaction_priorities = target_point.fill_priority_list(manipulator_tier) - return TRUE - - if("toggle_filter_skip") - target_point.should_use_filters = !target_point.should_use_filters - return TRUE - - if("cycle_pickup_point_type") - target_point.filtering_mode = cycle_value(target_point.filtering_mode, obj_flags & EMAGGED ? list(TAKE_ITEMS, TAKE_CLOSETS, TAKE_HUMANS) : list(TAKE_ITEMS, TAKE_CLOSETS)) - return TRUE - - if("cycle_worker_interaction") - target_point.worker_interaction = cycle_value(target_point.worker_interaction, list(WORKER_NORMAL_USE, WORKER_SINGLE_USE, WORKER_EMPTY_USE)) - return TRUE - - if("cycle_overflow_status") - target_point.overflow_status = cycle_value(target_point.overflow_status, list(POINT_OVERFLOW_ALLOWED, POINT_OVERFLOW_FILTERS, POINT_OVERFLOW_HELD, POINT_OVERFLOW_FORBIDDEN)) - return TRUE - - if("cycle_throw_range") - target_point.throw_range = cycle_value(target_point.throw_range, list(1, 2, 3, 4, 5, 6, 7)) - return TRUE - - if("cycle_post_interaction") - target_point.use_post_interaction = cycle_value(target_point.use_post_interaction, list(POST_INTERACTION_DROP_AT_POINT, POST_INTERACTION_DROP_AT_MACHINE, POST_INTERACTION_DROP_NEXT_FITTING, POST_INTERACTION_WAIT)) - return TRUE - - if("add_atom_filter_from_held") - var/obj/item/held_item = user.get_active_held_item() - - if(!held_item) + if(!value) return FALSE - - for(var/filter_path in target_point.atom_filters) - if(istype(held_item, filter_path)) - return FALSE - - target_point.atom_filters += held_item.type + target_task.name = sanitize_name(value, allow_numbers = TRUE) return TRUE - if("delete_filter") - target_point.atom_filters.Cut(value, value + 1) + if("set_wait_time") + if(!istype(target_task, /datum/manipulator_task/simple/wait)) + return FALSE + var/datum/manipulator_task/simple/wait/t = target_task + t.time_seconds = clamp(text2num(value), 1, 60) return TRUE - if("toggle_worker_rmb") - target_point.worker_use_rmb = !target_point.worker_use_rmb + if("remove_task") + tasks.Remove(target_task) + qdel(target_task) return TRUE - if("toggle_worker_combat") - target_point.worker_combat_mode = !target_point.worker_combat_mode + if("move_up") + var/idx = tasks.Find(target_task) + if(idx <= 1) + return FALSE + tasks.Swap(idx, idx - 1) return TRUE - if("priority_move_up") - return target_point.move_priority_up_by_index(value) + if("move_down") + var/idx = tasks.Find(target_task) + if(idx >= length(tasks)) + return FALSE + tasks.Swap(idx, idx + 1) + return TRUE if("move_to") + if(!istype(target_task, /datum/manipulator_task/cargo)) + return FALSE + var/datum/manipulator_task/cargo/cargo_task = target_task var/button_number = text2num(value["buttonNumber"]) - + if(button_number < 1 || button_number > 9) + return var/dx = ((button_number - 1) % 3) - 1 var/dy = 1 - round((button_number - 1) / 3) - var/turf/new_turf = locate(x + dx, y + dy, z) if(!new_turf || isclosedturf(new_turf)) return FALSE - - target_point.interaction_turf = new_turf - update_hud() + cargo_task.interaction_turf = new_turf + cargo_task.offset_dx = dx + cargo_task.offset_dy = dy return TRUE -/// Cycles the given value in the given list. Retuns the next value in the list, or the first one if the list isn't long enough. + if("toggle_filter_skip") + if(!istype(target_task, /datum/manipulator_task/cargo)) + return FALSE + var/datum/manipulator_task/cargo/ct = target_task + ct.should_use_filters = !ct.should_use_filters + return TRUE + + if("reset_atom_filters") + if(!istype(target_task, /datum/manipulator_task/cargo)) + return FALSE + var/datum/manipulator_task/cargo/ct = target_task + ct.atom_filters = list() + return TRUE + + if("add_atom_filter_from_held") + if(!istype(target_task, /datum/manipulator_task/cargo)) + return FALSE + var/datum/manipulator_task/cargo/ct = target_task + var/obj/item/held_item = user.get_active_held_item() + if(!held_item) + return FALSE + for(var/filter_path in ct.atom_filters) + if(istype(held_item, filter_path)) + return FALSE + ct.atom_filters += held_item.type + return TRUE + + if("delete_filter") + if(!istype(target_task, /datum/manipulator_task/cargo)) + return FALSE + var/datum/manipulator_task/cargo/ct = target_task + ct.atom_filters.Cut(value, value + 1) + return TRUE + + if("cycle_filtering_mode") + if(!istype(target_task, /datum/manipulator_task/cargo)) + return FALSE + var/datum/manipulator_task/cargo/ct = target_task + ct.filtering_mode = cycle_value(ct.filtering_mode, obj_flags & EMAGGED ? list(TAKE_ITEMS, TAKE_CLOSETS, TAKE_HUMANS) : list(TAKE_ITEMS, TAKE_CLOSETS)) + return TRUE + + if("toggle_priority") + if(!istype(target_task, /datum/manipulator_task/cargo)) + return FALSE + var/datum/manipulator_task/cargo/current_task = target_task + return current_task.tick_priority_by_index(value) + + if("priority_move_up") + if(!istype(target_task, /datum/manipulator_task/cargo)) + return FALSE + var/datum/manipulator_task/cargo/current_task = target_task + return current_task.move_priority_up_by_index(value) + + if("cycle_pickup_eagerness") + if(!istype(target_task, /datum/manipulator_task/cargo/pickup)) + return FALSE + var/datum/manipulator_task/cargo/pickup/cycle_target_task = target_task + cycle_target_task.pickup_eagerness = cycle_value(cycle_target_task.pickup_eagerness, list(PICKUP_CAN_WAIT, PICKUP_EAGER)) + return TRUE + + if("cycle_overflow_status") + if(!istype(target_task, /datum/manipulator_task/cargo/dropoff_base/drop)) + return FALSE + var/datum/manipulator_task/cargo/dropoff_base/drop/cycle_target_task = target_task + cycle_target_task.overflow_status = cycle_value(cycle_target_task.overflow_status, list(POINT_OVERFLOW_ALLOWED, POINT_OVERFLOW_FILTERS, POINT_OVERFLOW_HELD, POINT_OVERFLOW_FORBIDDEN)) + return TRUE + + if("cycle_throw_range") + if(!istype(target_task, /datum/manipulator_task/cargo/dropoff_base/throw)) + return FALSE + var/datum/manipulator_task/cargo/dropoff_base/throw/cycle_target_task = target_task + cycle_target_task.throw_range = cycle_value(cycle_target_task.throw_range, list(1, 2, 3, 4, 5, 6, 7)) + return TRUE + + if("cycle_worker_interaction") + var/list/vals = list(WORKER_NORMAL_USE, WORKER_SINGLE_USE, WORKER_EMPTY_USE) + if(istype(target_task, /datum/manipulator_task/cargo/dropoff_base/use)) + var/datum/manipulator_task/cargo/dropoff_base/use/cycle_target_task = target_task + cycle_target_task.worker_interaction = cycle_value(cycle_target_task.worker_interaction, vals) + return TRUE + if(istype(target_task, /datum/manipulator_task/cargo/interact)) + var/datum/manipulator_task/cargo/interact/cycle_target_task = target_task + cycle_target_task.worker_interaction = cycle_value(cycle_target_task.worker_interaction, vals) + return TRUE + return FALSE + + if("cycle_post_interaction") + var/list/vals = list(POST_INTERACTION_DROP_AT_POINT, POST_INTERACTION_DROP_AT_MACHINE, POST_INTERACTION_DROP_NEXT_FITTING, POST_INTERACTION_WAIT) + if(istype(target_task, /datum/manipulator_task/cargo/dropoff_base/use)) + var/datum/manipulator_task/cargo/dropoff_base/use/cycle_target_task = target_task + cycle_target_task.use_post_interaction = cycle_value(cycle_target_task.use_post_interaction, vals) + return TRUE + if(istype(target_task, /datum/manipulator_task/cargo/interact)) + var/datum/manipulator_task/cargo/interact/cycle_target_task = target_task + cycle_target_task.use_post_interaction = cycle_value(cycle_target_task.use_post_interaction, vals) + return TRUE + return FALSE + + if("toggle_worker_rmb") + if(istype(target_task, /datum/manipulator_task/cargo/dropoff_base/use)) + var/datum/manipulator_task/cargo/dropoff_base/use/cycle_target_task = target_task + cycle_target_task.worker_use_rmb = !cycle_target_task.worker_use_rmb + return TRUE + if(istype(target_task, /datum/manipulator_task/cargo/interact)) + var/datum/manipulator_task/cargo/interact/cycle_target_task = target_task + cycle_target_task.worker_use_rmb = !cycle_target_task.worker_use_rmb + return TRUE + return FALSE + + if("toggle_worker_combat") + if(istype(target_task, /datum/manipulator_task/cargo/dropoff_base/use)) + var/datum/manipulator_task/cargo/dropoff_base/use/cycle_target_task = target_task + cycle_target_task.worker_combat_mode = !cycle_target_task.worker_combat_mode + return TRUE + if(istype(target_task, /datum/manipulator_task/cargo/interact)) + var/datum/manipulator_task/cargo/interact/cycle_target_task = target_task + cycle_target_task.worker_combat_mode = !cycle_target_task.worker_combat_mode + return TRUE + return FALSE + +/// Cycles the given value in the given list. /obj/machinery/big_manipulator/proc/cycle_value(current_value, list/possible_values) var/current_index = possible_values.Find(current_value) if(current_index == 0) return possible_values[1] + return possible_values[(current_index % length(possible_values)) + 1] - var/next_index = (current_index % length(possible_values)) + 1 - return possible_values[next_index] - -/// Begins a new task with the specified type and duration -/obj/machinery/big_manipulator/proc/start_task(task_type, duration) - if(current_task == CURRENT_TASK_STOPPING) - return - - end_current_task() // ends any previous task first (momentarily sets IDLE) - current_task_start_time = world.time - current_task_duration = duration - current_task = task_type - SStgui.update_uis(src) - -/// Ends the current task -/obj/machinery/big_manipulator/proc/end_current_task() - current_task_start_time = 0 - current_task_duration = 0 - if(current_task == CURRENT_TASK_STOPPING) - current_task = CURRENT_TASK_NONE - SStgui.update_uis(src) // Update UI immediately - -/// Completes the stopping task and transitions to TASK_NONE -/obj/machinery/big_manipulator/proc/complete_stopping_task() - on = FALSE - next_cycle_scheduled = FALSE - end_current_task() - SStgui.update_uis(src) - -/obj/machinery/big_manipulator/proc/remove_all_huds() - var/image/main_hud = hud_list[BIG_MANIP_HUD] - if(main_hud) - main_hud.overlays.Cut() - main_hud.loc = null - - hud_points.Cut() - set_hud_image_inactive(BIG_MANIP_HUD) +/// Retries the task loop if we're waiting for a signal and the machine is on. +/obj/machinery/big_manipulator/proc/maybe_wake() + if(on && !stopping && waiting_for_signal) + something_happened() /obj/machinery/big_manipulator/proc/update_strategies() - pickup_strategy = create_strategy(pickup_tasking) - dropoff_strategy = create_strategy(dropoff_tasking) + master_tasking = create_strategy(tasking_strategy) -/obj/machinery/big_manipulator/proc/create_strategy(tasking_mode) - switch(tasking_mode) - if(TASKING_PREFER_FIRST) - return new /datum/tasking_strategy/prefer_first() - if(TASKING_ROUND_ROBIN) - return new /datum/tasking_strategy/round_robin() - if(TASKING_STRICT_ROBIN) - return new /datum/tasking_strategy/strict_robin() - return new /datum/tasking_strategy/prefer_first() +/obj/machinery/big_manipulator/proc/create_strategy(strategy_mode) + switch(strategy_mode) + if(TASKING_SEQUENTIAL) + return new /datum/tasking_strategy/sequential() + if(TASKING_STRICT) + return new /datum/tasking_strategy/strict() + return new /datum/tasking_strategy/sequential() diff --git a/code/game/machinery/big_manipulator/big_manipulator_interactions.dm b/code/game/machinery/big_manipulator/big_manipulator_interactions.dm index 900f659c5ac..01500efdd5a 100644 --- a/code/game/machinery/big_manipulator/big_manipulator_interactions.dm +++ b/code/game/machinery/big_manipulator/big_manipulator_interactions.dm @@ -1,55 +1,42 @@ -/// Selects which atom to pick up from this point for interaction with available dropoff points based on the dropoff points. -/obj/machinery/big_manipulator/proc/find_pickup_candidate_for_pickup_point(datum/interaction_point/pickup_point) - if(!pickup_point) - return null +/// We have no tasks to execute for some reason. Waits for a turf signal to retry. +/obj/machinery/big_manipulator/proc/nothing_ever_happens() + if(stopping) + complete_stopping_task() + return FALSE - var/turf/pickup_turf = pickup_point.interaction_turf - if(!pickup_turf) - return null + current_task = null + waiting_for_signal = TRUE + register_task_turf_signals() - var/list/candidates = list() - for(var/atom/movable/candidate as anything in pickup_turf.contents) - if(candidate.anchored || HAS_TRAIT(candidate, TRAIT_NODROP) || move_resist > MOVE_FORCE_STRONG) - continue + return FALSE - if(!pickup_point.check_filters_for_atom(candidate)) - continue +/// A signal ran or some settings changed; checking if we can run the tasks now. +/obj/machinery/big_manipulator/proc/something_happened() + next_cycle_scheduled = FALSE + step_tasks() - for(var/datum/interaction_point/dest_point as anything in dropoff_points) - if(!dest_point || !dest_point.is_valid()) - continue - if(!dest_point.check_filters_for_atom(candidate)) - continue - if(dest_point.is_available(TRANSFER_TYPE_DROPOFF, candidate)) - candidates += candidate - break - - if(!length(candidates)) - return null - - return pickup_strategy.get_next_candidate(candidates) - -/// Calculates the next interaction point the manipulator should transfer the item to or pick up it from. -/obj/machinery/big_manipulator/proc/find_next_point(transfer_type) - if(!transfer_type) - return NONE - - var/atom/movable/target = held_object?.resolve() - if(isnull(target) && transfer_type == TRANSFER_TYPE_DROPOFF) - return NONE - - var/list/interaction_points = transfer_type == TRANSFER_TYPE_DROPOFF ? dropoff_points : pickup_points - if(!length(interaction_points)) - return NONE - - var/datum/tasking_strategy/strategy = transfer_type == TRANSFER_TYPE_DROPOFF ? dropoff_strategy : pickup_strategy - var/datum/callback/availability_callback = transfer_type == TRANSFER_TYPE_DROPOFF ? CALLBACK(src, PROC_REF(check_dropoff_availability)) : CALLBACK(src, PROC_REF(check_pickup_availability)) - - return strategy.get_next_available(interaction_points, target, transfer_type, availability_callback) +/// Runs the next task. Or doesn't. +/obj/machinery/big_manipulator/proc/step_tasks() + if(!on || stopping) + return + next_cycle_scheduled = FALSE + if(waiting_for_signal) + unregister_task_turf_signals() + waiting_for_signal = FALSE + if(!length(tasks)) + nothing_ever_happens() + return + var/datum/manipulator_task/next_task = master_tasking.get_next_task(tasks, src) + if(!next_task) + nothing_ever_happens() + return + current_task = next_task + SStgui.update_uis(src) + next_task.run_task(src) /// Attempts to launch the work cycle. Should only be ran on pressing the "Run" button. /obj/machinery/big_manipulator/proc/try_kickstart(mob/user) - if(!on || !anchored || IS_BUSY) + if(!on || !anchored || stopping || current_task != null) return FALSE if(!use_energy(active_power_usage, force = FALSE)) @@ -58,208 +45,62 @@ return FALSE next_cycle_scheduled = FALSE - run_pickup_phase() + step_tasks() -/// Safely schedules the next cycle attempt to prevent overlapping. -/obj/machinery/big_manipulator/proc/schedule_next_cycle() - if(next_cycle_scheduled || IS_STOPPING) - return - - // Allow scheduling if manipulator is idle, none, or if we have a held object (need to drop it off) - if(current_task != CURRENT_TASK_IDLE && current_task != CURRENT_TASK_NONE && !held_object) +/// Safely schedules the next step to prevent overlapping. +/obj/machinery/big_manipulator/proc/schedule_next_cycle(time_seconds = BASE_INTERACTION_TIME) + if(next_cycle_scheduled || stopping) return next_cycle_scheduled = TRUE - if(held_object) - run_dropoff_phase() - else - run_pickup_phase() + addtimer(CALLBACK(src, PROC_REF(step_tasks)), time_seconds) -/// Handles the common pattern of waiting and scheduling next cycle when no work can be done. -/obj/machinery/big_manipulator/proc/handle_no_work_available() - // If we're stopping, don't schedule next cycle - if(IS_STOPPING) - complete_stopping_task() - return FALSE - - current_task = CURRENT_TASK_IDLE - - addtimer(CALLBACK(src, PROC_REF(schedule_next_cycle)), CYCLE_SKIP_TIMEOUT) - return FALSE - -/obj/machinery/big_manipulator/proc/check_pickup_availability(datum/interaction_point/point, atom/movable/target, transfer_type) - if(!point) - return FALSE - - var/turf/pickup_turf = point.interaction_turf - if(!pickup_turf) - return FALSE - - for(var/atom/movable/candidate as anything in pickup_turf.contents) - if(!candidate.anchored && !HAS_TRAIT(candidate, TRAIT_NODROP)) - return TRUE - - return FALSE - -/obj/machinery/big_manipulator/proc/check_dropoff_availability(datum/interaction_point/point, atom/movable/target, transfer_type) - return point.is_available(transfer_type, target) - -/// Attempts to run the pickup phase. Selects the next origin point and attempts to pick up an item from it. -/obj/machinery/big_manipulator/proc/run_pickup_phase() - if(!on || IS_STOPPING) +/// Rotates the manipulator arm to face the target task's turf. +/obj/machinery/big_manipulator/proc/rotate_to_point(datum/manipulator_task/cargo/target_task, callback_object, callback) + if(stopping) return - next_cycle_scheduled = FALSE - - var/datum/interaction_point/origin_point = find_next_point(TRANSFER_TYPE_PICKUP) - - if(!origin_point) - return handle_no_work_available() - - rotate_to_point(origin_point, PROC_REF(try_interact_with_origin_point), CURRENT_TASK_MOVING_PICKUP) - return TRUE - -/// Attempts to interact with the origin point (pick up the object) -/obj/machinery/big_manipulator/proc/try_interact_with_origin_point(datum/interaction_point/origin_point, hand_is_empty = FALSE) - // If we're stopping, just finish the task and shut down - if(IS_STOPPING) - complete_stopping_task() - return - - if(!origin_point.interaction_turf) - return handle_no_work_available() - - var/atom/movable/selected = find_pickup_candidate_for_pickup_point(origin_point) // find a suitable item that matches available destinations - if(!selected) - return handle_no_work_available() - - if(selected.anchored || HAS_TRAIT(selected, TRAIT_NODROP)) - return handle_no_work_available() - - if(isitem(selected)) - var/obj/item/selected_item = selected - if(selected_item.item_flags & (ABSTRACT|DROPDEL)) - return handle_no_work_available() - - start_task(CURRENT_TASK_INTERACTING, 0.2 SECONDS) - interact_with_origin_point(selected, hand_is_empty) - return TRUE - -/// Attempts to start a work cycle (pick up the object) -/obj/machinery/big_manipulator/proc/interact_with_origin_point(atom/movable/target, hand_is_empty = FALSE) - if(!hand_is_empty) - target.forceMove(src) - held_object = WEAKREF(target) - manipulator_arm.update_claw(held_object) - - // Schedule the dropoff phase after a successful pickup to avoid overlapping tasks - if(!hand_is_empty) - schedule_next_cycle() - -/obj/machinery/big_manipulator/proc/run_dropoff_phase() - // Find the next available destination point that can accept the held item - var/datum/interaction_point/destination_point = find_next_point(TRANSFER_TYPE_DROPOFF) - - next_cycle_scheduled = FALSE - - if(!destination_point) - return handle_no_work_available() - - rotate_to_point(destination_point, PROC_REF(try_interact_with_destination_point), CURRENT_TASK_MOVING_DROPOFF) - return TRUE - -/// Attempts to interact with the destination point (drop/use/throw the object) -/obj/machinery/big_manipulator/proc/try_interact_with_destination_point(datum/interaction_point/destination_point, hand_is_empty = FALSE) - // If we're stopping, just finish the task and shut down - if(IS_STOPPING) - complete_stopping_task() + if(!target_task) return FALSE - start_task(CURRENT_TASK_INTERACTING, 0.2 SECONDS) - - if(hand_is_empty) - use_thing_with_empty_hand(destination_point) - return TRUE - - var/obj/actual_held_object = held_object?.resolve() - if(actual_held_object.loc != src) - handle_no_work_available() - return FALSE - - switch(destination_point.interaction_mode) - if(INTERACT_DROP) - try_drop_thing(destination_point) - if(INTERACT_USE) - try_use_thing(destination_point) - if(INTERACT_THROW) - throw_thing(destination_point) - - return TRUE - -/// Rotates the manipulator arm to face the target point. -/obj/machinery/big_manipulator/proc/rotate_to_point(datum/interaction_point/target_point, callback, type) - if(IS_STOPPING) - return - - if(!target_point) - return FALSE - - var/target_dir = get_dir(get_turf(src), target_point.interaction_turf) + var/target_dir = get_dir(get_turf(src), target_task.interaction_turf) var/target_angle = dir2angle(target_dir) var/current_angle = manipulator_arm.transform.get_angle() var/angle_diff = closer_angle_difference(current_angle, target_angle) var/num_rotations = round(abs(angle_diff) / 45) - var/total_rotation_time = num_rotations * BASE_INTERACTION_TIME / speed_multiplier - start_task(type == CURRENT_TASK_MOVING_PICKUP ? CURRENT_TASK_MOVING_PICKUP : CURRENT_TASK_MOVING_DROPOFF, total_rotation_time) - - // If the next point is on the same tile, we don't need to rotate at all if(!num_rotations) - addtimer(CALLBACK(src, callback, target_point), BASE_INTERACTION_TIME) + var/datum/callback/cb = CALLBACK(callback_object, callback, src) + cb.Invoke() return TRUE - // Breaking the angle up into 45 degree steps var/rotation_step = 45 * sign(angle_diff) - do_step_rotation(target_point, callback, current_angle, target_angle, rotation_step, 0, total_rotation_time) - + do_step_rotation(target_task, callback_object, callback, current_angle, target_angle, rotation_step) return TRUE /// Does a 45 degree step, animating the claw -/obj/machinery/big_manipulator/proc/do_step_rotation(datum/interaction_point/target_point, callback, current_angle, target_angle, rotation_step, elapsed_time, total_time) - if(IS_STOPPING) +/obj/machinery/big_manipulator/proc/do_step_rotation(datum/manipulator_task/cargo/target_task, callback_object, callback, current_angle, target_angle, rotation_step) + if(stopping) return - // Just making sure we're not there already var/angle_diff = closer_angle_difference(current_angle, target_angle) if(abs(angle_diff) < abs(rotation_step)) - // If this is the last step, doing a precise degree turn var/matrix/final_matrix = matrix() final_matrix.Turn(target_angle) animate(manipulator_arm, transform = final_matrix, time = BASE_INTERACTION_TIME / speed_multiplier) - addtimer(CALLBACK(src, callback, target_point), BASE_INTERACTION_TIME / speed_multiplier) + addtimer(CALLBACK(callback_object, callback, src), BASE_INTERACTION_TIME / speed_multiplier) return - // Animating a single rotation step - - // YES, this has to be done like that because byond or whatever is stupid and `animate`ing a 180+ degree turn - // fucking fails and squashes the icon vertically (or horizontally, whichever it feels like) instead - var/next_angle = current_angle + rotation_step var/matrix/next_matrix = matrix() next_matrix.Turn(next_angle) animate(manipulator_arm, transform = next_matrix, time = BASE_INTERACTION_TIME / speed_multiplier) - // Recursively planning the next step (yay recursion :yuppie: call me a madman I LOVE recursion) - elapsed_time += BASE_INTERACTION_TIME / speed_multiplier - addtimer(CALLBACK(src, PROC_REF(do_step_rotation), target_point, callback, next_angle, target_angle, rotation_step, elapsed_time, total_time), BASE_INTERACTION_TIME / speed_multiplier) + addtimer(CALLBACK(src, PROC_REF(do_step_rotation), target_task, callback_object, callback, next_angle, target_angle, rotation_step), BASE_INTERACTION_TIME / speed_multiplier) -/// Moves the item onto the turf. -/// -/// If the turf has an atom with fitting `atom_storage` that corresponds to the -/// priority settings, it will attempt to insert the held item. -/obj/machinery/big_manipulator/proc/try_drop_thing(datum/interaction_point/destination_point) - var/drop_endpoint = destination_point.find_type_priority() +/obj/machinery/big_manipulator/proc/try_drop_thing(datum/manipulator_task/cargo/dropoff_base/drop/destination_task) + var/drop_endpoint = destination_task.find_type_priority() var/obj/actual_held_object = held_object?.resolve() if(isnull(drop_endpoint)) @@ -268,46 +109,42 @@ var/atom/drop_target = drop_endpoint if(drop_target.atom_storage && actual_held_object && (!drop_target.atom_storage.attempt_insert(actual_held_object, override = TRUE, messages = FALSE))) actual_held_object.forceMove(drop_target.drop_location()) - finish_manipulation(TRANSFER_TYPE_DROPOFF) + finish_manipulation() return TRUE actual_held_object?.forceMove(drop_endpoint) - finish_manipulation(TRANSFER_TYPE_DROPOFF) + finish_manipulation() return TRUE -/// Attempts to use the held object on the atoms of the interaction turf. -/// -/// If the interaction turf has an atom that corresponds to the priority settings, -/// it will attempt to use the held item. If it doesn't, it will simply drop the item. -/obj/machinery/big_manipulator/proc/try_use_thing(datum/interaction_point/destination_point, work_done_at_point = FALSE) - if(IS_STOPPING) +/obj/machinery/big_manipulator/proc/try_use_thing(datum/manipulator_task/cargo/interact/destination_task, work_done_at_point = FALSE) + if(stopping) return var/obj/obj_resolve = held_object?.resolve() var/mob/living/carbon/human/species/monkey/monkey_resolve = monkey_worker?.resolve() - var/destination_turf = destination_point.interaction_turf + var/destination_turf = destination_task.interaction_turf if(!obj_resolve || QDELETED(obj_resolve) || obj_resolve.loc != src) - finish_manipulation(TRANSFER_TYPE_DROPOFF) + finish_manipulation() return FALSE if(!monkey_resolve || !destination_turf) - finish_manipulation(TRANSFER_TYPE_DROPOFF) + finish_manipulation() return FALSE - if(!(monkey_resolve.loc == src)) - finish_manipulation(TRANSFER_TYPE_DROPOFF) + if(monkey_resolve.loc != src) + finish_manipulation() return FALSE var/obj/item/held_item = obj_resolve - var/atom/type_to_use = destination_point.find_type_priority() + var/atom/type_to_use = destination_task.find_type_priority() if(isnull(type_to_use)) - check_for_cycle_end_drop(destination_point, FALSE, work_done_at_point) + check_for_cycle_end_drop(destination_task, FALSE, work_done_at_point) return FALSE - if(isitem(type_to_use) && !destination_point.check_filters_for_atom(type_to_use)) - check_for_cycle_end_drop(destination_point, FALSE, work_done_at_point) + if(isitem(type_to_use) && !destination_task.check_filters_for_atom(type_to_use)) + check_for_cycle_end_drop(destination_task, FALSE, work_done_at_point) return FALSE var/original_loc = held_item.loc @@ -316,109 +153,99 @@ if(held_item.GetComponent(/datum/component/two_handed)) held_item.attack_self(monkey_resolve) - var/use_rmb = destination_point.worker_use_rmb - var/use_combat = destination_point.worker_combat_mode - - monkey_resolve.combat_mode = use_combat - held_item.melee_attack_chain(monkey_resolve, type_to_use, list(RIGHT_CLICK = use_rmb ? TRUE : FALSE)) + monkey_resolve.combat_mode = destination_task.worker_combat_mode + held_item.melee_attack_chain(monkey_resolve, type_to_use, list(RIGHT_CLICK = destination_task.worker_use_rmb ? TRUE : FALSE)) monkey_resolve.combat_mode = FALSE do_attack_animation(destination_turf) manipulator_arm.do_attack_animation(destination_turf) - // if we destroyed the item while using it OR something else uncanny happened to it and it's GONE if(QDELETED(held_item) || !held_item || (held_item.loc != monkey_resolve && held_item.loc != original_loc)) held_object = null manipulator_arm.update_claw(null) - finish_manipulation(TRANSFER_TYPE_DROPOFF) + finish_manipulation() return TRUE if(held_item.loc == monkey_resolve) held_item.forceMove(original_loc) - check_for_cycle_end_drop(destination_point, TRUE, TRUE) + check_for_cycle_end_drop(destination_task, TRUE, TRUE) -/// Checks what should we do with the `held_object` after `USE`-ing it. -/obj/machinery/big_manipulator/proc/check_for_cycle_end_drop(datum/interaction_point/drop_point, item_used_this_iteration, work_done_at_point = FALSE) +/obj/machinery/big_manipulator/proc/check_for_cycle_end_drop(datum/manipulator_task/cargo/interact/destination_task, item_used_this_iteration, work_done_at_point = FALSE) var/obj/obj_resolve = held_object?.resolve() - var/turf/drop_turf = drop_point.interaction_turf + var/turf/drop_turf = destination_task.interaction_turf if(!obj_resolve || obj_resolve.loc != src || QDELETED(obj_resolve)) - finish_manipulation(TRANSFER_TYPE_DROPOFF) + finish_manipulation() return - if(drop_point.worker_interaction == WORKER_SINGLE_USE && item_used_this_iteration) + if(destination_task.worker_interaction == WORKER_SINGLE_USE && item_used_this_iteration) obj_resolve.forceMove(drop_turf) obj_resolve.dir = get_dir(get_turf(obj_resolve), get_turf(src)) - finish_manipulation(TRANSFER_TYPE_DROPOFF) + finish_manipulation() return - if(!on || drop_point.interaction_mode != INTERACT_USE) - finish_manipulation(TRANSFER_TYPE_DROPOFF) + if(!on) + finish_manipulation() return if(item_used_this_iteration) - addtimer(CALLBACK(src, PROC_REF(try_use_thing), drop_point, TRUE), BASE_INTERACTION_TIME * 2) + addtimer(CALLBACK(src, PROC_REF(try_use_thing), destination_task, TRUE), BASE_INTERACTION_TIME * 2) return - switch(drop_point.use_post_interaction) + drop_held_after_use(destination_task) + +/obj/machinery/big_manipulator/proc/drop_held_after_use(datum/manipulator_task/cargo/interact/destination_task) + var/obj/obj_resolve = held_object?.resolve() + var/turf/drop_turf = destination_task.interaction_turf + + switch(destination_task.use_post_interaction) if(POST_INTERACTION_DROP_AT_POINT) obj_resolve.forceMove(drop_turf) obj_resolve.dir = get_dir(get_turf(obj_resolve), get_turf(src)) - finish_manipulation(TRANSFER_TYPE_DROPOFF) - return + finish_manipulation() if(POST_INTERACTION_DROP_AT_MACHINE) obj_resolve.forceMove(get_turf(src)) - finish_manipulation(TRANSFER_TYPE_DROPOFF) - return + finish_manipulation() if(POST_INTERACTION_DROP_NEXT_FITTING) - var/datum/interaction_point/next = find_next_point(TRANSFER_TYPE_DROPOFF) - if(next) - rotate_to_point(next, PROC_REF(try_interact_with_destination_point), CURRENT_TASK_MOVING_DROPOFF) + var/datum/manipulator_task/next = master_tasking.get_next_task(tasks, src) + if(istype(next, /datum/manipulator_task/cargo/dropoff_base)) + rotate_to_point(next, next, TYPE_PROC_REF(/datum/manipulator_task/cargo/dropoff_base, try_dropoff)) return obj_resolve.forceMove(drop_turf) obj_resolve.dir = get_dir(get_turf(obj_resolve), get_turf(src)) - finish_manipulation(TRANSFER_TYPE_DROPOFF) - return - - if(POST_INTERACTION_WAIT) + finish_manipulation() + else schedule_next_cycle() - return - schedule_next_cycle() - -/// Throws the held object in the direction of the interaction point. -/obj/machinery/big_manipulator/proc/throw_thing(datum/interaction_point/drop_point) - var/drop_turf = drop_point.interaction_turf - var/item_throw_range = drop_point.throw_range +/obj/machinery/big_manipulator/proc/throw_thing(datum/manipulator_task/cargo/dropoff_base/throw/throw_task) + var/drop_turf = throw_task.interaction_turf var/atom/movable/held_atom = held_object?.resolve() held_atom.forceMove(drop_turf) do_attack_animation(drop_turf) manipulator_arm.do_attack_animation(drop_turf) - if(((isliving(held_atom))) && !(obj_flags & EMAGGED)) + if(isliving(held_atom) && !(obj_flags & EMAGGED)) held_atom.dir = get_dir(get_turf(held_atom), get_turf(src)) - finish_manipulation(TRANSFER_TYPE_DROPOFF) + finish_manipulation() return - held_atom.throw_at(get_edge_target_turf(get_turf(src), get_dir(get_turf(src), get_turf(held_atom))), item_throw_range, 2) - finish_manipulation(TRANSFER_TYPE_DROPOFF) + held_atom.throw_at(get_edge_target_turf(get_turf(src), get_dir(get_turf(src), get_turf(held_atom))), throw_task.throw_range, 2) + finish_manipulation() -/// Uses the empty hand to interact with objects -/obj/machinery/big_manipulator/proc/use_thing_with_empty_hand(datum/interaction_point/destination_point) +/obj/machinery/big_manipulator/proc/use_thing_with_empty_hand(datum/manipulator_task/cargo/interact/destination_task) var/mob/living/carbon/human/species/monkey/monkey_resolve = monkey_worker?.resolve() if(isnull(monkey_resolve)) - finish_manipulation(TRANSFER_TYPE_DROPOFF) + finish_manipulation() return - var/atom/type_to_use = destination_point.find_type_priority() + var/atom/type_to_use = destination_task.find_type_priority() if(isnull(type_to_use)) - check_end_of_use_for_use_with_empty_hand(destination_point, FALSE) + check_end_of_use_for_use_with_empty_hand(destination_task, FALSE) return - // We don't perform an unarmed attack on items because we pick them up duh if(isitem(type_to_use)) var/obj/item/interact_with_item = type_to_use var/resolve_loc = interact_with_item.loc @@ -426,37 +253,78 @@ interact_with_item.attack_self(monkey_resolve) interact_with_item.forceMove(resolve_loc) else + monkey_resolve.combat_mode = destination_task.worker_combat_mode monkey_resolve.UnarmedAttack(type_to_use) + monkey_resolve.combat_mode = FALSE - var/turf/dest_turf = destination_point.interaction_turf + var/turf/dest_turf = destination_task.interaction_turf if(dest_turf) do_attack_animation(dest_turf) manipulator_arm.do_attack_animation(dest_turf) - check_end_of_use_for_use_with_empty_hand(destination_point, TRUE) -/// Checks if we should continue using the empty hand after interaction -/obj/machinery/big_manipulator/proc/check_end_of_use_for_use_with_empty_hand(datum/interaction_point/destination_point, item_was_used = TRUE) - if(!on || (destination_point.worker_interaction != WORKER_EMPTY_USE && destination_point.interaction_mode == INTERACT_USE)) - finish_manipulation(TRANSFER_TYPE_DROPOFF) + check_end_of_use_for_use_with_empty_hand(destination_task, TRUE) + +/obj/machinery/big_manipulator/proc/check_end_of_use_for_use_with_empty_hand(datum/manipulator_task/cargo/interact/destination_task, item_was_used = TRUE) + if(!on || destination_task.worker_interaction != WORKER_EMPTY_USE) + finish_manipulation() return if(!item_was_used) - finish_manipulation(TRANSFER_TYPE_DROPOFF) + finish_manipulation() return - addtimer(CALLBACK(src, PROC_REF(use_thing_with_empty_hand), destination_point), BASE_INTERACTION_TIME) + addtimer(CALLBACK(src, PROC_REF(use_thing_with_empty_hand), destination_task), BASE_INTERACTION_TIME) -/// Completes the current manipulation action -/obj/machinery/big_manipulator/proc/finish_manipulation(transfer_type = TRANSFER_TYPE_DROPOFF) +/// Completes the current manipulation action and schedules the next step. +/obj/machinery/big_manipulator/proc/finish_manipulation() held_object = null manipulator_arm.update_claw(null) + current_task = null - end_current_task() + SStgui.update_uis(src) - if(IS_STOPPING) + if(stopping) complete_stopping_task() return - current_task = CURRENT_TASK_IDLE - schedule_next_cycle() + +/// Completes the stopping task and transitions to idle +/obj/machinery/big_manipulator/proc/complete_stopping_task() + on = FALSE + stopping = FALSE + next_cycle_scheduled = FALSE + current_task = null + unregister_task_turf_signals() + waiting_for_signal = FALSE + SStgui.update_uis(src) + +/// Registers enter/exit signals on all unique cargo task turfs. +/obj/machinery/big_manipulator/proc/register_task_turf_signals() + unregister_task_turf_signals() + for(var/datum/manipulator_task/cargo/task in tasks) + if(!task.interaction_turf || (task.interaction_turf in signal_turfs)) + continue + signal_turfs += task.interaction_turf + RegisterSignals(task.interaction_turf, list(COMSIG_ATOM_ENTERED, COMSIG_ATOM_EXITED), PROC_REF(on_task_turf_changed)) + +/// Unregisters all previously registered turf signals. +/obj/machinery/big_manipulator/proc/unregister_task_turf_signals() + for(var/turf/t in signal_turfs) + UnregisterSignal(t, list(COMSIG_ATOM_ENTERED, COMSIG_ATOM_EXITED)) + signal_turfs = list() + +/// Fires when something enters or leaves a watched task turf. +/obj/machinery/big_manipulator/proc/on_task_turf_changed(datum/source) + SIGNAL_HANDLER + if(!on || stopping || !waiting_for_signal) + return + something_happened() + +/// Drop the held atom. +/obj/machinery/big_manipulator/proc/drop_held_atom() + if(isnull(held_object)) + return + var/obj/obj_resolve = held_object?.resolve() + obj_resolve?.forceMove(get_turf(obj_resolve)) + finish_manipulation() diff --git a/code/game/machinery/big_manipulator/interaction_points.dm b/code/game/machinery/big_manipulator/interaction_points.dm deleted file mode 100644 index 3d3a8c4b8fb..00000000000 --- a/code/game/machinery/big_manipulator/interaction_points.dm +++ /dev/null @@ -1,239 +0,0 @@ -/datum/interaction_point - var/name = "interaction point" - - /// The turf this interaction point represents. - var/turf/interaction_turf - /// Should we check our filters while interacting with this point? - var/should_use_filters = FALSE - /// How should this point be interacted with? - var/interaction_mode = INTERACT_DROP - /// How should the monkey worker (if there is one) interact with the target point? - var/worker_interaction = WORKER_NORMAL_USE - /// How far should the manipulator throw the object? - var/throw_range = 1 - /// Which items are supposed to be picked up from `interaction_turf` if this is a pickup point - /// or looked for in the `interaction_turf` if this is a dropoff point. - var/list/atom_filters = list() - /// If this is a dropoff point, influences which interaction endpoints are preferred over which - /// by the manipulator. - var/list/interaction_priorities = list() - /// Should the manipulator put items on this point if there are already such items on the turf? - var/overflow_status = POINT_OVERFLOW_ALLOWED - /// Which object category should the filters be looking out for. - var/filtering_mode = TAKE_ITEMS - /// Whether the worker will use combat mode while interacting with this point. - var/worker_combat_mode = FALSE - /// Whether the worker will simulate RMB instead of LMB on interaction. - var/worker_use_rmb = FALSE - /// List of types that can be picked up from this point - var/list/type_filters = list( - /obj/item, - /obj/structure/closet, - ) - /// What should the manipulator do when there's nothing to "USE" the held item on anymore? - var/use_post_interaction = POST_INTERACTION_DROP_AT_POINT - -/datum/interaction_point/New(turf/new_turf, list/new_filters, new_should_use_filters, new_interaction_mode, new_allowed_types, new_overflow_status, manipulator_tier) - if(!new_turf) - stack_trace("New manipulator interaction point created with no valid turf references passed.") - qdel(src) - return - - if(isclosedturf(new_turf)) - qdel(src) - return - - interaction_turf = new_turf - - if(length(new_filters)) - atom_filters = new_filters - - if(new_should_use_filters) - should_use_filters = new_should_use_filters - - if(new_interaction_mode) - interaction_mode = new_interaction_mode - - if(new_allowed_types) - type_filters = new_allowed_types - - if(new_overflow_status) - overflow_status = new_overflow_status - - interaction_priorities = fill_priority_list(manipulator_tier) - -/// Finds the type priority of the interaction point. -/datum/interaction_point/proc/find_type_priority() - var/list/turf_contents = interaction_turf.contents - - var/atom/movable/best_candidate = null - var/best_priority_index = INFINITY - - for(var/atom/movable/thing as anything in turf_contents) - for(var/i in 1 to length(interaction_priorities)) - if(i >= best_priority_index) - break - - var/datum/manipulator_priority/prio = interaction_priorities[i] - - if(!prio.active) - continue - - if(prio.atom_typepath == /turf) - if(i < best_priority_index) - best_candidate = interaction_turf - best_priority_index = i - continue - - if(!istype(thing, prio.atom_typepath)) - continue - - if(isliving(thing)) - var/mob/living/L = thing - if(L.stat == DEAD) - continue - - best_candidate = thing - best_priority_index = i - - if(best_priority_index == 1) - return best_candidate - break - - return best_candidate - -/// Checks if the interaction point is available - if it has items that can be interacted with. -/datum/interaction_point/proc/is_available(transfer_type, atom/movable/target) - if(!is_valid()) - return FALSE - - // All atoms on the turf that can be interacted with. - var/list/atoms_on_the_turf = interaction_turf?.contents - - // For pickup points, we want points that have atoms to pick up - if(transfer_type == TRANSFER_TYPE_PICKUP) - - if(!length(atoms_on_the_turf)) - return FALSE // nothing to pick up - - // If the atom filters are required, we need to check if any atom on the turf fits the filters. If not, the check will only determine whether it fits the category - for(var/atom/movable/movable_atom as anything in atoms_on_the_turf) - if(check_filters_for_atom(movable_atom)) - return TRUE - - // No suitable atoms to pick up - the pickup point is unavailable. - return FALSE - - if(transfer_type == TRANSFER_TYPE_DROPOFF) - // If filters are enabled, the held item itself must match them for any overflow mode - if(!check_filters_for_atom(target) && should_use_filters) - return FALSE - - if(interaction_mode != INTERACT_DROP) // you don't check for overflow if you're not actually putting anything on the turf silly - return TRUE - - switch(overflow_status) - if(POINT_OVERFLOW_ALLOWED) - // If we don't care if there are already things on this turf, then we just check for filters - // Hence if the atom filters are skipped, the point is available for dropoff - if(!should_use_filters) - return TRUE - - if(POINT_OVERFLOW_FILTERS) - // We need to check if there are already items matching the filters on the turf - for(var/atom/movable/movable_atom as anything in atoms_on_the_turf) - if(check_filters_for_atom(movable_atom)) - return FALSE // the item on the turf was in the filters, hence the turf is considered overflowed - - if(POINT_OVERFLOW_HELD) - // We need to check if any of the items on the turf match the item we're holding - for(var/atom/movable/movable_atom as anything in atoms_on_the_turf) - if(istype(movable_atom, target?.type)) - return FALSE // one of the items on the turf was the same as the one we're holding - - if(POINT_OVERFLOW_FORBIDDEN) - // We need to check if there are already ANY items on the turf - if(locate(/obj/item) in atoms_on_the_turf) - return FALSE - - return TRUE - - // Ambiguous interaction type — no interaction is possible, point is unavailable - return FALSE - -/// Checks if the interaction point is valid — is not located on a closed turf. -/datum/interaction_point/proc/is_valid() - if(!interaction_turf) - return FALSE - - if(isclosedturf(interaction_turf)) - return FALSE - return TRUE - -/// Checks if the passed movable `atom` fits the filters. -/datum/interaction_point/proc/check_filters_for_atom(atom/movable/target) - if(!target || target.anchored || HAS_TRAIT(target, TRAIT_NODROP)) - return FALSE - - switch(filtering_mode) - if(TAKE_CLOSETS) - return iscloset(target) - - if(TAKE_HUMANS) - return ishuman(target) - - if(TAKE_ITEMS) - if(!should_use_filters) - return(isitem(target)) - - for(var/filter_path in atom_filters) - if(istype(target, filter_path)) - return TRUE - return FALSE - - return FALSE - -/// Fills the interaction endpoint priority list for the current interaction mode. -/datum/interaction_point/proc/fill_priority_list(manipulator_tier) - var/list/priorities_to_set = new /list((manipulator_tier == 4 ? 5 : 4)) - - switch(interaction_mode) - if(INTERACT_DROP) - priorities_to_set[1] = new /datum/manipulator_priority/drop/in_storage - priorities_to_set[2] = new /datum/manipulator_priority/drop/on_floor - - if(INTERACT_USE) - priorities_to_set[1] = new /datum/manipulator_priority/interact/with_living - priorities_to_set[2] = new /datum/manipulator_priority/interact/with_structure - priorities_to_set[3] = new /datum/manipulator_priority/interact/with_machinery - priorities_to_set[4] = new /datum/manipulator_priority/interact/with_items - - if(manipulator_tier == 4) - priorities_to_set[5] = new /datum/manipulator_priority/interact/with_vehicles - - return priorities_to_set - -/// Moves the priority for a given index 1 step higher. -/datum/interaction_point/proc/move_priority_up_by_index(index) - if(!index) // also handles index being 0 - return FALSE - - interaction_priorities.Swap(index, index + 1) - - return TRUE - -/// Toggles the priority's `active` param. Sets to TRUE if `reset` is TRUE. -/datum/interaction_point/proc/tick_priority_by_index(index, reset = FALSE) - var/datum/manipulator_priority/target_priority = interaction_priorities[index + 1] - - if(reset) - target_priority.active = TRUE - else - target_priority.active = !target_priority.active - - return TRUE - -/datum/interaction_point/Destroy() - interaction_turf = null - QDEL_LIST(interaction_priorities) - return ..() diff --git a/code/game/machinery/big_manipulator/manipulator_tasks.dm b/code/game/machinery/big_manipulator/manipulator_tasks.dm new file mode 100644 index 00000000000..48a136ff255 --- /dev/null +++ b/code/game/machinery/big_manipulator/manipulator_tasks.dm @@ -0,0 +1,501 @@ +/datum/manipulator_task + var/name = "task" + +/datum/manipulator_task/proc/can_run(obj/machinery/big_manipulator/manipulator) + return FALSE + +/datum/manipulator_task/proc/run_task(obj/machinery/big_manipulator/manipulator) + return + +/datum/manipulator_task/proc/serialize() + return list("type" = type) + +/datum/manipulator_task/New(...) + ..() + return + +// ===== WAIT ===== + +/datum/manipulator_task/simple/wait + name = "wait" + var/time_seconds = 1 + +/datum/manipulator_task/simple/wait/can_run(obj/machinery/big_manipulator/manipulator) + for(var/datum/manipulator_task/cargo/task in manipulator.tasks) + if(task.can_run(manipulator)) + return TRUE + return FALSE + +/datum/manipulator_task/simple/wait/run_task(obj/machinery/big_manipulator/manipulator) + manipulator.schedule_next_cycle(time_seconds SECONDS) + +/datum/manipulator_task/simple/wait/serialize() + var/list/data = ..() + data["time_seconds"] = time_seconds + return data + +/datum/manipulator_task/simple/wait/New(..., serialized_data) + ..() + if(serialized_data) + time_seconds = serialized_data["time_seconds"] + return + +// ===== BASE CARGO ===== + +/datum/manipulator_task/cargo + var/turf/interaction_turf + var/offset_dx + var/offset_dy + var/should_use_filters = FALSE + var/list/atom_filters = list() + var/filtering_mode = TAKE_ITEMS + var/list/type_filters = list( + /obj/item, + /obj/structure/closet, + ) + var/list/interaction_priorities = list() + +/datum/manipulator_task/cargo/New(turf/new_turf, manipulator_tier, serialized_data) + if(serialized_data) + var/list/offset = serialized_data["offset"] + if(islist(offset)) + offset_dx = offset["dx"] + offset_dy = offset["dy"] + if(new_turf) + interaction_turf = new_turf + + should_use_filters = !!serialized_data["should_use_filters"] + atom_filters = serialized_data["atom_filters"] || list() + filtering_mode = serialized_data["filtering_mode"] + type_filters = serialized_data["type_filters"] || list() + + var/list/prios_data = serialized_data["interaction_priorities"] + if(islist(prios_data)) + interaction_priorities = list() + for(var/list/prio_data as anything in prios_data) + if(!islist(prio_data)) + continue + var/prio_type = prio_data["type"] + if(!ispath(prio_type, /datum/manipulator_priority)) + continue + var/datum/manipulator_priority/prio = new prio_type + prio.active = !!prio_data["active"] + interaction_priorities += prio + + return ..() + + if(!new_turf) + stack_trace("New manipulator task created with no valid turf reference passed.") + qdel(src) + return + + if(isclosedturf(new_turf)) + qdel(src) + return + + interaction_turf = new_turf + interaction_priorities = fill_priority_list(manipulator_tier) + return ..() + +/datum/manipulator_task/cargo/proc/fill_priority_list(manipulator_tier) + return list() + +/datum/manipulator_task/cargo/proc/find_type_priority() + var/atom/movable/best_candidate = null + var/best_priority_index = INFINITY + + for(var/atom/movable/thing as anything in interaction_turf.contents) + for(var/i in 1 to length(interaction_priorities)) + if(i >= best_priority_index) + break + + var/datum/manipulator_priority/prio = interaction_priorities[i] + + if(!prio.active || ispath(prio, /turf)) + continue + + if(!istype(thing, prio.atom_typepath)) + continue + + if(isliving(thing)) + var/mob/living/living_mob = thing + if(living_mob.stat == DEAD) + continue + + best_candidate = thing + best_priority_index = i + + if(best_priority_index == 1) + return best_candidate + break + + for(var/i in 1 to length(interaction_priorities)) + if(i >= best_priority_index) + break + var/datum/manipulator_priority/prio = interaction_priorities[i] + if(prio.active && prio.atom_typepath == /turf) + best_candidate = interaction_turf + best_priority_index = i + break + + return best_candidate + +/datum/manipulator_task/cargo/proc/move_priority_up_by_index(index) + if(!index) + return FALSE + interaction_priorities.Swap(index, index + 1) + return TRUE + +/datum/manipulator_task/cargo/proc/tick_priority_by_index(index, reset = FALSE) + var/datum/manipulator_priority/target_priority = interaction_priorities[index + 1] + if(reset) + target_priority.active = TRUE + else + target_priority.active = !target_priority.active + return TRUE + +/datum/manipulator_task/cargo/proc/is_valid() + if(!interaction_turf) + return FALSE + return !isclosedturf(interaction_turf) + +/datum/manipulator_task/cargo/proc/check_filters_for_atom(atom/movable/target) + if(!target || target.anchored || HAS_TRAIT(target, TRAIT_NODROP)) + return FALSE + + switch(filtering_mode) + if(TAKE_CLOSETS) + return iscloset(target) + if(TAKE_HUMANS) + return ishuman(target) + if(TAKE_ITEMS) + if(!should_use_filters) + return isitem(target) + for(var/filter_path in atom_filters) + if(istype(target, filter_path)) + return TRUE + return FALSE + + return FALSE + +/datum/manipulator_task/cargo/can_run(obj/machinery/big_manipulator/manipulator) + return is_valid() + +/datum/manipulator_task/cargo/serialize() + var/list/data = ..() + data["offset"] = list( + "dx" = offset_dx, + "dy" = offset_dy, + ) + data["should_use_filters"] = should_use_filters + data["atom_filters"] = atom_filters + data["filtering_mode"] = filtering_mode + data["type_filters"] = type_filters + data["interaction_priorities"] = list() + for(var/datum/manipulator_priority/prio as anything in interaction_priorities) + data["interaction_priorities"] += list(list( + "type" = prio.type, + "active" = prio.active, + )) + return data + + +/datum/manipulator_task/cargo/Destroy() + interaction_turf = null + QDEL_LIST(interaction_priorities) + return ..() + +// ===== PICKUP ===== + +/datum/manipulator_task/cargo/pickup + name = "pickup" + var/pickup_eagerness = PICKUP_CAN_WAIT + +/datum/manipulator_task/cargo/pickup/fill_priority_list(manipulator_tier) + return list() + +/datum/manipulator_task/cargo/pickup/can_run(obj/machinery/big_manipulator/manipulator) + if(!..()) + return FALSE + if(manipulator.held_object) + return FALSE + for(var/atom/movable/candidate as anything in interaction_turf.contents) + if(!check_filters_for_atom(candidate)) + continue + if(pickup_eagerness == PICKUP_EAGER) + return TRUE + for(var/datum/manipulator_task/cargo/dropoff_base/dest in manipulator.tasks) + if(dest.can_accept(candidate)) + return TRUE + return FALSE + +/datum/manipulator_task/cargo/pickup/run_task(obj/machinery/big_manipulator/manipulator) + manipulator.rotate_to_point(src, src, PROC_REF(try_pickup)) + +/datum/manipulator_task/cargo/pickup/proc/try_pickup(obj/machinery/big_manipulator/manipulator) + var/atom/movable/selected = find_pickup_candidate(manipulator) + if(!selected) + manipulator.nothing_ever_happens() + return + + if(selected.anchored || HAS_TRAIT(selected, TRAIT_NODROP)) + manipulator.nothing_ever_happens() + return + + if(isitem(selected)) + var/obj/item/selected_item = selected + if(selected_item.item_flags & (ABSTRACT|DROPDEL)) + manipulator.nothing_ever_happens() + return + + selected.forceMove(manipulator) + manipulator.held_object = WEAKREF(selected) + manipulator.manipulator_arm.update_claw(manipulator.held_object) + manipulator.schedule_next_cycle() + +/datum/manipulator_task/cargo/pickup/serialize() + var/list/data = ..() + data["pickup_eagerness"] = pickup_eagerness + return data + +/datum/manipulator_task/cargo/pickup/New(turf/new_turf, manipulator_tier, serialized_data) + ..(new_turf, manipulator_tier, serialized_data) + if(serialized_data) + pickup_eagerness = serialized_data["pickup_eagerness"] + return + +/datum/manipulator_task/cargo/pickup/proc/find_pickup_candidate(obj/machinery/big_manipulator/manipulator) + var/list/candidates = list() + + for(var/atom/movable/candidate as anything in interaction_turf.contents) + if(candidate.anchored || HAS_TRAIT(candidate, TRAIT_NODROP)) + continue + if(!check_filters_for_atom(candidate)) + continue + if(pickup_eagerness == PICKUP_EAGER) + candidates += candidate + continue + for(var/datum/manipulator_task/cargo/dropoff_base/dest in manipulator.tasks) + if(dest.can_accept(candidate)) + candidates += candidate + break + + if(!length(candidates)) + return null + + return manipulator.master_tasking.get_next_candidate(candidates) + +// ===== BASE DROPOFF ===== +// Base type for anything that accepts a `held_object`: drop, throw, use. +// Pickup iterates by this type to find a target point. + +/datum/manipulator_task/cargo/dropoff_base + name = "dropoff" + +/datum/manipulator_task/cargo/dropoff_base/proc/can_accept(atom/movable/target) + if(!is_valid()) + return FALSE + if(should_use_filters && !check_filters_for_atom(target)) + return FALSE + return TRUE + +/datum/manipulator_task/cargo/dropoff_base/can_run(obj/machinery/big_manipulator/manipulator) + if(!..()) + return FALSE + var/atom/movable/target = manipulator.held_object?.resolve() + if(!target) + return FALSE + return can_accept(target) + +/datum/manipulator_task/cargo/dropoff_base/run_task(obj/machinery/big_manipulator/manipulator) + manipulator.rotate_to_point(src, src, PROC_REF(try_dropoff)) + +/datum/manipulator_task/cargo/dropoff_base/proc/try_dropoff(obj/machinery/big_manipulator/manipulator) + var/obj/actual_held_object = manipulator.held_object?.resolve() + if(!actual_held_object || actual_held_object.loc != manipulator) + manipulator.nothing_ever_happens() + return FALSE + do_dropoff(manipulator) + return TRUE + +/datum/manipulator_task/cargo/dropoff_base/serialize() + var/list/data = ..() + return data + + +/datum/manipulator_task/cargo/dropoff_base/proc/do_dropoff(obj/machinery/big_manipulator/manipulator) + return + +// ===== DROP ===== + +/datum/manipulator_task/cargo/dropoff_base/drop + name = "drop" + var/overflow_status = POINT_OVERFLOW_ALLOWED + +/datum/manipulator_task/cargo/dropoff_base/drop/fill_priority_list(manipulator_tier) + return list( + new /datum/manipulator_priority/drop/in_storage, + new /datum/manipulator_priority/drop/on_floor + ) + +/datum/manipulator_task/cargo/dropoff_base/drop/can_accept(atom/movable/target) + if(!..()) + return FALSE + + var/list/atoms_on_the_turf = interaction_turf.contents + switch(overflow_status) + if(POINT_OVERFLOW_ALLOWED) + return TRUE + if(POINT_OVERFLOW_FILTERS) + for(var/atom/movable/movable_atom as anything in atoms_on_the_turf) + if(check_filters_for_atom(movable_atom)) + return FALSE + if(POINT_OVERFLOW_HELD) + for(var/atom/movable/movable_atom as anything in atoms_on_the_turf) + if(istype(movable_atom, target?.type)) + return FALSE + if(POINT_OVERFLOW_FORBIDDEN) + if(locate(/obj/item) in atoms_on_the_turf) + return FALSE + + return TRUE + +/datum/manipulator_task/cargo/dropoff_base/drop/serialize() + var/list/data = ..() + data["overflow_status"] = overflow_status + return data + +/datum/manipulator_task/cargo/dropoff_base/drop/New(turf/new_turf, manipulator_tier, serialized_data) + ..(new_turf, manipulator_tier, serialized_data) + if(serialized_data) + overflow_status = serialized_data["overflow_status"] + return + +/datum/manipulator_task/cargo/dropoff_base/drop/do_dropoff(obj/machinery/big_manipulator/manipulator) + manipulator.try_drop_thing(src) + +// ===== THROW ===== + +/datum/manipulator_task/cargo/dropoff_base/throw + name = "throw" + var/throw_range = 1 + +/datum/manipulator_task/cargo/dropoff_base/throw/can_accept(atom/movable/target) + if(!is_valid()) + return FALSE + if(should_use_filters && !check_filters_for_atom(target)) + return FALSE + return TRUE + +/datum/manipulator_task/cargo/dropoff_base/throw/serialize() + var/list/data = ..() + data["throw_range"] = throw_range + return data + +/datum/manipulator_task/cargo/dropoff_base/throw/New(turf/new_turf, manipulator_tier, serialized_data) + ..(new_turf, manipulator_tier, serialized_data) + if(serialized_data) + throw_range = serialized_data["throw_range"] + return + +/datum/manipulator_task/cargo/dropoff_base/throw/do_dropoff(obj/machinery/big_manipulator/manipulator) + manipulator.throw_thing(src) + +// ===== USE ===== + +/datum/manipulator_task/cargo/dropoff_base/use + name = "use" + var/worker_interaction = WORKER_NORMAL_USE + var/use_post_interaction = POST_INTERACTION_DROP_AT_POINT + var/worker_combat_mode = FALSE + var/worker_use_rmb = FALSE + +/datum/manipulator_task/cargo/dropoff_base/use/fill_priority_list(manipulator_tier) + var/list/priorities = list( + new /datum/manipulator_priority/interact/with_living, + new /datum/manipulator_priority/interact/with_structure, + new /datum/manipulator_priority/interact/with_machinery, + new /datum/manipulator_priority/interact/with_items, + ) + if(manipulator_tier == 4) + priorities += new /datum/manipulator_priority/interact/with_vehicles + return priorities + +/datum/manipulator_task/cargo/dropoff_base/use/can_accept(atom/movable/target) + if(!is_valid()) + return FALSE + if(should_use_filters && !check_filters_for_atom(target)) + return FALSE + return TRUE + +/datum/manipulator_task/cargo/dropoff_base/use/serialize() + var/list/data = ..() + data["worker_interaction"] = worker_interaction + data["use_post_interaction"] = use_post_interaction + data["worker_combat_mode"] = worker_combat_mode + data["worker_use_rmb"] = worker_use_rmb + return data + +/datum/manipulator_task/cargo/dropoff_base/use/New(turf/new_turf, manipulator_tier, serialized_data) + ..(new_turf, manipulator_tier, serialized_data) + if(serialized_data) + worker_interaction = serialized_data["worker_interaction"] + use_post_interaction = serialized_data["use_post_interaction"] + worker_combat_mode = !!serialized_data["worker_combat_mode"] + worker_use_rmb = !!serialized_data["worker_use_rmb"] + return + +/datum/manipulator_task/cargo/dropoff_base/use/do_dropoff(obj/machinery/big_manipulator/manipulator) + manipulator.try_use_thing(src) + +// ===== INTERACT (empty hand) ===== + +/datum/manipulator_task/cargo/interact + name = "interact" + var/worker_interaction = WORKER_EMPTY_USE + var/use_post_interaction = POST_INTERACTION_DROP_AT_POINT + var/worker_combat_mode = FALSE + var/worker_use_rmb = FALSE + +/datum/manipulator_task/cargo/interact/fill_priority_list(manipulator_tier) + var/list/priorities = list( + new /datum/manipulator_priority/interact/with_living, + new /datum/manipulator_priority/interact/with_structure, + new /datum/manipulator_priority/interact/with_machinery, + new /datum/manipulator_priority/interact/with_items, + ) + if(manipulator_tier == 4) + priorities += new /datum/manipulator_priority/interact/with_vehicles + return priorities + +/datum/manipulator_task/cargo/interact/can_run(obj/machinery/big_manipulator/manipulator) + if(!..()) + return FALSE + return find_type_priority() != null + +/datum/manipulator_task/cargo/interact/run_task(obj/machinery/big_manipulator/manipulator) + manipulator.rotate_to_point(src, src, PROC_REF(try_interact)) + +/datum/manipulator_task/cargo/interact/serialize() + var/list/data = ..() + data["worker_interaction"] = worker_interaction + data["use_post_interaction"] = use_post_interaction + data["worker_combat_mode"] = worker_combat_mode + data["worker_use_rmb"] = worker_use_rmb + return data + +/datum/manipulator_task/cargo/interact/New(turf/new_turf, manipulator_tier, serialized_data) + ..(new_turf, manipulator_tier, serialized_data) + if(serialized_data) + worker_interaction = serialized_data["worker_interaction"] + use_post_interaction = serialized_data["use_post_interaction"] + worker_combat_mode = !!serialized_data["worker_combat_mode"] + worker_use_rmb = !!serialized_data["worker_use_rmb"] + return + +/datum/manipulator_task/cargo/interact/proc/try_interact(obj/machinery/big_manipulator/manipulator) + var/atom/movable/held = manipulator.held_object?.resolve() + if(held) + manipulator.try_use_thing(src) + else + manipulator.use_thing_with_empty_hand(src) diff --git a/code/game/machinery/big_manipulator/tasking.dm b/code/game/machinery/big_manipulator/tasking.dm index 90db115d1f6..cc91434363e 100644 --- a/code/game/machinery/big_manipulator/tasking.dm +++ b/code/game/machinery/big_manipulator/tasking.dm @@ -1,109 +1,69 @@ -// Handles indexing for the tasking strategy used for the manipulator's point iteraction /datum/tasking_strategy var/current_index = 1 -/// Get the next available point for this tasking strategy -/datum/tasking_strategy/proc/get_next_available(list/points, atom/movable/target, transfer_type, availability_check) +/// Returns the next task to run, or null if nothing is available. +/datum/tasking_strategy/proc/get_next_task(list/tasks) return null -// Prefers the first point avaliable -/datum/tasking_strategy/prefer_first - -/datum/tasking_strategy/prefer_first/get_next_available(list/points, atom/movable/target, transfer_type, datum/callback/availability_check) - if(!length(points)) - return null - - for(var/datum/interaction_point/point in points) - if(availability_check.Invoke(point, target, transfer_type)) - return point - - return null - -/datum/tasking_strategy/round_robin - -/datum/tasking_strategy/round_robin/get_next_available(list/points, atom/movable/target, transfer_type, datum/callback/availability_check) - if(!length(points)) - return null - - if(current_index < 1 || current_index > length(points)) - current_index = 1 - - var/starting_index = current_index - - while(TRUE) - var/datum/interaction_point/point = points[current_index] - - if(point && availability_check.Invoke(point, target, transfer_type)) - advance_index(length(points)) - return point - - advance_index(length(points)) - - if(current_index == starting_index) - break - - return null - -/// Advances the index of the last point the manipulator interacted with to properly iterate in the correct order -/datum/tasking_strategy/round_robin/proc/advance_index(list_length) - current_index++ - if(current_index > list_length) - current_index = 1 - -/datum/tasking_strategy/strict_robin - -/datum/tasking_strategy/strict_robin/get_next_available(list/points, atom/movable/target, transfer_type, datum/callback/availability_check) - if(!length(points)) - return null - - if(current_index < 1 || current_index > length(points)) - current_index = 1 - - var/datum/interaction_point/point = points[current_index] - - if(point && availability_check.Invoke(point, target, transfer_type)) - current_index++ - if(current_index > length(points)) - current_index = 1 - return point - - return null - -/// Picks a next candidate to run the checks for +/// Picks a next candidate from a list of eligible atoms. /datum/tasking_strategy/proc/get_next_candidate(list/candidates) if(!length(candidates)) return null return candidates[1] -/datum/tasking_strategy/prefer_first/get_next_candidate(list/candidates) +// Moves through the list, skipping tasks that can't run. +/datum/tasking_strategy/sequential + +/datum/tasking_strategy/sequential/get_next_task(list/tasks, obj/machinery/big_manipulator/manipulator) + if(!length(tasks)) + return null + if(current_index < 1 || current_index > length(tasks)) + current_index = 1 + var/start = current_index + while(TRUE) + var/datum/manipulator_task/task = tasks[current_index] + current_index++ + if(current_index > length(tasks)) + current_index = 1 + if(task.can_run(manipulator)) + return task + if(current_index == start) + return null + +/datum/tasking_strategy/sequential/get_next_candidate(list/candidates) if(!length(candidates)) return null - return candidates[1] - -/datum/tasking_strategy/round_robin/get_next_candidate(list/candidates) - if(!length(candidates)) - return null - if(current_index < 1 || current_index > length(candidates)) current_index = 1 - var/candidate = candidates[current_index] current_index++ if(current_index > length(candidates)) current_index = 1 - return candidate -/datum/tasking_strategy/strict_robin/get_next_candidate(list/candidates) +// Stays on the current task until it can run. +/datum/tasking_strategy/strict + +/datum/tasking_strategy/strict/get_next_task(list/tasks, obj/machinery/big_manipulator/manipulator) + if(!length(tasks)) + return null + if(current_index < 1 || current_index > length(tasks)) + current_index = 1 + var/datum/manipulator_task/task = tasks[current_index] + if(!task.can_run(manipulator)) + return null + current_index++ + if(current_index > length(tasks)) + current_index = 1 + return task + +/datum/tasking_strategy/strict/get_next_candidate(list/candidates) if(!length(candidates)) return null - if(current_index < 1 || current_index > length(candidates)) current_index = 1 - var/candidate = candidates[current_index] current_index++ if(current_index > length(candidates)) current_index = 1 - return candidate diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 1988c2b70ae..66b37ddd7a3 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -334,20 +334,28 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/camera/xray, 0) if(proximity_monitor) drop_upgrade(proximity_monitor) -/obj/machinery/camera/update_icon_state() //TO-DO: Make panel open states, xray camera, and indicator lights overlays instead. - var/xray_module - if(isXRay(TRUE)) - xray_module = "xray" - - if(!camera_enabled) +/obj/machinery/camera/update_icon_state() + var/xray_module = isXRay(TRUE) ? "xray" : "" + if(!camera_enabled || (machine_stat & EMPED)) icon_state = "[xray_module][base_icon_state]_off" return ..() - if(machine_stat & EMPED) - icon_state = "[xray_module][base_icon_state]_emp" - return ..() - icon_state = "[xray_module][base_icon_state][in_use_lights ? "_in_use" : ""]" + icon_state = "[xray_module][base_icon_state]" return ..() +/obj/machinery/camera/update_overlays() + . = ..() + if(panel_open) + . += "[base_icon_state]_panel" + + var/xray_module = isXRay(TRUE) ? "xray" : "" + if(machine_stat & EMPED) + . += "[xray_module][base_icon_state]_emp" + . += emissive_appearance(icon, "[xray_module][base_icon_state]_emp", src, alpha = src.alpha) + return + if(camera_enabled) + . += "[xray_module][base_icon_state]_[in_use_lights ? "in_use" : "on"]" + . += emissive_appearance(icon, "[xray_module][base_icon_state]_[in_use_lights ? "in_use" : "on"]", src, alpha = src.alpha) + /obj/machinery/camera/proc/toggle_cam(mob/user, displaymessage = TRUE) camera_enabled = !camera_enabled if(can_use()) diff --git a/code/game/machinery/computer/accounting.dm b/code/game/machinery/computer/accounting.dm index 05a1d12ed40..6ccc1d2c7b3 100644 --- a/code/game/machinery/computer/accounting.dm +++ b/code/game/machinery/computer/accounting.dm @@ -37,7 +37,7 @@ data["accounts"] = player_accounts data["audit_log"] = SSeconomy.audit_log data["crashing"] = HAS_TRAIT(SSeconomy, TRAIT_MARKET_CRASHING) - data["station_time"] = station_time_timestamp("hh:mm") + data["station_time"] = round_timestamp("hh:mm") return data /obj/machinery/computer/accounting/ui_static_data(mob/user) diff --git a/code/game/machinery/computer/apc_control.dm b/code/game/machinery/computer/apc_control.dm index 6c56f6e2aa6..a7add4639c3 100644 --- a/code/game/machinery/computer/apc_control.dm +++ b/code/game/machinery/computer/apc_control.dm @@ -48,7 +48,7 @@ /obj/machinery/computer/apc_control/proc/log_activity(log_text) if(!should_log) return - LAZYADD(logs, "([station_time_timestamp()]): [auth_id] [log_text]") + LAZYADD(logs, "([round_timestamp()]): [auth_id] [log_text]") ///Resets the console's emagged state and re-enables logging of activity /obj/machinery/computer/apc_control/proc/restore_comp(mob/user) diff --git a/code/game/machinery/computer/dna_console.dm b/code/game/machinery/computer/dna_console.dm index 3654e25d176..043d0fc47ac 100644 --- a/code/game/machinery/computer/dna_console.dm +++ b/code/game/machinery/computer/dna_console.dm @@ -834,7 +834,7 @@ // Create a new DNA Injector and add the appropriate mutations to it var/obj/item/dnainjector/activator/injector = new /obj/item/dnainjector/activator(loc) - injector.add_mutations += mutation.make_copy() + LAZYADD(injector.add_mutations, mutation.make_copy()) var/is_activator = text2num(params["is_activator"]) @@ -1308,93 +1308,19 @@ // number later // params["type"] - Type of injector to create // Expected results: - // "ue" - Unique Enzyme, changes name and blood type + // "ue" - Unique Enzyme, changes name and blood type // "ui" - Unique Identity, changes looks // "uf" - Unique Features, changes mutant bodyparts and mutcolors // "mixed" - Combination of both ue and ui if("makeup_injector") if(!COOLDOWN_FINISHED(src, enzyme_copy_timer)) return - // Convert the index to a number and clamp within the array range, then - // copy the data from the disk to that buffer - var/buffer_index = text2num(params["index"]) - buffer_index = clamp(buffer_index, 1, NUMBER_OF_BUFFERS) - var/list/buffer_slot = genetic_makeup_buffer[buffer_index] - - // GUARD CHECK - This shouldn't be possible to execute this on a null - // buffer. Unexpected resut - if(!istype(buffer_slot)) + // Convert the index to a number and clamp within the array range, then copy the data from the disk to that buffer + var/buffer_index = clamp(text2num(params["index"]), 1, NUMBER_OF_BUFFERS) + if(!make_cosmetic_dna_injector(dna_injector_type_to_flag(params["type"]), genetic_makeup_buffer[buffer_index])) + to_chat(usr, span_warning("Genetic data corrupted, unable to create injector.")) return - - var/type = params["type"] - var/obj/item/dnainjector/timed/I - - switch(type) - if("ui") - // GUARD CHECK - There's currently no way to save partial genetic data. - // However, if this is the case, we can't make a complete injector and - // this catches that edge case - if(!buffer_slot["UI"]) - to_chat(usr,span_warning("Genetic data corrupted, unable to create injector.")) - return - - I = new /obj/item/dnainjector/timed(loc) - I.fields = list("UI"=buffer_slot["UI"]) - - // If there is a connected scanner, we can use its upgrades to reduce - // the genetic damage generated by this injector - if(scanner_operational()) - I.damage_coeff = connected_scanner.damage_coeff - if("ue") - // GUARD CHECK - There's currently no way to save partial genetic data. - // However, if this is the case, we can't make a complete injector and - // this catches that edge case - if(!buffer_slot["name"] || !buffer_slot["UE"] || !buffer_slot["blood_type"]) - to_chat(usr,span_warning("Genetic data corrupted, unable to create injector.")) - return - - I = new /obj/item/dnainjector/timed(loc) - I.fields = list("name"=buffer_slot["name"], "UE"=buffer_slot["UE"], "blood_type"=buffer_slot["blood_type"]) - - // If there is a connected scanner, we can use its upgrades to reduce - // the genetic damage generated by this injector - if(scanner_operational()) - I.damage_coeff = connected_scanner.damage_coeff - if("uf") - // GUARD CHECK - There's currently no way to save partial genetic data. - // However, if this is the case, we can't make a complete injector and - // this catches that edge case - if(!buffer_slot["name"] || !buffer_slot["UF"] || !buffer_slot["blood_type"]) - to_chat(usr,span_warning("Genetic data corrupted, unable to create injector.")) - return - - I = new /obj/item/dnainjector/timed(loc) - I.fields = list("name"=buffer_slot["name"], "UF"=buffer_slot["UF"]) - - // If there is a connected scanner, we can use its upgrades to reduce - // the genetic damage generated by this injector - if(scanner_operational()) - I.damage_coeff = connected_scanner.damage_coeff - if("mixed") - // GUARD CHECK - There's currently no way to save partial genetic data. - // However, if this is the case, we can't make a complete injector and - // this catches that edge case - if(!buffer_slot["UI"] || !buffer_slot["name"] || !buffer_slot["UE"] || !buffer_slot["UF"] || !buffer_slot["blood_type"]) - to_chat(usr,span_warning("Genetic data corrupted, unable to create injector.")) - return - - I = new /obj/item/dnainjector/timed(loc) - I.fields = list("UI"=buffer_slot["UI"],"name"=buffer_slot["name"], "UE"=buffer_slot["UE"], "UF"=buffer_slot["UF"], "blood_type"=buffer_slot["blood_type"]) - - // If there is a connected scanner, we can use its upgrades to reduce - // the genetic damage generated by this injector - if(scanner_operational()) - I.damage_coeff = connected_scanner.damage_coeff - - // If we successfully created an injector, don't forget to set the new - // ready timer. - if(I) - injector_ready = world.time + MISC_INJECTOR_TIMEOUT + injector_ready = world.time + MISC_INJECTOR_TIMEOUT if(connected_scanner) connected_scanner.use_energy(connected_scanner.active_power_usage) else @@ -1584,7 +1510,7 @@ // new injector var/total_stability = 0 for(var/datum/mutation/mutation as anything in injector_selection[inj_name]) - injector.add_mutations += mutation.make_copy() + LAZYADD(injector.add_mutations, mutation.make_copy()) total_stability += mutation.instability // Force apply any mutations, this is functionality similar to mutators @@ -1790,12 +1716,90 @@ return TRUE return FALSE + /** * Checks if there is a connected DNA Scanner that is operational */ /obj/machinery/computer/dna_console/proc/scanner_operational() return connected_scanner?.is_operational +/** + * Gets the damage coefficient of the connected DNA Scanner, or 1 if there isn't an operational one + */ +/obj/machinery/computer/dna_console/proc/get_injector_damage_coeff() + if(scanner_operational()) + return connected_scanner.damage_coeff + return 1 + +/// Copy UI to the dna injector +#define DNA_INJECTOR_FLAG_UI (1<<0) +/// Copy UE to the dna injector +#define DNA_INJECTOR_FLAG_UE (1<<1) +/// Copy UF to the dna injector +#define DNA_INJECTOR_FLAG_UF (1<<2) +/// Copy name to the dna injector +#define DNA_INJECTOR_FLAG_NAME (1<<3) +/// Copy blood type to the dna injector +#define DNA_INJECTOR_FLAG_BLOOD (1<<4) + +/** + * Converts a string (from tgui) to a series of flags determine what we should put in a DNA Injector + */ +/obj/machinery/computer/dna_console/proc/dna_injector_type_to_flag(injector_type) + switch(injector_type) + if("ui") + return DNA_INJECTOR_FLAG_UI + if("ue") + return DNA_INJECTOR_FLAG_UE | DNA_INJECTOR_FLAG_NAME | DNA_INJECTOR_FLAG_BLOOD + if("uf") + return DNA_INJECTOR_FLAG_UF | DNA_INJECTOR_FLAG_NAME + if("mixed") + return ALL + return NONE + +/** + * Pass an injector flag and a genetic makeup buffer slot to create a DNA Injector + */ +/obj/machinery/computer/dna_console/proc/make_cosmetic_dna_injector(dna_flag, list/buffer_slot = list()) + if(!dna_flag || !length(buffer_slot)) + return FALSE + + var/datum/dna/stored_dna = new() + + if(dna_flag & DNA_INJECTOR_FLAG_NAME) + if(!buffer_slot["name"]) + return FALSE + stored_dna.real_name = buffer_slot["name"] + + if(dna_flag & DNA_INJECTOR_FLAG_BLOOD) + if(!buffer_slot["blood_type"]) + return FALSE + stored_dna.blood_type = buffer_slot["blood_type"] + + if(dna_flag & DNA_INJECTOR_FLAG_UI) + if(!buffer_slot["UI"]) + return FALSE + stored_dna.unique_identity = buffer_slot["UI"] + + if(dna_flag & DNA_INJECTOR_FLAG_UE) + if(!buffer_slot["UE"]) + return FALSE + stored_dna.unique_enzymes = buffer_slot["UE"] + + if(dna_flag & DNA_INJECTOR_FLAG_UF) + if(!buffer_slot["UF"]) + return FALSE + stored_dna.unique_features = buffer_slot["UF"] + + new /obj/item/dnainjector/timed(loc, stored_dna, get_injector_damage_coeff()) + return TRUE + +#undef DNA_INJECTOR_FLAG_UI +#undef DNA_INJECTOR_FLAG_UE +#undef DNA_INJECTOR_FLAG_UF +#undef DNA_INJECTOR_FLAG_NAME +#undef DNA_INJECTOR_FLAG_BLOOD + /** * Checks if there is a valid DNA Scanner occupant for genetic modification * diff --git a/code/game/machinery/computer/orders/order_items/mining/order_mining.dm b/code/game/machinery/computer/orders/order_items/mining/order_mining.dm index cf33d3bd8e5..d628e3fc329 100644 --- a/code/game/machinery/computer/orders/order_items/mining/order_mining.dm +++ b/code/game/machinery/computer/orders/order_items/mining/order_mining.dm @@ -122,4 +122,4 @@ /datum/orderable_item/mining/grapple_gun purchase_path = /obj/item/grapple_gun - cost_per_order = 3000 + cost_per_order = 1500 diff --git a/code/game/machinery/computer/orders/order_items/mining/order_pka.dm b/code/game/machinery/computer/orders/order_items/mining/order_pka.dm index ceaa83d8ef7..9ebe4b72b8b 100644 --- a/code/game/machinery/computer/orders/order_items/mining/order_pka.dm +++ b/code/game/machinery/computer/orders/order_items/mining/order_pka.dm @@ -34,7 +34,7 @@ cost_per_order = 150 /datum/orderable_item/accelerator/aoe_mobs - purchase_path = /obj/item/borg/upgrade/modkit/aoe/mobs + purchase_path = /obj/item/borg/upgrade/modkit/cooldown/aoe/mobs cost_per_order = 1500 /datum/orderable_item/accelerator/minebot_passthrough diff --git a/code/game/machinery/computer/records/medical.dm b/code/game/machinery/computer/records/medical.dm index af464c0be42..aeaa0d5a19a 100644 --- a/code/game/machinery/computer/records/medical.dm +++ b/code/game/machinery/computer/records/medical.dm @@ -106,7 +106,7 @@ if(!content) return FALSE - var/datum/medical_note/new_note = new(usr.name, content, station_time_timestamp()) + var/datum/medical_note/new_note = new(usr.name, content, round_timestamp()) while(length(target.medical_notes) > 2) target.medical_notes.Cut(1, 2) diff --git a/code/game/machinery/digital_clock.dm b/code/game/machinery/digital_clock.dm index 57c58083aae..e43ed60c32f 100644 --- a/code/game/machinery/digital_clock.dm +++ b/code/game/machinery/digital_clock.dm @@ -110,7 +110,7 @@ if(obj_flags & EMAGGED) station_minutes = rand(0, 99) else - station_minutes = text2num(station_time_timestamp(format = "mm")) + station_minutes = text2num(round_timestamp(format = "mm")) // tenth / the '3' in '31' / 31 -> 3.1 -> 3 var/station_minute_tenth = station_minutes >= 10 ? round(station_minutes * 0.1) : 0 @@ -122,7 +122,7 @@ if(obj_flags & EMAGGED) station_hours = rand(0, 99) else - station_hours = text2num(station_time_timestamp(format = "hh")) + station_hours = text2num(round_timestamp(format = "hh")) // one / the '1' in '12' / 12 -> 1.2 -> 1 var/station_hours_tenth = station_minutes >= 10 ? round(station_hours * 0.1) : 0 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 e69a78f132d..83ed8b3a02e 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 @@ -214,3 +214,43 @@ tier = DNA_MUTANT_TIER_ONE unreachable_effect = TRUE status_effect_type = /datum/status_effect/organ_set_bonus/fish + +/datum/infuser_entry/stoat + name = "Stoat" + infuse_mob_name = "stoat" + desc = "We looked at a stoat, and begin to admire its fearless nature, hunting animals much larger than itself head on. \ + This kind of action is what we need on the corporate ladder." + threshold_desc = "become fearless, dodging attacks from larger opponents" + qualities = list( + "a snout!", + "really tall", + "better senses, weaker organs", + "instinctively want to be alone", + "ferocious bites - especially when grappling", + "rodents and eggs look very tasty... but anything plant does not", + ) + input_obj_or_mob = list( + /mob/living/basic/stoat, + ) + output_organs = list( + /obj/item/organ/eyes/stoat, + /obj/item/organ/ears/stoat, + /obj/item/organ/heart/stoat, + /obj/item/organ/tongue/stoat, + /obj/item/organ/snout/stoat, + ) + infusion_desc = "ermine" + tier = DNA_MUTANT_TIER_ONE + status_effect_type = /datum/status_effect/organ_set_bonus/stoat + +/datum/infuser_entry/stoat/get_output_organs(mob/living/carbon/human/target, atom/movable/infused_from) + // eyes and ears are low priority, infuse them last + var/datum/status_effect/organ_set_bonus/stoat/organ_tracker = target.has_status_effect(__IMPLIED_TYPE__) + if(organ_tracker?.organs < 3) + return list( + /obj/item/organ/heart/stoat, + /obj/item/organ/tongue/stoat, + /obj/item/organ/snout/stoat, + ) + + return ..() diff --git a/code/game/machinery/dna_infuser/infuser_entries/infuser_tier_zero_entries.dm b/code/game/machinery/dna_infuser/infuser_entries/infuser_tier_zero_entries.dm index e4d93a587f8..a00e561d589 100644 --- a/code/game/machinery/dna_infuser/infuser_entries/infuser_tier_zero_entries.dm +++ b/code/game/machinery/dna_infuser/infuser_entries/infuser_tier_zero_entries.dm @@ -110,3 +110,56 @@ ) infusion_desc = "domestic" tier = DNA_MUTANT_TIER_ZERO + +/datum/infuser_entry/penguin + name = "Penguin" + infuse_mob_name = "penguin" + desc = "Honestly, there wasn't much to gleam from a penguin's DNA, other than they walk funny." + threshold_desc = DNA_INFUSION_NO_THRESHOLD + qualities = list( + "you waddle when you walk", + ) + input_obj_or_mob = list( + /mob/living/basic/pet/penguin, + ) + output_organs = list( + /obj/item/organ/ears/penguin, + ) + infusion_desc = "waddly" + tier = DNA_MUTANT_TIER_ZERO + +/datum/infuser_entry/plants + name = "Plant" + infuse_mob_name = "plant hybrid" + desc = "Hydroponics research has long been interested in splicing human DNA into plant DNA, creating podpeople. \ + Many scientists didn't want to let those hippies get the leg up on them, so they attempted the opposite - to pretty uninteresting results." + threshold_desc = DNA_INFUSION_NO_THRESHOLD + qualities = list( + "gives you neat hair", + "not much else, honestly", + ) + input_obj_or_mob = list( + /obj/item/food/grown, + /obj/item/grown, + ) + output_organs = list( + /obj/item/organ/appendix/pod, + /obj/item/organ/brain/pod, + /obj/item/organ/ears/pod, + /obj/item/organ/eyes/pod, + /obj/item/organ/heart/pod, + /obj/item/organ/liver/pod, + /obj/item/organ/lungs/pod, + /obj/item/organ/pod_hair, + /obj/item/organ/stomach/pod, + /obj/item/organ/tongue/pod, + ) + infusion_desc = "botanical" + tier = DNA_MUTANT_TIER_ZERO + +/datum/infuser_entry/plants/get_output_organs(mob/living/carbon/human/target, atom/movable/infused_from) + // Prioritize pod hair since it's the only thing that matters here + if(!target.get_organ_by_type(/obj/item/organ/pod_hair)) + return list(/obj/item/organ/pod_hair) + + return ..() diff --git a/code/game/machinery/dna_infuser/organ_sets/fish_organs.dm b/code/game/machinery/dna_infuser/organ_sets/fish_organs.dm index 2284e2afa18..78a32be3c6f 100644 --- a/code/game/machinery/dna_infuser/organ_sets/fish_organs.dm +++ b/code/game/machinery/dna_infuser/organ_sets/fish_organs.dm @@ -6,7 +6,6 @@ /// Currently liver, stomach, lungs and tail plus tongue #define FISH_INFUSION_ALL_ORGANS 4 -///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 diff --git a/code/game/machinery/dna_infuser/organ_sets/goliath_organs.dm b/code/game/machinery/dna_infuser/organ_sets/goliath_organs.dm index 8939fb64e0f..3a9a893d54d 100644 --- a/code/game/machinery/dna_infuser/organ_sets/goliath_organs.dm +++ b/code/game/machinery/dna_infuser/organ_sets/goliath_organs.dm @@ -3,7 +3,6 @@ #define GOLIATH_PUPIL_COLOR COLOR_RED #define GOLIATH_COLORS GOLIATH_ORGAN_COLOR + GOLIATH_SCLERA_COLOR + GOLIATH_PUPIL_COLOR -///bonus of the goliath: you can swim through space! /datum/status_effect/organ_set_bonus/goliath id = "organ_set_bonus_goliath" organs_needed = 4 diff --git a/code/game/machinery/dna_infuser/organ_sets/gondola_organs.dm b/code/game/machinery/dna_infuser/organ_sets/gondola_organs.dm index b3d400ac39d..d8c0ee95f53 100644 --- a/code/game/machinery/dna_infuser/organ_sets/gondola_organs.dm +++ b/code/game/machinery/dna_infuser/organ_sets/gondola_organs.dm @@ -57,6 +57,7 @@ Fluoride Stare: After someone says 5 words, blah blah blah... post_init_icon_state = "tongue" greyscale_config = /datum/greyscale_config/mutant_organ greyscale_colors = GONDOLA_COLORS + speakable_with = FALSE organ_traits = list(TRAIT_MUTE) /obj/item/organ/tongue/gondola/Initialize(mapload) diff --git a/code/game/machinery/dna_infuser/organ_sets/rat_organs.dm b/code/game/machinery/dna_infuser/organ_sets/rat_organs.dm index 3b1e1b9f3bb..d9a0abbe76a 100644 --- a/code/game/machinery/dna_infuser/organ_sets/rat_organs.dm +++ b/code/game/machinery/dna_infuser/organ_sets/rat_organs.dm @@ -62,6 +62,7 @@ greyscale_config = /datum/greyscale_config/mutant_organ greyscale_colors = RAT_COLORS beat_noise = "a fast-paced high-pitched pit-pat" + organ_traits = list(TRAIT_DWARF) /obj/item/organ/heart/rat/Initialize(mapload) . = ..() @@ -74,8 +75,6 @@ if(!ishuman(receiver)) return var/mob/living/carbon/human/human_receiver = receiver - if(human_receiver.can_mutate()) - human_receiver.dna.add_mutation(/datum/mutation/dwarfism, MUTATION_SOURCE_RAT_HEART) //but 1.5 damage human_receiver.physiology?.damage_resistance -= 50 @@ -84,7 +83,6 @@ if(!ishuman(heartless)) return var/mob/living/carbon/human/human_heartless = heartless - human_heartless.dna.remove_mutation(/datum/mutation/dwarfism, MUTATION_SOURCE_RAT_HEART) human_heartless.physiology?.damage_resistance += 50 /// you occasionally squeak, and have some rat related verbal tics diff --git a/code/game/machinery/dna_infuser/organ_sets/stoat_organs.dm b/code/game/machinery/dna_infuser/organ_sets/stoat_organs.dm new file mode 100644 index 00000000000..90c5c2c1f4f --- /dev/null +++ b/code/game/machinery/dna_infuser/organ_sets/stoat_organs.dm @@ -0,0 +1,303 @@ +// Organ color - Sclera color - Pupil color +#define STOAT_COLORS COLOR_BROWNER_BROWN + COLOR_BLACK + COLOR_BLACK + +/datum/status_effect/organ_set_bonus/stoat + id = "organ_set_bonus_stoat" + tick_interval = 3 SECONDS + organs_needed = 4 + bonus_activate_text = span_notice("Stoat DNA is deeply infused with you! \ + Your instincts set in - you now feel fearless, as if you could take on any enemy, no matter the size difference.") + bonus_deactivate_text = span_notice("You are no longer majority stoat, \ + and you realize larger enemies are quite intimidating after all.") + bonus_traits = list(TRAIT_FEARLESS, TRAIT_NOFEAR_HOLDUPS) + COOLDOWN_DECLARE(big_attack_dodge_cd) + +/datum/status_effect/organ_set_bonus/stoat/enable_bonus(obj/item/organ/inserted_organ) + . = ..() + RegisterSignal(owner, COMSIG_LIVING_CHECK_BLOCK, PROC_REF(dodge_bigger_attack)) + +/datum/status_effect/organ_set_bonus/stoat/disable_bonus(obj/item/organ/removed_organ) + . = ..() + UnregisterSignal(owner, COMSIG_LIVING_CHECK_BLOCK) + owner.clear_mood_event("stoat_enemy") + owner.clear_mood_event("stoat_friendly") + +/datum/status_effect/organ_set_bonus/stoat/on_remove() + . = ..() + UnregisterSignal(owner, COMSIG_LIVING_CHECK_BLOCK) + owner.clear_mood_event("stoat_enemy") + owner.clear_mood_event("stoat_friendly") + +/datum/status_effect/organ_set_bonus/stoat/proc/dodge_bigger_attack(datum/source, atom/movable/hit_by, damage, the_attack, attack_type, ...) + SIGNAL_HANDLER + + if(attack_type != UNARMED_ATTACK && attack_type != OVERWHELMING_ATTACK && attack_type != LEAP_ATTACK) + return NONE + if(!COOLDOWN_FINISHED(src, big_attack_dodge_cd)) + return NONE + if(isliving(hit_by)) + var/mob/living/attacker = hit_by + if(attacker.mob_size <= owner.mob_size) + return NONE + else if(!ismecha(hit_by)) + return NONE + + if(owner.incapacitated || owner.is_blind()) + return FAILED_BLOCK + + INVOKE_ASYNC(owner, TYPE_PROC_REF(/mob, emote), "spin") + owner.visible_message( + span_warning("[owner] instinctively dodges [the_attack] from [hit_by]!"), + span_warning("You instinctively dodge out of the way of [the_attack] from [hit_by]!"), + vision_distance = COMBAT_MESSAGE_RANGE, + ) + owner.add_movespeed_modifier(/datum/movespeed_modifier/stoat_dodge) + addtimer(CALLBACK(owner, TYPE_PROC_REF(/mob, remove_movespeed_modifier), /datum/movespeed_modifier/stoat_dodge), 1 SECONDS) + COOLDOWN_START(src, big_attack_dodge_cd, 5 SECONDS) + playsound(owner, 'sound/items/weapons/punchmiss.ogg', 25, TRUE, -1) + return SUCCESSFUL_BLOCK + +/datum/status_effect/organ_set_bonus/stoat/proc/is_dangerous_mob(mob/living/target) + if(target.stat >= UNCONSCIOUS) + return FALSE + if(istype(target, /mob/living/basic/stoat)) + return owner.gender == MALE && target.gender == MALE // other stoats are ENEMIES if we are both males + for(var/obj/item/weapon in target.held_items) + if(weapon.force > 15 || isgun(weapon)) + return TRUE + if(target.mob_size > owner.mob_size) + return TRUE + if(target.mob_size == owner.mob_size) + return !ishuman(target) // assuming same-sized animals are enemies, same-sized humans are friends + return FALSE + +/datum/status_effect/organ_set_bonus/stoat/proc/is_friendly_mob(mob/living/target) + if(target.stat >= UNCONSCIOUS) + return FALSE + if(istype(target, /mob/living/basic/stoat)) + return owner.gender != MALE || target.gender != MALE + if(ishuman(target)) + return TRUE + return FALSE + +/datum/status_effect/organ_set_bonus/stoat/tick(seconds_between_ticks) + . = ..() + if(!bonus_active) + return + var/nearby_friends = 0 + var/nearby_enemies = 0 + for(var/obj/vehicle/sealed/mecha/mech in oview(owner, 5)) + nearby_enemies++ + for(var/mob/living/nearby in oview(owner, 5)) + if(is_dangerous_mob(nearby)) + nearby_enemies++ + else if(is_friendly_mob(nearby)) + nearby_friends++ + + if(nearby_enemies) + switch(nearby_enemies) + if(1) + owner.add_mood_event("stoat_enemy", /datum/mood_event/stoat/enemies_nearby/one) + if(2 to 4) + owner.add_mood_event("stoat_enemy", /datum/mood_event/stoat/enemies_nearby/multiple) + if(4 to INFINITY) + owner.add_mood_event("stoat_enemy", /datum/mood_event/stoat/enemies_nearby/crowd) + owner.clear_mood_event("stoat_friendly") + + else + switch(nearby_friends) + if(0) + owner.add_mood_event("stoat_friendly", /datum/mood_event/stoat/friendlies_nearby/one) + if(2 to 4) + owner.add_mood_event("stoat_friendly", /datum/mood_event/stoat/friendlies_nearby/multiple) + if(4 to INFINITY) + owner.add_mood_event("stoat_friendly", /datum/mood_event/stoat/friendlies_nearby/crowd) + owner.clear_mood_event("stoat_enemy") + + +/obj/item/organ/heart/stoat + name = "mutated stoat-heart" + desc = "Stoat DNA infused into what was once a normal heart." + icon = 'icons/map_icons/items/_item.dmi' + icon_state = "/obj/item/organ/heart/stoat" + post_init_icon_state = "heart" + greyscale_config = /datum/greyscale_config/mutant_organ + greyscale_colors = STOAT_COLORS + beat_noise = "a fast-paced high-pitched pit-pat" + maxHealth = parent_type::maxHealth * 0.8 // weaker heart + /// Tracks height of the mob on add + var/mob_base_height = HUMAN_HEIGHT_MEDIUM + +/obj/item/organ/heart/stoat/Initialize(mapload) + . = ..() + AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/stoat) + AddElement(/datum/element/update_icon_blocker) + +/obj/item/organ/heart/stoat/on_mob_insert(mob/living/carbon/organ_owner, special, movement_flags) + . = ..() + if(!ishuman(organ_owner)) + return + var/mob/living/carbon/human/human_owner = organ_owner + mob_base_height = human_owner.get_base_mob_height() + human_owner.set_mob_height(HUMAN_HEIGHT_TALLEST, update_dna = FALSE) + +/obj/item/organ/heart/stoat/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) + . = ..() + if(!ishuman(organ_owner)) + return + var/mob/living/carbon/human/human_owner = organ_owner + human_owner.set_mob_height(mob_base_height, update_dna = FALSE) + +/obj/item/organ/tongue/stoat + name = "mutated stoat-tongue" + desc = "Stoat DNA infused into what was once a normal tongue." + say_mod = "chirps" + modifies_speech = TRUE + icon = 'icons/map_icons/items/_item.dmi' + icon_state = "/obj/item/organ/tongue/rat" + post_init_icon_state = "tongue" + greyscale_config = /datum/greyscale_config/mutant_organ + greyscale_colors = STOAT_COLORS + liked_foodtypes = MEAT | RAW | GORE | BUGS + disliked_foodtypes = FRUIT | VEGETABLES + taste_sensitivity = 12 + organ_traits = list(TRAIT_FERAL_BITER) + +/obj/item/organ/tongue/stoat/Initialize(mapload) + . = ..() + AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/stoat) + +/obj/item/organ/tongue/stoat/on_life(seconds_per_tick) + . = ..() + if(prob(1)) + playsound(owner, 'sound/mobs/non-humanoids/stoat/stoat_sounds.ogg', 100) + +/obj/item/organ/tongue/stoat/on_mob_insert(mob/living/carbon/receiver, special, movement_flags) + . = ..() + RegisterSignals(receiver, COMSIG_LIVING_GET_PERCEIVED_FOOD_QUALITY, PROC_REF(get_perceived_food_quality)) + if(ishuman(receiver)) + var/mob/living/carbon/human/human_receiver = receiver + human_receiver.physiology.hunger_mod *= 2 + +/obj/item/organ/tongue/stoat/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) + . = ..() + UnregisterSignal(organ_owner, COMSIG_LIVING_GET_PERCEIVED_FOOD_QUALITY) + if(ishuman(organ_owner)) + var/mob/living/carbon/human/human_remover = organ_owner + human_remover.physiology.hunger_mod /= 2 + +/obj/item/organ/tongue/stoat/on_bodypart_insert(obj/item/bodypart/limb) + . = ..() + limb.unarmed_damage_low += 7 + limb.unarmed_damage_high += 7 + limb.unarmed_effectiveness += 20 + limb.unarmed_pummeling_bonus += 0.75 + limb.unarmed_attack_effect = ATTACK_EFFECT_BITE + limb.unarmed_sharpness = SHARP_POINTY + +/obj/item/organ/tongue/stoat/on_bodypart_remove(obj/item/bodypart/limb) + . = ..() + limb.unarmed_damage_low -= 7 + limb.unarmed_damage_high -= 7 + limb.unarmed_effectiveness -= 20 + limb.unarmed_pummeling_bonus -= 0.75 + limb.unarmed_attack_effect = initial(limb.unarmed_attack_effect) + limb.unarmed_sharpness = initial(limb.unarmed_sharpness) + +/obj/item/organ/tongue/stoat/proc/get_perceived_food_quality(mob/living/carbon/consumer, obj/item/food/consumed_food, list/extra_quality) + SIGNAL_HANDLER + + if(organ_flags & ORGAN_FAILING) + return + if(istype(consumed_food, /obj/item/food/deadmouse) || istype(consumed_food, /obj/item/food/egg)) + extra_quality += LIKED_FOOD_QUALITY_CHANGE + +/obj/item/organ/eyes/stoat + name = "mutated stoat-eyes" + desc = "Stoat DNA infused into what was once a normal pair of eyes." + icon = 'icons/map_icons/items/_item.dmi' + icon_state = "/obj/item/organ/eyes/stoat" + post_init_icon_state = "eyes" + greyscale_config = /datum/greyscale_config/mutant_organ + greyscale_colors = STOAT_COLORS + eye_color_left = COLOR_BLACK + eye_color_right = COLOR_BLACK + lighting_cutoff = LIGHTING_CUTOFF_LOW + maxHealth = parent_type::maxHealth * 0.8 // weaker eyes + penlight_message = "shine green" + +/obj/item/organ/eyes/stoat/Initialize(mapload) + . = ..() + AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/stoat) + AddElement(/datum/element/noticable_organ, "%PRONOUN_Their eyes are black orbs.", zone) + +/obj/item/organ/ears/stoat + name = "mutated stoat-ears" + desc = "Stoat DNA infused into what was once a normal pair of ears." + icon = 'icons/map_icons/items/_item.dmi' + icon_state = "/obj/item/organ/ears/stoat" + post_init_icon_state = "ears" + greyscale_config = /datum/greyscale_config/mutant_organ + greyscale_colors = STOAT_COLORS + damage_multiplier = 1.2 + maxHealth = parent_type::maxHealth * 0.8 // weaker ears + +/obj/item/organ/ears/stoat/Initialize(mapload) + . = ..() + AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/stoat) + AddElement(/datum/element/noticable_organ, "%PRONOUN_Their ears are furred, and twitch occasionally.", zone) + +/obj/item/organ/ears/stoat/on_mob_insert(mob/living/carbon/organ_owner, special, movement_flags) + . = ..() + organ_owner.eavesdrop_range += 2 + +/obj/item/organ/ears/stoat/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) + . = ..() + organ_owner.eavesdrop_range -= 2 + +/obj/item/organ/snout/stoat + name = "stoat snout" + +/obj/item/organ/snout/stoat/Initialize(mapload) + . = ..() + AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/stoat) + +/datum/mood_event/stoat + +/datum/mood_event/stoat/enemies_nearby + event_flags = MOOD_EVENT_FEAR + +/datum/mood_event/stoat/enemies_nearby/one + description = "My instincts say there's something dangerous nearby, better be careful." + mood_change = -1 + +/datum/mood_event/stoat/enemies_nearby/multiple + description = "My instincts say there potential danger nearby, better be on edge." + mood_change = -3 + +/datum/mood_event/stoat/enemies_nearby/crowd + description = "My instincts say there are a lot of dangerous things nearby, I need to get out of here!" + mood_change = -5 + +/datum/mood_event/stoat/alone + description = "There is no one nearby, my instincts are at rest. I feel at peace." + mood_change = 1 + +/datum/mood_event/stoat/friendlies_nearby + event_flags = MOOD_EVENT_FEAR + +/datum/mood_event/stoat/friendlies_nearby/one + description = "There is only one friend nearby, my instincts are at rest." + +/datum/mood_event/stoat/friendlies_nearby/multiple + description = "My instincts say there are too many people nearby, I feel a little on edge." + mood_change = -1 + +/datum/mood_event/stoat/friendlies_nearby/crowd + description = "My instincts say there are too many people nearby, I need to get out of here!" + mood_change = -3 + +/datum/movespeed_modifier/stoat_dodge + multiplicative_slowdown = 1 + +#undef STOAT_COLORS diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 5103813eead..ed8d694c71a 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1582,7 +1582,7 @@ bolt() //Bolt it! set_electrified(MACHINE_ELECTRIFIED_PERMANENT) //Shock it! if(origin) - LAZYADD(shockedby, "\[[time_stamp()]\] [key_name(origin)]") + LAZYADD(shockedby, "\[[server_timestamp()]\] [key_name(origin)]") /obj/machinery/door/airlock/disable_lockdown() @@ -1606,7 +1606,7 @@ return if(prob(severity*10 - 20) && (secondsElectrified < 30) && (secondsElectrified != MACHINE_ELECTRIFIED_PERMANENT)) set_electrified(30) - LAZYADD(shockedby, "\[[time_stamp()]\]EM Pulse") + LAZYADD(shockedby, "\[[server_timestamp()]\]EM Pulse") /obj/machinery/door/airlock/proc/set_electrified(seconds, mob/user) secondsElectrified = seconds @@ -1623,7 +1623,7 @@ message = "unshocked" else message = "temp shocked for [secondsElectrified] seconds" - LAZYADD(shockedby, "\[[time_stamp()]\] [key_name(user)] - ([uppertext(message)])") + LAZYADD(shockedby, "\[[server_timestamp()]\] [key_name(user)] - ([uppertext(message)])") log_combat(user, src, message) add_hiddenprint(user) @@ -2407,6 +2407,10 @@ security_level = 1 damage_deflection = 30 +/obj/machinery/door/airlock/highsecurity/syndicate + icon = 'icons/obj/doors/airlocks/syndicate/highsec.dmi' + overlays_file = null + // Shuttle Airlocks /obj/machinery/door/airlock/shuttle diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 97a546f8f62..a3d62de92d8 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -322,6 +322,10 @@ return return ..() +/obj/machinery/door/allowed(mob/accessor) + return ..() || emergency + +/// A mob is trying to open or close the door /obj/machinery/door/proc/try_to_activate_door(mob/user, access_bypass = FALSE, bumped = FALSE) add_fingerprint(user) if(operating || (obj_flags & EMAGGED)) @@ -333,24 +337,8 @@ if(elevator_mode && elevator_status != LIFT_PLATFORM_UNLOCKED) return - var/access_check = access_bypass - if(emergency) - access_check = TRUE - else if(unrestricted_side(user) && !delayed_unres_open) - access_check = TRUE - else if(!requiresID()) - access_check = TRUE - else if(allowed(user)) // You - access_check = TRUE - else for(var/mob/living/human_backpack in user.buckled_mobs) - if(allowed(human_backpack)) // Your partner in crime - access_check = TRUE - break - - if(!access_check && unrestricted_side(user) && attempt_delayed_unres_open(user)) - access_check = TRUE - - if(access_check) + // note: if the ID wire is cut no ID cards are checked at all! (This is intentional!) + if(access_bypass || (requiresID() && user_can_activate_door(user))) if(density) open() else @@ -360,6 +348,18 @@ else if(!operating && density) run_animation(DOOR_DENY_ANIMATION) +/// Used in try_to_activate_door +/obj/machinery/door/proc/user_can_activate_door(mob/user) + PRIVATE_PROC(TRUE) + if(allowed(user)) + return TRUE + for(var/mob/living/human_backpack in user.buckled_mobs) + if(allowed(human_backpack)) + return TRUE + if(unrestricted_side(user)) + return !delayed_unres_open || attempt_delayed_unres_open(user) + return FALSE + /// Allows for specific side of airlocks to be unrestricted (IE, can exit maint freely, but need access to enter) /obj/machinery/door/proc/unrestricted_side(mob/opener) return get_dir(src, opener) & unres_sides diff --git a/code/game/machinery/doors/shutters.dm b/code/game/machinery/doors/shutters.dm index 46370354003..72c5f4f5eed 100644 --- a/code/game/machinery/doors/shutters.dm +++ b/code/game/machinery/doors/shutters.dm @@ -99,3 +99,15 @@ icon_state = "open" density = FALSE opacity = FALSE + +/obj/machinery/door/poddoor/shutters/syndicate + icon = 'icons/obj/doors/syndicateshutters.dmi' + +/obj/machinery/door/poddoor/shutters/syndicate/preopen + icon_state = "open" + density = FALSE + opacity = FALSE + +/obj/machinery/door/poddoor/shutters/syndicate/indestructible + name = "hardened syndicate shutters" + resistance_flags = INDESTRUCTIBLE diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index ee4158538b3..01ec6e7b66c 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -535,6 +535,18 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/door/window/brigdoor/security/holding icon_state = "rightsecure" base_state = "rightsecure" +/obj/machinery/door/window/brigdoor/security/holodeck + name = "cell door" + desc = "For keeping in criminal scum." + req_one_access = COMMON_ACCESS + +MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/door/window/brigdoor/security/holodeck/left, 0) +MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/door/window/brigdoor/security/holodeck/right, 0) + +/obj/machinery/door/window/brigdoor/security/holodeck/right + icon_state = "rightsecure" + base_state = "rightsecure" + /* * Subtype used in unit tests to ensure instant windoor open/close */ diff --git a/code/game/machinery/experimental_cloner/experimental_cloner_pod.dm b/code/game/machinery/experimental_cloner/experimental_cloner_pod.dm index 460786c9ea8..617d013fab3 100644 --- a/code/game/machinery/experimental_cloner/experimental_cloner_pod.dm +++ b/code/game/machinery/experimental_cloner/experimental_cloner_pod.dm @@ -163,7 +163,7 @@ GLOBAL_VAR_INIT(experimental_cloner_fuckup_chance, 50) if (prob(75)) var/static/list/permitted_heights = list(HUMAN_HEIGHT_SHORTEST, HUMAN_HEIGHT_SHORT, HUMAN_HEIGHT_MEDIUM, HUMAN_HEIGHT_TALL, HUMAN_HEIGHT_TALLER, HUMAN_HEIGHT_TALLEST) - new_clone.dna.remove_mutation(/datum/mutation/dwarfism, list(MUTATION_SOURCE_ACTIVATED, MUTATION_SOURCE_MUTATOR)) + new_clone.dna.remove_mutation(/datum/mutation/dwarfism, GLOB.standard_mutation_sources) new_clone.set_mob_height(pick(permitted_heights - loaded_record.height)) // To differentiate the clones return new_clone diff --git a/code/game/machinery/fat_sucker.dm b/code/game/machinery/fat_sucker.dm index d9806ba6f2b..a0756ca11db 100644 --- a/code/game/machinery/fat_sucker.dm +++ b/code/game/machinery/fat_sucker.dm @@ -190,17 +190,17 @@ meat.set_custom_materials(list(SSmaterials.get_material(/datum/material/meat/mob_meat, C) = round(SHEET_MATERIAL_AMOUNT * (4/3)))) nutrients = 0 -/obj/machinery/fat_sucker/screwdriver_act(mob/living/user, obj/item/I) +/obj/machinery/fat_sucker/screwdriver_act(mob/living/user, obj/item/tool) if(occupant) to_chat(user, span_warning("[src] is currently occupied!")) return ITEM_INTERACT_BLOCKING if(state_open) to_chat(user, span_warning("[src] must be closed to [panel_open ? "close" : "open"] its maintenance hatch!")) return ITEM_INTERACT_BLOCKING - return default_deconstruction_screwdriver(user, I) + return default_deconstruction_screwdriver(user, tool) -/obj/machinery/fat_sucker/crowbar_act(mob/living/user, obj/item/I) - return default_deconstruction_crowbar(user, I) +/obj/machinery/fat_sucker/crowbar_act(mob/living/user, obj/item/tool) + return default_deconstruction_crowbar(user, tool) /obj/machinery/fat_sucker/emag_act(mob/user, obj/item/card/emag/emag_card) if(obj_flags & EMAGGED) diff --git a/code/game/machinery/launch_pad.dm b/code/game/machinery/launch_pad.dm index 34a52615623..ed60bd83539 100644 --- a/code/game/machinery/launch_pad.dm +++ b/code/game/machinery/launch_pad.dm @@ -91,7 +91,12 @@ /obj/machinery/launchpad/update_icon_state() . = ..() - icon_state = panel_open ? "[base_icon_state]-open" : base_icon_state + if(machine_stat & (BROKEN|NOPOWER)) + icon_state = "[base_icon_state]-off" + else if(state_open) + icon_state = "[base_icon_state]-open" + else + icon_state = "[base_icon_state]-idle" /obj/machinery/launchpad/attack_ghost(mob/dead/observer/ghost) . = ..() @@ -399,11 +404,18 @@ if("move_pos") var/plus_x = text2num(params["x"]) var/plus_y = text2num(params["y"]) - // sanitizes our ranges for us - our_pad.set_offset( - x = our_pad.x_offset + plus_x, - y = our_pad.y_offset + plus_y - ) + if(plus_x || plus_y) + // sanitizes our ranges for us + our_pad.set_offset( + x = our_pad.x_offset + plus_x, + y = our_pad.y_offset + plus_y, + ) + else + // for resetting + our_pad.set_offset( + x = 0, + y = 0, + ) . = TRUE if("rename") . = TRUE diff --git a/code/game/machinery/medipen_refiller.dm b/code/game/machinery/medipen_refiller.dm index 272365dfea6..65e848b54bb 100644 --- a/code/game/machinery/medipen_refiller.dm +++ b/code/game/machinery/medipen_refiller.dm @@ -119,12 +119,10 @@ return TRUE /obj/machinery/medipen_refiller/wrench_act(mob/living/user, obj/item/tool) - default_unfasten_wrench(user, tool) - return ITEM_INTERACT_SUCCESS + return default_unfasten_wrench(user, tool) /obj/machinery/medipen_refiller/crowbar_act(mob/living/user, obj/item/tool) - default_deconstruction_crowbar(tool) - return ITEM_INTERACT_SUCCESS + return default_deconstruction_crowbar(user, tool) /obj/machinery/medipen_refiller/screwdriver_act(mob/living/user, obj/item/tool) return default_deconstruction_screwdriver(user, tool) diff --git a/code/game/machinery/newscaster/newscaster_data.dm b/code/game/machinery/newscaster/newscaster_data.dm index 59b8f09db47..6c91c94d6af 100644 --- a/code/game/machinery/newscaster/newscaster_data.dm +++ b/code/game/machinery/newscaster/newscaster_data.dm @@ -207,7 +207,7 @@ GLOBAL_LIST_EMPTY(request_list) var/datum/feed_message/new_article = new /datum/feed_message new_article.author = author new_article.body = msg - new_article.time_stamp = "[station_time_timestamp()]" + new_article.time_stamp = "[round_timestamp()]" new_article.is_admin_message = adminMessage new_article.locked = !allow_comments @@ -243,7 +243,7 @@ GLOBAL_LIST_EMPTY(request_list) var/datum/feed_comment/new_feed_comment = new/datum/feed_comment new_feed_comment.author = newscaster_username new_feed_comment.body = comment_text - new_feed_comment.time_stamp = station_time_timestamp() + new_feed_comment.time_stamp = round_timestamp() GLOB.news_network.last_action ++ current_message.comments += new_feed_comment if(user) diff --git a/code/game/machinery/prisongate.dm b/code/game/machinery/prisongate.dm index 88cb40dd50f..688ddc08702 100644 --- a/code/game/machinery/prisongate.dm +++ b/code/game/machinery/prisongate.dm @@ -1,4 +1,7 @@ #define SPAM_CD (3 SECONDS) +#define ALLOW_EXIT "allow_exit" +#define BLOCK_EXIT "block_exit" +#define SKIP_EXIT null /obj/machinery/prisongate name = "prison gate scanner" @@ -14,6 +17,7 @@ idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 0.05 active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 0.03 anchored = TRUE + req_one_access = list(ACCESS_BRIG) /// dictates whether the gate barrier is up or not var/gate_active = TRUE COOLDOWN_DECLARE(spam_cooldown_time) @@ -55,39 +59,74 @@ COOLDOWN_START(src, spam_cooldown_time, SPAM_CD) return FALSE var/mob/living/carbon/the_toucher = gate_toucher - if(gate_active == FALSE) + if(!gate_active) return TRUE - for(var/obj/item/card/id/regular_id in the_toucher.get_all_contents()) - var/list/id_access = regular_id.GetAccess() - if(ACCESS_BRIG in id_access) - if(COOLDOWN_FINISHED(src, spam_cooldown_time)) - say("Brig clearance detected. Access granted.") - playsound(src, 'sound/machines/chime.ogg', 50, FALSE) - COOLDOWN_START(src, spam_cooldown_time, SPAM_CD) - return TRUE - for(var/obj/item/card/id/advanced/prisoner/prison_id in the_toucher.get_all_contents()) - if(!prison_id.timed) - continue - if(prison_id.time_to_assign) - say("Prison ID with active sentence detected. Please enjoy your stay in our corporate rehabilitation center, [prison_id.registered_name]!") - playsound(src, 'sound/machines/chime.ogg', 50, FALSE) - prison_id.time_left = prison_id.time_to_assign - prison_id.time_to_assign = initial(prison_id.time_to_assign) - prison_id.start_timer() - return TRUE - if(prison_id.time_left <= 0) - say("Prison ID with served sentence detected. Access granted.") - prison_id.timed = FALSE //disables the id check from earlier so you can't just throw it back into perma for mass escapes - playsound(src, 'sound/machines/chime.ogg', 50, FALSE) - return TRUE + if(allowed(the_toucher)) if(COOLDOWN_FINISHED(src, spam_cooldown_time)) - say("Prison ID with ongoing sentence detected. Access denied.") - playsound(src, 'sound/machines/buzz/buzz-two.ogg', 50, FALSE) + say("Brig clearance detected. Access granted.") + playsound(src, 'sound/machines/chime.ogg', 50, FALSE) COOLDOWN_START(src, spam_cooldown_time, SPAM_CD) - return FALSE + return TRUE + + else if(the_toucher.pulledby && allowed(the_toucher.pulledby)) + if(COOLDOWN_FINISHED(src, spam_cooldown_time)) + say("Brig escort detected. Access granted.") + playsound(src, 'sound/machines/chime.ogg', 50, FALSE) + COOLDOWN_START(src, spam_cooldown_time, SPAM_CD) + return TRUE + + for(var/obj/item/card/id/advanced/prisoner/prison_id in the_toucher.get_all_contents()) + switch(allow_prisoner_id(prison_id)) + if(ALLOW_EXIT) + return TRUE + if(BLOCK_EXIT) + return FALSE + if(COOLDOWN_FINISHED(src, spam_cooldown_time)) to_chat(the_toucher, span_warning("You try to push through the hardlight barrier with little effect.")) COOLDOWN_START(src, spam_cooldown_time, SPAM_CD) return FALSE +/obj/machinery/prisongate/proc/allow_prisoner_id(obj/item/card/id/advanced/prisoner/prison_id) + if(!prison_id.timed) + return SKIP_EXIT + if(prison_id.time_to_assign) + say("Prison ID with active sentence detected. Please enjoy your stay in our corporate rehabilitation center, [prison_id.registered_name]!") + playsound(src, 'sound/machines/chime.ogg', 50, FALSE) + prison_id.time_left = prison_id.time_to_assign + prison_id.time_to_assign = initial(prison_id.time_to_assign) + prison_id.start_timer() + return ALLOW_EXIT + if(prison_id.time_left <= 0) + say("Prison ID with served sentence detected. Access granted.") + prison_id.timed = FALSE //disables the id check from earlier so you can't just throw it back into perma for mass escapes + playsound(src, 'sound/machines/chime.ogg', 50, FALSE) + return ALLOW_EXIT + if(COOLDOWN_FINISHED(src, spam_cooldown_time)) + say("Prison ID with ongoing sentence detected. Access denied.") + playsound(src, 'sound/machines/buzz/buzz-two.ogg', 50, FALSE) + COOLDOWN_START(src, spam_cooldown_time, SPAM_CD) + return BLOCK_EXIT + +/obj/machinery/prisongate/labour + name = "labor camp gate scanner" + +/obj/machinery/prisongate/labour/allow_prisoner_id(obj/item/card/id/advanced/prisoner/prison_id) + if(!prison_id.goal) + return SKIP_EXIT + if(prison_id.points >= prison_id.goal) + if(COOLDOWN_FINISHED(src, spam_cooldown_time)) + say("All points served. Access granted.") + playsound(src, 'sound/machines/chime.ogg', 50, FALSE) + COOLDOWN_START(src, spam_cooldown_time, SPAM_CD) + return ALLOW_EXIT + if(COOLDOWN_FINISHED(src, spam_cooldown_time)) + say("[prison_id.goal - prison_id.points] point\s remaining on sentence. Access denied.") + playsound(src, 'sound/machines/buzz/buzz-two.ogg', 50, FALSE) + COOLDOWN_START(src, spam_cooldown_time, SPAM_CD) + return BLOCK_EXIT + #undef SPAM_CD +#undef ALLOW_EXIT +#undef BLOCK_EXIT +#undef SKIP_EXIT diff --git a/code/game/machinery/quantum_pad.dm b/code/game/machinery/quantum_pad.dm index 3d3bbc76163..b57df71107f 100644 --- a/code/game/machinery/quantum_pad.dm +++ b/code/game/machinery/quantum_pad.dm @@ -94,7 +94,10 @@ /obj/machinery/quantumpad/update_icon_state() . = ..() - icon_state = panel_open ? "[base_icon_state]-idle-open" : "[base_icon_state]-idle" + if(machine_stat & (BROKEN|NOPOWER) || state_open) + icon_state = "[base_icon_state]-idle-open" + else + icon_state = "[base_icon_state]-idle" /obj/machinery/quantumpad/interact(mob/user, obj/machinery/quantumpad/target_pad = linked_pad) if(QDELETED(target_pad)) diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index 71fb98e224d..1babfa078e9 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -389,7 +389,7 @@ GLOBAL_LIST_EMPTY(req_console_ckey_departments) /obj/machinery/requests_console/ui_data(mob/user) var/list/data = list() - data["is_admin_ghost_ai"] = isAdminGhostAI() + data["is_admin_ghost_ai"] = isAdminGhostAI(user) data["can_send_announcements"] = can_send_announcements data["department"] = department data["emergency"] = emergency diff --git a/code/game/machinery/slotmachine.dm b/code/game/machinery/slotmachine.dm index 8903bacc8f0..5fcb061e065 100644 --- a/code/game/machinery/slotmachine.dm +++ b/code/game/machinery/slotmachine.dm @@ -579,7 +579,7 @@ desc = "Repurposed from a confiscated syndicate gambling ring. Losing is a crime. Winning is also a crime." symbol_paths = list( /obj/item/food/donut/berry, - /mob/living/simple_animal/bot/secbot/beepsky, + /mob/living/basic/bot/secbot/beepsky, /obj/item/melee/baton/security/loaded, /obj/item/gun/energy/disabler, /obj/vehicle/sealed/mecha/ripley/paddy, diff --git a/code/game/machinery/stasis.dm b/code/game/machinery/stasis.dm index 539d3cc0e8d..89f8c527e18 100644 --- a/code/game/machinery/stasis.dm +++ b/code/game/machinery/stasis.dm @@ -172,10 +172,10 @@ else if(HAS_TRAIT(L_occupant, TRAIT_STASIS)) thaw_them(L_occupant) -/obj/machinery/stasis/screwdriver_act(mob/living/user, obj/item/I) - return default_deconstruction_screwdriver(user, I) +/obj/machinery/stasis/screwdriver_act(mob/living/user, obj/item/tool) + return default_deconstruction_screwdriver(user, tool) -/obj/machinery/stasis/crowbar_act(mob/living/user, obj/item/I) - return default_deconstruction_crowbar(user, I) +/obj/machinery/stasis/crowbar_act(mob/living/user, obj/item/tool) + return default_deconstruction_crowbar(user, tool) #undef STASIS_TOGGLE_COOLDOWN diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 5b78deb2bc0..838e902f0bc 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -732,8 +732,7 @@ wires.interact(user) return ITEM_INTERACT_SUCCESS else if(tool.tool_behaviour == TOOL_CROWBAR) - default_deconstruction_crowbar(tool) - return ITEM_INTERACT_SUCCESS + return default_deconstruction_crowbar(user, tool) if(default_pry_open(user, tool) & ITEM_INTERACT_SUCCESS) dump_inventory_contents() diff --git a/code/game/machinery/syndicatebeacon.dm b/code/game/machinery/syndicatebeacon.dm index 97ac006bcd5..7eec0b16f40 100644 --- a/code/game/machinery/syndicatebeacon.dm +++ b/code/game/machinery/syndicatebeacon.dm @@ -24,10 +24,6 @@ if(user) to_chat(user, span_notice("The connected wire doesn't have enough current.")) return - for (var/datum/component/singularity/singulo as anything in GLOB.singularities) - var/atom/singulo_atom = singulo.parent - if(singulo_atom.z == z) - singulo.target = src icon_state = "[icontype]1" active = TRUE if(user) @@ -35,8 +31,7 @@ /obj/machinery/power/singularity_beacon/proc/Deactivate(mob/user = null) - for(var/_singulo in GLOB.singularities) - var/datum/component/singularity/singulo = _singulo + for(var/datum/component/singularity/singulo as anything in GLOB.singularities) if(singulo.target == src) singulo.target = null icon_state = "[icontype]0" @@ -97,10 +92,10 @@ 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 + for(var/datum/component/singularity/singulo_component as anything in GLOB.singularities) var/atom/singulo = singulo_component.parent if(singulo.z == z) + singulo_component.target = src say("[singulo] is now [get_dist(src,singulo)] standard lengths away to the [dir2text(get_dir(src,singulo))]") else Deactivate() diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm index c09b74cab85..942344a30d6 100644 --- a/code/game/machinery/syndicatebomb.dm +++ b/code/game/machinery/syndicatebomb.dm @@ -20,7 +20,7 @@ /// What is the lowest amount of time we can set the timer to? var/minimum_timer = SYNDIEBOMB_MIN_TIMER_SECONDS /// What is the highest amount of time we can set the timer to? - var/maximum_timer = 100 MINUTES + var/maximum_timer = 100*60 // 100 MINUTES // not using the MINUTES define because those are for deciseconds /// What is the default amount of time we set the timer to? var/timer_set = SYNDIEBOMB_MIN_TIMER_SECONDS /// Can we be unanchored? diff --git a/code/game/machinery/telecomms/machines/message_server.dm b/code/game/machinery/telecomms/machines/message_server.dm index f9fb183e53e..cb34bf1e813 100644 --- a/code/game/machinery/telecomms/machines/message_server.dm +++ b/code/game/machinery/telecomms/machines/message_server.dm @@ -105,7 +105,7 @@ if (calibrating) calibrating += world.time say("Calibrating... Estimated wait time: [rand(3, 9)] minutes.") - pda_msgs += new /datum/data_tablet_msg("System Administrator", "system", "This is an automated message. System calibration started at [station_time_timestamp()].") + pda_msgs += new /datum/data_tablet_msg("System Administrator", "system", "This is an automated message. System calibration started at [server_timestamp(ic_time = TRUE)] (PT: [round_timestamp()]).") else pda_msgs += new /datum/data_tablet_msg("System Administrator", "system", MESSAGE_SERVER_FUNCTIONING_MESSAGE) diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index 4e7ca61d0dd..91e858273ec 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -82,12 +82,16 @@ RETURN_TYPE(/datum/reagents) if (reagents) return reagents + return init_reagents(decal_reagent, reagent_amount) - if (!decal_reagent) +/obj/effect/decal/cleanable/proc/init_reagents(reagent = null, amount = null) + RETURN_TYPE(/datum/reagents) + + if (!reagent) return - create_reagents(reagent_amount) - reagents.add_reagent(decal_reagent, reagent_amount) + create_reagents(amount) + reagents.add_reagent(reagent, amount) return reagents /obj/effect/decal/cleanable/item_interaction(mob/living/user, obj/item/tool, list/modifiers) diff --git a/code/game/objects/effects/decals/cleanable/blood.dm b/code/game/objects/effects/decals/cleanable/blood.dm index 6ce7fc07c5f..3c1481a0ceb 100644 --- a/code/game/objects/effects/decals/cleanable/blood.dm +++ b/code/game/objects/effects/decals/cleanable/blood.dm @@ -134,7 +134,9 @@ create_reagents(round(bloodiness * BLOOD_TO_UNITS_MULTIPLIER, CHEMICAL_VOLUME_ROUNDING)) var/num_reagents = length(reagents_to_add) for(var/reagent_type in reagents_to_add) - reagents.add_reagent(reagent_type, round(bloodiness * BLOOD_TO_UNITS_MULTIPLIER / num_reagents, CHEMICAL_VOLUME_ROUNDING)) + reagents.add_reagent(reagent_type = reagent_type, + amount = round(bloodiness * BLOOD_TO_UNITS_MULTIPLIER / num_reagents, CHEMICAL_VOLUME_ROUNDING), + data = ispath(reagent_type, /datum/reagent/blood) ? list("blood_DNA" = pick(blood_DNA)) : null) return reagents /obj/effect/decal/cleanable/blood/replace_decal(obj/effect/decal/cleanable/blood/merger) @@ -540,13 +542,7 @@ /obj/effect/decal/cleanable/blood/gibs/lazy_init_reagents() if (reagents) return reagents - - if (!decal_reagent) - return - - create_reagents(reagent_amount) - reagents.add_reagent(decal_reagent, reagent_amount) - return reagents + return init_reagents(decal_reagent, reagent_amount) /obj/effect/decal/cleanable/blood/gibs/update_overlays() . = ..() diff --git a/code/game/objects/effects/decals/cleanable/toxic.dm b/code/game/objects/effects/decals/cleanable/toxic.dm new file mode 100644 index 00000000000..13a3fe57a0f --- /dev/null +++ b/code/game/objects/effects/decals/cleanable/toxic.dm @@ -0,0 +1,61 @@ +#define DISSOLVE_DURATION 45 SECONDS + +/obj/effect/decal/cleanable/greenglow/waste + name = "caustic sludge" + desc = "A puddle of toxic, industrial waste. Eats through the floor if not cleaned up." + icon_state = "waste_spill" + light_power = 1 + beauty = -300 + clean_type = CLEAN_TYPE_ACID + decal_reagent = /datum/reagent/toxin/acid/industrial_waste + reagent_amount = 5 + alpha = 0 + color = "#bebebe8e" + + /// audio of the waste bubbling and melting things. + var/datum/looping_sound/bubbling_audio // It's really just bubbling liquid audio, which is what I need here. + /// TimerID for the floor melting effect, so we can stop it if it gets cleaned up. + var/dissolve_timer + +/obj/effect/decal/cleanable/greenglow/waste/Initialize(mapload, list/datum/disease/diseases) + . = ..() + animate(src, alpha = 255, time = 0.5 SECONDS) + + var/mutable_appearance/splash_animation = mutable_appearance('icons/effects/effects.dmi', "splash_hydroponics") + splash_animation.color = "#15ff00" + flick_overlay_view(splash_animation, 1.1 SECONDS) + +/obj/effect/decal/cleanable/greenglow/waste/Destroy() + QDEL_NULL(bubbling_audio) + QDEL_NULL(particles) + return ..() + +/** + * Sets up our waste to perform dissolve_floor after the timer goes off. + */ +/obj/effect/decal/cleanable/greenglow/waste/proc/pre_dissolve(display_message = TRUE, dissolve_clock = DISSOLVE_DURATION) + if(display_message) + visible_message(span_warning("\The [src] begins corroding \the [get_turf(src)]!")) + color = "#ffffffff" + + playsound(src, 'sound/items/tools/welder.ogg', 50, TRUE) + bubbling_audio = new /datum/looping_sound/soup/toxic(src) + bubbling_audio.start() + + dissolve_timer = addtimer(CALLBACK(src, PROC_REF(dissolve_floor)), dissolve_clock, TIMER_STOPPABLE | TIMER_DELETE_ME) + particles = new /particles/acid/toxic() + +/obj/effect/decal/cleanable/greenglow/waste/proc/dissolve_floor() + if(QDELETED(src)) + return + var/atom/splashed_turf = get_turf(src) + if(!isfloorturf(splashed_turf)) + return + var/turf/open/splash_floor = splashed_turf + splash_floor.ScrapeAway(flags = CHANGETURF_IGNORE_AIR) //Eat away the floor + visible_message(span_warning("The waste eats away at the floor, leaving \the [get_turf(src)] behind.")) + animate(src, time = 0.5 SECONDS, color = "#bebebe8e") + bubbling_audio?.stop() + QDEL_NULL(particles) + +#undef DISSOLVE_DURATION diff --git a/code/game/objects/effects/effect_system/fluid_spread/effects_foam.dm b/code/game/objects/effects/effect_system/fluid_spread/effects_foam.dm index 736be058ee4..cea1190aa66 100644 --- a/code/game/objects/effects/effect_system/fluid_spread/effects_foam.dm +++ b/code/game/objects/effects/effect_system/fluid_spread/effects_foam.dm @@ -31,12 +31,17 @@ var/allow_duplicate_results = TRUE /// The amount of time this foam stick around for before it dissipates. var/lifetime = 8 SECONDS + /// The orignal value of lifetime + var/original_lifetime = 8 SECONDS /// Whether or not this foam should be slippery. var/slippery_foam = TRUE -/obj/effect/particle_effect/fluid/foam/Initialize(mapload) +/obj/effect/particle_effect/fluid/foam/Initialize(mapload, fluid_group, source, lifetime, slippery) . = ..() + src.lifetime = lifetime ? lifetime : src.lifetime + src.original_lifetime = src.lifetime + src.slippery_foam = !isnull(slippery) ? slippery : slippery_foam if(slippery_foam) AddComponent(/datum/component/slippery, 100, can_slip_callback = CALLBACK(src, PROC_REF(try_slip))) if(HAS_TRAIT(loc, TRAIT_ELEVATED_TURF)) @@ -165,7 +170,7 @@ continue foam_mob(foaming, seconds_per_tick) - var/obj/effect/particle_effect/fluid/foam/spread_foam = new type(spread_turf, group, src) + var/obj/effect/particle_effect/fluid/foam/spread_foam = new type(spread_turf, group, src, src.original_lifetime, src.slippery_foam) reagents.trans_to(spread_foam, reagents.total_volume, copy_only = TRUE) spread_foam.add_atom_colour(color, FIXED_COLOUR_PRIORITY) spread_foam.result_type = result_type @@ -219,7 +224,7 @@ /// What type of thing the foam should leave behind when it dissipates. var/atom/movable/result_type = null -/datum/effect_system/fluid_spread/foam/New(turf/location, range = 1, amount = null, atom/holder = null, datum/reagents/carry = null, result_type = null, stop_reactions = FALSE, reagent_scale = FOAM_REAGENT_SCALE) +/datum/effect_system/fluid_spread/foam/New(turf/location, range = 1, amount = null, atom/holder = null, datum/reagents/carry = null, result_type = null, stop_reactions = FALSE, reagent_scale = FOAM_REAGENT_SCALE,) . = ..() chemholder = new(1000, NO_REACT) carry?.trans_to(chemholder, carry.total_volume, no_react = stop_reactions, copy_only = TRUE) @@ -231,8 +236,8 @@ QDEL_NULL(chemholder) return ..() -/datum/effect_system/fluid_spread/foam/start(log = FALSE) - var/obj/effect/particle_effect/fluid/foam/foam = new effect_type(location, new /datum/fluid_group(amount)) +/datum/effect_system/fluid_spread/foam/start(log = FALSE, lifetime, slippery) + var/obj/effect/particle_effect/fluid/foam/foam = new effect_type(location, new /datum/fluid_group(amount), null, lifetime, slippery) var/foamcolor = mix_color_from_reagents(chemholder.reagent_list) if(reagent_scale > 1) // Make room in case we were created by a particularly stuffed payload. foam.reagents.maximum_volume *= reagent_scale @@ -291,10 +296,9 @@ QDEL_NULL(hotspot) var/datum/gas_mixture/air = location.air - var/list/gases = air.gases - if (gases[/datum/gas/plasma]) - var/scrub_amt = min(30, gases[/datum/gas/plasma][MOLES]) //Absorb some plasma - gases[/datum/gas/plasma][MOLES] -= scrub_amt + if (air.gases[/datum/gas/plasma]) + var/scrub_amt = min(30, air.gases[/datum/gas/plasma][MOLES]) //Absorb some plasma + air.adjust_gas(/datum/gas/plasma, -scrub_amt) absorbed_plasma += scrub_amt if (air.temperature > T20C) air.temperature = max(air.temperature / 2, T20C) diff --git a/code/game/objects/effects/effect_system/fluid_spread/effects_smoke.dm b/code/game/objects/effects/effect_system/fluid_spread/effects_smoke.dm index b6d3d892896..cca69643fb3 100644 --- a/code/game/objects/effects/effect_system/fluid_spread/effects_smoke.dm +++ b/code/game/objects/effects/effect_system/fluid_spread/effects_smoke.dm @@ -297,11 +297,10 @@ if(!distcheck || get_dist(location, chilly) < blast) // Otherwise we'll get silliness like people using Nanofrost to kill people through walls with cold air air.temperature = temperature - var/list/gases = air.gases - if(gases[/datum/gas/plasma]) - air.assert_gas(/datum/gas/nitrogen) - gases[/datum/gas/nitrogen][MOLES] += gases[/datum/gas/plasma][MOLES] - gases[/datum/gas/plasma][MOLES] = 0 + if(air.gases[/datum/gas/plasma]) + var/mole_count = air.gases[/datum/gas/plasma][MOLES] + air.adjust_gas(/datum/gas/nitrogen, mole_count) + air.adjust_gas(/datum/gas/plasma, -mole_count) air.garbage_collect() for(var/obj/effect/hotspot/fire in chilly) diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index d4d54ed8abf..edd348fb52a 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -275,36 +275,64 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark) GLOB.wizardstart += loc return INITIALIZE_HINT_QDEL -/obj/effect/landmark/start/nukeop +/// Places to put midround nukeops (normal) +GLOBAL_LIST_EMPTY(nukeop_base_start) +/// Places to put midround nukeops (leader) +GLOBAL_LIST_EMPTY(nukeop_base_leader_start) +/// Places to put nukeops overwatch agents +GLOBAL_LIST_EMPTY(nukeop_base_overwatch_start) +/// Places to spawn nukeops on roundstart +GLOBAL_LIST_EMPTY(nukeop_elevator_start) + +/obj/effect/landmark/start/nukeop_base name = "nukeop" icon = 'icons/effects/landmarks_static.dmi' icon_state = "snukeop_spawn" -/obj/effect/landmark/start/nukeop/Initialize(mapload) +/obj/effect/landmark/start/nukeop_base/Initialize(mapload) ..() - GLOB.nukeop_start += loc + var/list/add_to = get_global_list() + add_to += loc return INITIALIZE_HINT_QDEL -/obj/effect/landmark/start/nukeop_leader +/obj/effect/landmark/start/nukeop_base/proc/get_global_list() + return GLOB.nukeop_base_start + +/obj/effect/landmark/start/nukeop_base/leader name = "nukeop leader" icon = 'icons/effects/landmarks_static.dmi' icon_state = "snukeop_leader_spawn" -/obj/effect/landmark/start/nukeop_leader/Initialize(mapload) - ..() - GLOB.nukeop_leader_start += loc - return INITIALIZE_HINT_QDEL +/obj/effect/landmark/start/nukeop_base/leader/get_global_list() + return GLOB.nukeop_base_leader_start -/obj/effect/landmark/start/nukeop_overwatch +/obj/effect/landmark/start/nukeop_base/overwatch name = "nukeop overwatch" icon = 'icons/effects/landmarks_static.dmi' icon_state = "snukeop_leader_spawn" -/obj/effect/landmark/start/nukeop_overwatch/Initialize(mapload) - ..() - GLOB.nukeop_overwatch_start += loc +/obj/effect/landmark/start/nukeop_base/overwatch/get_global_list() + return GLOB.nukeop_base_overwatch_start + +/obj/effect/landmark/start/nukeop_elevator + name = "nukeop (elevator)" + icon = /obj/effect/landmark/start/nukeop_base::icon + icon_state = /obj/effect/landmark/start/nukeop_base::icon_state + +/obj/effect/landmark/start/nukeop_elevator/Initialize(mapload) + . = ..() + GLOB.nukeop_elevator_start += loc return INITIALIZE_HINT_QDEL +/obj/effect/landmark/nukeop_elevator + icon_state = "x" + +/obj/effect/landmark/nukeop_elevator/interior + name = "nukeop elevator interior top right corner" + +/obj/effect/landmark/nukeop_elevator/exterior + name = "nukeop elevator exterior top right corner" + // Must be immediate because players will // join before SSatom initializes everything. INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) diff --git a/code/game/objects/effects/particles/acid.dm b/code/game/objects/effects/particles/acid.dm index 5ce0984991d..19683b6ad78 100644 --- a/code/game/objects/effects/particles/acid.dm +++ b/code/game/objects/effects/particles/acid.dm @@ -13,3 +13,16 @@ gravity = list(0, 0.15) position = generator(GEN_SPHERE, 0, 16, NORMAL_RAND) spin = generator(GEN_NUM, -15, 15, NORMAL_RAND) + +/particles/acid/toxic + count = 1000 + spawning = 4 + color = "#34ff19a1" + lifespan = null + grow = -0.08 + velocity = list(0, 1, 0) + position = generator(GEN_CIRCLE, 0, 16, NORMAL_RAND) + drift = generator(GEN_VECTOR, list(0, -0.2), list(0, 0.2)) + gravity = list(0, 0) + rotation = 25 + spin = generator(GEN_NUM, -20, 20) diff --git a/code/game/objects/effects/spawners/bombspawner.dm b/code/game/objects/effects/spawners/bombspawner.dm index 9d1da48cd29..c5c82b485e0 100644 --- a/code/game/objects/effects/spawners/bombspawner.dm +++ b/code/game/objects/effects/spawners/bombspawner.dm @@ -44,14 +44,11 @@ if(!first_gasmix || !second_gasmix) return - first_gasmix.temperature = 1413 - second_gasmix.temperature = 141.3 + first_gasmix.set_temperature(1413) + second_gasmix.set_temperature(141.3) - first_gasmix.assert_gas(/datum/gas/plasma) - second_gasmix.assert_gas(/datum/gas/oxygen) - - first_gasmix.gases[/datum/gas/plasma][MOLES] = calculate_pressure(first_gasmix, TANK_LEAK_PRESSURE - 1) - second_gasmix.gases[/datum/gas/oxygen][MOLES] = calculate_pressure(second_gasmix, TANK_LEAK_PRESSURE - 1) + first_gasmix.set_gas(/datum/gas/plasma, calculate_pressure(first_gasmix, TANK_LEAK_PRESSURE - 1)) + second_gasmix.set_gas(/datum/gas/oxygen, calculate_pressure(second_gasmix, TANK_LEAK_PRESSURE - 1)) /obj/effect/spawner/newbomb/tritium @@ -60,16 +57,13 @@ if(!first_gasmix || !second_gasmix) return - first_gasmix.temperature = 8000 - second_gasmix.temperature = 43 + first_gasmix.set_temperature(8000) + second_gasmix.set_temperature(43) - first_gasmix.assert_gas(/datum/gas/plasma) - second_gasmix.assert_gas(/datum/gas/oxygen) - second_gasmix.assert_gas(/datum/gas/tritium) + first_gasmix.set_gas(/datum/gas/plasma, calculate_pressure(first_gasmix, TANK_LEAK_PRESSURE - 1)) - first_gasmix.gases[/datum/gas/plasma][MOLES] = calculate_pressure(first_gasmix, TANK_LEAK_PRESSURE - 1) - second_gasmix.gases[/datum/gas/oxygen][MOLES] = 0.67 * calculate_pressure(second_gasmix, TANK_LEAK_PRESSURE - 1) - second_gasmix.gases[/datum/gas/tritium][MOLES] = 0.33 * calculate_pressure(second_gasmix, TANK_LEAK_PRESSURE - 1) + second_gasmix.set_gas(/datum/gas/oxygen, 0.67 * calculate_pressure(second_gasmix, TANK_LEAK_PRESSURE - 1)) + second_gasmix.set_gas(/datum/gas/tritium, 0.33 * calculate_pressure(second_gasmix, TANK_LEAK_PRESSURE - 1)) /obj/effect/spawner/newbomb/isolated_tritium @@ -78,16 +72,13 @@ if(!first_gasmix || !second_gasmix) return - first_gasmix.temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST + 1 - second_gasmix.temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST + 1 + first_gasmix.set_temperature(FIRE_MINIMUM_TEMPERATURE_TO_EXIST + 1) + second_gasmix.set_temperature(FIRE_MINIMUM_TEMPERATURE_TO_EXIST + 1) - first_gasmix.assert_gas(/datum/gas/hypernoblium) - first_gasmix.assert_gas(/datum/gas/tritium) - second_gasmix.assert_gas(/datum/gas/oxygen) + first_gasmix.set_gas(/datum/gas/hypernoblium, REACTION_OPPRESSION_THRESHOLD - 0.01,) + first_gasmix.set_gas( /datum/gas/tritium, 0.5 * calculate_pressure(first_gasmix, TANK_LEAK_PRESSURE - 1)) - first_gasmix.gases[/datum/gas/hypernoblium][MOLES] = REACTION_OPPRESSION_THRESHOLD - 0.01 - first_gasmix.gases[/datum/gas/tritium][MOLES] = 0.5 * calculate_pressure(first_gasmix, TANK_LEAK_PRESSURE - 1) - second_gasmix.gases[/datum/gas/oxygen][MOLES] = calculate_pressure(second_gasmix, TANK_LEAK_PRESSURE-1) + second_gasmix.set_gas(/datum/gas/oxygen, calculate_pressure(second_gasmix, TANK_LEAK_PRESSURE-1)) /obj/effect/spawner/newbomb/noblium @@ -96,14 +87,11 @@ if(!first_gasmix || !second_gasmix) return - first_gasmix.temperature = 2.7 - second_gasmix.temperature = 2.7 + first_gasmix.set_temperature(2.7) + second_gasmix.set_temperature(2.7) - first_gasmix.assert_gas(/datum/gas/nitrogen) - second_gasmix.assert_gas(/datum/gas/tritium) - - first_gasmix.gases[/datum/gas/nitrogen][MOLES] = calculate_pressure(first_gasmix, TANK_LEAK_PRESSURE - 1) - second_gasmix.gases[/datum/gas/tritium][MOLES] = calculate_pressure(second_gasmix, TANK_LEAK_PRESSURE - 1) + first_gasmix.set_gas(/datum/gas/nitrogen, calculate_pressure(first_gasmix, TANK_LEAK_PRESSURE - 1)) + second_gasmix.set_gas(/datum/gas/tritium, calculate_pressure(second_gasmix, TANK_LEAK_PRESSURE - 1)) /obj/effect/spawner/newbomb/pressure @@ -112,11 +100,8 @@ if(!first_gasmix || !second_gasmix) return - first_gasmix.temperature = 20000 - second_gasmix.temperature = 2.7 + first_gasmix.set_temperature(20000) + second_gasmix.set_temperature(2.7) - first_gasmix.assert_gas(/datum/gas/hypernoblium) - second_gasmix.assert_gas(/datum/gas/tritium) - - first_gasmix.gases[/datum/gas/hypernoblium][MOLES] = calculate_pressure(first_gasmix, TANK_LEAK_PRESSURE - 1) - second_gasmix.gases[/datum/gas/tritium][MOLES] = calculate_pressure(second_gasmix, TANK_LEAK_PRESSURE - 1) + first_gasmix.set_gas(/datum/gas/hypernoblium, calculate_pressure(first_gasmix, TANK_LEAK_PRESSURE - 1)) + second_gasmix.set_gas(/datum/gas/tritium, calculate_pressure(second_gasmix, TANK_LEAK_PRESSURE - 1)) diff --git a/code/game/objects/effects/spawners/random/exotic.dm b/code/game/objects/effects/spawners/random/exotic.dm index 901bb06cee7..500d0832e4c 100644 --- a/code/game/objects/effects/spawners/random/exotic.dm +++ b/code/game/objects/effects/spawners/random/exotic.dm @@ -43,35 +43,61 @@ ) /obj/effect/spawner/random/exotic/antag_gear_weak - name = "antag gear weak" + name = "loot weak" icon_state = "syndi_toolbox" loot = list( - /obj/item/storage/medkit/regular = 45, - /obj/item/storage/medkit/toxin = 35, - /obj/item/storage/medkit/brute = 27, - /obj/item/storage/medkit/fire = 27, - /obj/item/storage/toolbox/syndicate = 12, - /obj/item/borg/upgrade/diamond_drill = 3, - /obj/item/knife/butcher = 14, - /obj/item/clothing/glasses/night = 10, - /obj/item/pickaxe/drill/diamonddrill = 6, + /obj/item/clothing/glasses/science/night = 15, + /obj/item/storage/fancy/cigarettes/cigpack_syndicate = 10, + /obj/item/storage/toolbox/syndicate = 10, + /obj/item/shield/riot = 10, + /obj/item/storage/box/syndie_kit/chameleon = 10, + /obj/item/knife/combat = 10, + /obj/item/grenade/clusterbuster/smoke = 10, + /obj/item/stack/sheet/mineral/diamond{amount = 15} = 5, + /obj/item/stack/sheet/mineral/uranium{amount = 15} = 5, + /obj/item/stack/sheet/mineral/plasma{amount = 15} = 5, + /obj/item/stack/sheet/mineral/gold{amount = 15} = 5, + /obj/item/implantcase/deathrattle = 5, ) /obj/effect/spawner/random/exotic/antag_gear name = "antag gear" icon_state = "esword" loot = list( - /obj/item/clothing/glasses/science/night = 15, - /obj/item/shield/riot = 12, - /obj/item/stack/sheet/mineral/diamond{amount = 15} = 5, - /obj/item/stack/sheet/mineral/uranium{amount = 15} = 5, - /obj/item/stack/sheet/mineral/plasma{amount = 15} = 5, - /obj/item/stack/sheet/mineral/gold{amount = 15} = 5, - /obj/item/grenade/clusterbuster/smoke = 15, - /obj/item/clothing/under/chameleon = 13, - /obj/item/knife/combat = 10, - /obj/item/implantcase/deathrattle = 5, - /obj/item/storage/fancy/cigarettes/cigpack_syndicate = 1, + /obj/item/storage/box/stockparts/deluxe = 13, + /obj/item/storage/box/survival/syndie = 9, + /obj/item/reagent_containers/spray/syndicate = 9, + /obj/item/flashlight/lantern/syndicate = 5, + /obj/item/storage/box/evilmeds = 5, + /obj/item/storage/box/syndie_kit/space = 5, + /obj/item/gun/ballistic/automatic/pistol/m1911 = 5,//replaces makarov + /obj/item/climbing_hook/syndicate = 5, + /obj/item/dualsaber/toy = 5, + /obj/item/card/emag/blue = 5, + /obj/item/storage/box/syndie_kit/imp_storage = 5, + /obj/item/storage/box/syndie_kit/imp_radio = 5, + /obj/item/storage/box/alchemist_random_chems = 5, + /obj/item/gun/ballistic/automatic/smartgun = 4, + /obj/item/autosurgeon/syndicate/emaggedsurgerytoolset/single_use = 3, + /obj/item/mod/module/energy_shield/prototype = 2, + /obj/item/mod/module/jetpack/advanced = 2, + /obj/item/mod/module/visor/night = 2, + /obj/item/mod/module/storage/syndicate = 2, + /obj/item/autosurgeon/syndicate/anti_stun/single_use = 2, + /obj/item/mod/module/jetpack/advanced = 2, + /obj/item/melee/energy/sword/surplus = 1, + /obj/item/mod/control/pre_equipped/responsory/inquisitory/syndie/less_mods = 1, + /obj/item/gun/ballistic/automatic/napad = 1, + /obj/effect/spawner/random/exotic/antag_sub_spawner = 1, + /obj/item/card/emag/blue = 1, + ) + +/obj/effect/spawner/random/exotic/antag_sub_spawner + name = "antag gear sub spawner" + loot = list( + /obj/item/storage/box/stockparts/deluxe = 98, + /obj/item/storage/box/syndicate/bundle_b = 1, + /obj/item/storage/box/syndicate/bundle_a = 1, ) /obj/effect/spawner/random/exotic/snow_gear @@ -90,3 +116,25 @@ /obj/structure/mecha_wreckage/ripley = 3, /obj/vehicle/sealed/mecha/ripley/mining = 1, ) + +/obj/item/mod/module/energy_shield/prototype + name = "MOD prototype energy shield" + desc = "An early prototype of energy shield adapted for use inside of a MOD, the energy shield before this saw \ + extensive use in now defunct construction, combat, and mining exosuits with exosuits being something between a \ + modsuit and a mech with most still functioning exosuits either being in a museaum or a military parade" + recharge_start_delay = 30 SECONDS + max_charges = 2 + charge_increment_delay = 30 SECONDS + shield_icon = "shield-yellow" + +/obj/item/mod/control/pre_equipped/responsory/inquisitory/syndie/less_mods + starting_frequency = null + req_access = null + applied_cell = /obj/item/stock_parts/power_store/cell/super + insignia_type = /obj/item/mod/module/insignia/security + theme = /datum/mod_theme/responsory/traitor + applied_modules = list( + /obj/item/mod/module/magnetic_harness, + /obj/item/mod/module/jetpack, + /obj/item/mod/module/pathfinder, + ) diff --git a/code/game/objects/effects/spawners/random/medical.dm b/code/game/objects/effects/spawners/random/medical.dm index 57b180a02b4..5c2017e23b2 100644 --- a/code/game/objects/effects/spawners/random/medical.dm +++ b/code/game/objects/effects/spawners/random/medical.dm @@ -75,7 +75,7 @@ /obj/effect/spawner/random/medical/surgery_tool name = "Surgery tool spawner" - icon_state = "scapel" + icon_state = "scalpel" loot = list( /obj/item/scalpel, /obj/item/hemostat, @@ -88,7 +88,7 @@ /obj/effect/spawner/random/medical/surgery_tool_advanced name = "Advanced surgery tool spawner" - icon_state = "scapel" + icon_state = "scalpel" loot = list( // Mail loot spawner. Drop pool of advanced medical tools typically from research. Not endgame content. /obj/item/scalpel/advanced, /obj/item/retractor/advanced, @@ -97,7 +97,7 @@ /obj/effect/spawner/random/medical/surgery_tool_alien name = "Rare surgery tool spawner" - icon_state = "scapel" + icon_state = "scalpel" loot = list( // Mail loot spawner. Some sort of random and rare surgical tool. Alien tech found here. /obj/item/scalpel/alien, /obj/item/hemostat/alien, diff --git a/code/game/objects/effects/spawners/random/mining_loot.dm b/code/game/objects/effects/spawners/random/mining_loot.dm index 682c6e4ad23..f5f86dbe5f3 100644 --- a/code/game/objects/effects/spawners/random/mining_loot.dm +++ b/code/game/objects/effects/spawners/random/mining_loot.dm @@ -58,7 +58,7 @@ icon = 'icons/obj/mining.dmi' icon_state = "modkit" loot = list( - /obj/item/borg/upgrade/modkit/aoe/mobs/andturfs = 1, + /obj/item/borg/upgrade/modkit/cooldown/aoe/mobs/andturfs = 1, /obj/item/borg/upgrade/modkit/cooldown/repeater = 1, /obj/item/borg/upgrade/modkit/resonator_blasts = 1, /obj/item/borg/upgrade/modkit/bounty = 1, diff --git a/code/game/objects/effects/spawners/random/structure.dm b/code/game/objects/effects/spawners/random/structure.dm index bfebd92e01f..38f49d611cb 100644 --- a/code/game/objects/effects/spawners/random/structure.dm +++ b/code/game/objects/effects/spawners/random/structure.dm @@ -22,6 +22,7 @@ /obj/structure/closet/mini_fridge = 35, /obj/effect/spawner/random/trash/mess = 30, /obj/item/kirbyplants/fern = 20, + /obj/effect/spawner/random/gizmo = 20, /obj/structure/closet/crate/decorations = 15, /obj/effect/decal/remains/human/smokey/maintenance = 7, /obj/structure/destructible/cult/pants_altar = 1, diff --git a/code/game/objects/effects/temporary_visuals/effect_trail.dm b/code/game/objects/effects/temporary_visuals/effect_trail.dm index 5eed9462dfd..e8ab9526f51 100644 --- a/code/game/objects/effects/temporary_visuals/effect_trail.dm +++ b/code/game/objects/effects/temporary_visuals/effect_trail.dm @@ -27,7 +27,7 @@ return INITIALIZE_HINT_QDEL AddElement(/datum/element/floor_loving) - AddComponent(/datum/component/spawner, spawn_types = list(spawned_effect), max_spawned = max_spawned, spawn_time = spawn_interval) + add_spawner() src.target = target movement = GLOB.move_manager.move_towards(src, chasing = target, delay = move_speed, home = homing, timeout = duration, flags = MOVEMENT_LOOP_START_FAST) @@ -35,6 +35,9 @@ if (isliving(target)) RegisterSignal(target, COMSIG_LIVING_DEATH, PROC_REF(on_target_invalid)) +/obj/effect/temp_visual/effect_trail/proc/add_spawner() + AddComponent(/datum/component/spawner, spawn_types = list(spawned_effect), max_spawned = max_spawned, spawn_time = spawn_interval) + /// Destroy ourselves if the target is no longer valid /obj/effect/temp_visual/effect_trail/proc/on_target_invalid() SIGNAL_HANDLER diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm index 6d8e8104f50..91729cae9b2 100644 --- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm +++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm @@ -782,17 +782,17 @@ pixel_x = -16 pixel_y = -16 duration = 0.5 SECONDS - color = COLOR_LIME var/max_alpha = 255 ///How far the effect would scale in size var/amount_to_scale = 2 -/obj/effect/temp_visual/circle_wave/Initialize(mapload) +/obj/effect/temp_visual/circle_wave/Initialize(mapload, color) transform = matrix().Scale(0.1) animate(src, transform = matrix().Scale(amount_to_scale), time = duration, flags = ANIMATION_PARALLEL) animate(src, alpha = max_alpha, time = duration * 0.6, flags = ANIMATION_PARALLEL) animate(alpha = 0, time = duration * 0.4) apply_wibbly_filters(src) + src.color ||= color return ..() /obj/effect/temp_visual/circle_wave/bioscrambler diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 8461f99a880..bfcf2ab4e59 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -445,7 +445,8 @@ if(item_flags & CRUEL_IMPLEMENT) .[span_red("morbid")] = "It seems quite practical for particularly morbid procedures and experiments." - + if(item_flags & BLUESPACE_INTERFERENCE) + .["bluespace-active"] = "It is highly active in bluespace and will cause malfunctions in teleporters." if (siemens_coefficient == 0) .["insulated"] = "It is made from a robust electrical insulator and will block any electricity passing through it!" else if (siemens_coefficient <= 0.5) @@ -2106,47 +2107,8 @@ obj_flags |= CONDUCTS_ELECTRICITY /obj/item/change_material_strength(datum/material/material, mat_amount, multiplier, remove = FALSE) - var/density = material.get_property(MATERIAL_DENSITY) - var/hardness = material.get_property(MATERIAL_HARDNESS) - var/flexibility = material.get_property(MATERIAL_FLEXIBILITY) - - // Item force calculation depends on its initial (assumed to be main) sharpness - // Transforming component doesn't work with materials at all and will need a refactor to change that, so we don't care about it here. - - var/force_mod = 1 - var/throwforce_mod = 1 - - switch (sharpness) - if (NONE) - // Blunt items are really hurt by all the flexing - force_mod = (1 + (density - 4) * 0.1) / (1 + flexibility * 0.1) - throwforce_mod = 1 + (density - 4) * 0.1 - flexibility * 0.1 - - if (SHARP_EDGED) - // Sharp items don't care about density and need high hardness to get a real bonus, but can tolerate (and benefit from) some flex - force_mod = 1 + (hardness - 4) * 0.1 - throwforce_mod = 1 + (hardness - 4) * 0.1 - - // Peaks out at 20% at flexibility of 1, drops off up to -80% at 10 - if (flexibility < 2) - force_mod *= 1 + (1 - abs(1 - flexibility)) * 0.2 - throwforce_mod += (1 - abs(1 - flexibility)) * 0.2 - else - force_mod *= 1 - (flexibility - 2) * 0.1 - throwforce_mod -= (flexibility - 2) * 0.1 - - if (SHARP_POINTY) - // Pointy items care about both density and hardness - force_mod = 1 + MATERIAL_PROPERTY_DIVERGENCE(density, 4, 6) * 0.05 + (hardness - 4) * 0.1 - throwforce_mod = 1 + MATERIAL_PROPERTY_DIVERGENCE(density, 4, 6) * 0.05 * 0.05 + (hardness - 4) * 0.1 - // But are not affected by flexibility until higher values, although they don't benefit from it either - if (flexibility > 4) - force_mod *= (1 - (flexibility - 4) * 0.2) - throwforce_mod -= (flexibility - 4) * 0.2 - - // Just for sanity in case something breaks - force_mod = round(clamp(force_mod, MATERIAL_MIN_FORCE_MULTIPLIER, MATERIAL_MAX_FORCE_MULTIPLIER), 0.01) - throwforce_mod = round(clamp(throwforce_mod, MATERIAL_MIN_FORCE_MULTIPLIER, MATERIAL_MAX_FORCE_MULTIPLIER), 0.01) + var/force_mod = get_material_force_modifier(material) + var/throwforce_mod = get_material_throwforce_modifier(material) if (!remove) force *= GET_MATERIAL_MODIFIER(force_mod, multiplier) @@ -2155,43 +2117,69 @@ force /= GET_MATERIAL_MODIFIER(force_mod, multiplier) throwforce /= GET_MATERIAL_MODIFIER(throwforce_mod, multiplier) -/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 +/// Returns a force multiplier from a material for a given sharpness +/obj/item/proc/get_material_force_modifier(datum/material/material, item_sharpness = get_sharpness()) + var/density = material.get_property(MATERIAL_DENSITY) + var/hardness = material.get_property(MATERIAL_HARDNESS) + var/flexibility = material.get_property(MATERIAL_FLEXIBILITY) + var/force_mod = 1 + switch (item_sharpness) + if (NONE) + // Blunt items are really hurt by all the flexing + force_mod = (1 + (density - 4) * 0.1) / (1 + flexibility * 0.1) -/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) + if (SHARP_EDGED) + // Sharp items don't care about density and need high hardness to get a real bonus, but can tolerate (and benefit from) some flex + force_mod = 1 + (hardness - 4) * 0.1 + + // Peaks out at 20% at flexibility of 1, drops off up to -80% at 10 + if (flexibility < 2) + force_mod *= 1 + (1 - abs(1 - flexibility)) * 0.2 + else + force_mod *= 1 - (flexibility - 2) * 0.1 + + if (SHARP_POINTY) + // Pointy items care about both density and hardness + force_mod = 1 + MATERIAL_PROPERTY_DIVERGENCE(density, 4, 6) * 0.05 + (hardness - 4) * 0.1 + // But are not affected by flexibility until higher values, although they don't benefit from it either + if (flexibility > 4) + force_mod *= (1 - (flexibility - 4) * 0.2) + + // Just for sanity in case something breaks + force_mod = round(clamp(force_mod, MATERIAL_MIN_FORCE_MULTIPLIER, MATERIAL_MAX_FORCE_MULTIPLIER), 0.01) + return force_mod + +/// Returns a force multiplier from a material for a given sharpness +/obj/item/proc/get_material_throwforce_modifier(datum/material/material, item_sharpness = get_sharpness()) + var/density = material.get_property(MATERIAL_DENSITY) + var/hardness = material.get_property(MATERIAL_HARDNESS) + var/flexibility = material.get_property(MATERIAL_FLEXIBILITY) + var/throwforce_mod = 1 + switch (item_sharpness) + if (NONE) + // Blunt items are really hurt by all the flexing + throwforce_mod = 1 + (density - 4) * 0.1 - flexibility * 0.1 + + if (SHARP_EDGED) + // Sharp items don't care about density and need high hardness to get a real bonus, but can tolerate (and benefit from) some flex + throwforce_mod = 1 + (hardness - 4) * 0.1 + + // Peaks out at 20% at flexibility of 1, drops off up to -80% at 10 + if (flexibility < 2) + throwforce_mod += (1 - abs(1 - flexibility)) * 0.2 + else + throwforce_mod -= (flexibility - 2) * 0.1 + + if (SHARP_POINTY) + // Pointy items care about both density and hardness + throwforce_mod = 1 + MATERIAL_PROPERTY_DIVERGENCE(density, 4, 6) * 0.05 * 0.05 + (hardness - 4) * 0.1 + // But are not affected by flexibility until higher values, although they don't benefit from it either + if (flexibility > 4) + throwforce_mod -= (flexibility - 4) * 0.2 + + // Just for sanity in case something breaks + throwforce_mod = round(clamp(throwforce_mod, MATERIAL_MIN_FORCE_MULTIPLIER, MATERIAL_MAX_FORCE_MULTIPLIER), 0.01) + return throwforce_mod /** * Returns the atom(either itself or an internal module) that will interact/attack the target on behalf of us diff --git a/code/game/objects/items/AI_modules/_AI_modules.dm b/code/game/objects/items/AI_modules/_AI_modules.dm index be1d5a311cf..b89b9099f58 100644 --- a/code/game/objects/items/AI_modules/_AI_modules.dm +++ b/code/game/objects/items/AI_modules/_AI_modules.dm @@ -89,7 +89,7 @@ else to_chat(user, span_notice("Upload complete.")) - var/time = time2text(world.realtime,"hh:mm:ss", TIMEZONE_UTC) + var/time = round_timestamp() var/ainame = law_datum.owner ? law_datum.owner.name : "empty AI core" var/aikey = law_datum.owner ? law_datum.owner.ckey : "null" diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index d4a964246e0..949e4b7d8a1 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -824,7 +824,7 @@ /obj/item/card/id/click_alt(mob/living/user) if(!alt_click_can_use_id(user)) return NONE - if (registered_account.being_dumped) + if (LAZYLEN(registered_account.being_dumped)) registered_account.bank_card_talk(span_warning("内部服务器错误"), TRUE) return CLICK_ACTION_SUCCESS if(registered_account.account_debt) diff --git a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm index 6d0745a6a14..3c3fc8fb4b5 100644 --- a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm @@ -1702,6 +1702,7 @@ /obj/item/assembly/igniter/condenser = 1, /datum/stock_part/servo = 2, /datum/stock_part/matter_bin = 2, + /obj/item/reagent_containers/cup/beaker = 1, ) /obj/item/circuitboard/machine/smelter @@ -1712,6 +1713,7 @@ /obj/item/assembly/igniter = 1, /datum/stock_part/servo = 2, /datum/stock_part/matter_bin = 2, + /obj/item/reagent_containers/cup/beaker = 1, ) /obj/item/circuitboard/machine/shieldwallgen diff --git a/code/game/objects/items/clown_items.dm b/code/game/objects/items/clown_items.dm index 9b2537e205b..be4b16908c1 100644 --- a/code/game/objects/items/clown_items.dm +++ b/code/game/objects/items/clown_items.dm @@ -114,6 +114,10 @@ cleanspeed = 0.3 SECONDS //Only the truest of mind soul and body get one of these uses = 800 //In the Greek numeric system, Omega has a value of 800 +/obj/item/soap/omega/Initialize(mapload) + . = ..() + AddComponent(/datum/component/slippery, 120) //Same slipperiness as Super Lube + /obj/item/soap/omega/grind_results() return list( /datum/reagent/consumable/potato_juice = 9, @@ -125,7 +129,8 @@ /datum/reagent/consumable/ethanol/hooch = 9, /datum/reagent/bluespace = 9, /datum/reagent/drug/pumpup = 9, - /datum/reagent/consumable/space_cola = 9 + /datum/reagent/consumable/space_cola = 9, + /datum/reagent/iron = 9 ) /obj/item/soap/omega/suicide_act(mob/living/user) @@ -136,7 +141,7 @@ /obj/item/paper/fluff/stations/soap name = "ancient janitorial poem" desc = "An old paper that has passed many hands." - default_raw_text = "The legend of the omega soap

Essence of potato. Juice, not grind.

A lizard's tail, turned into wine.

powder of monkey, to help the workload.

Some Krokodil, because meth would explode.

Nitric acid and Baldium, for organic dissolving.

A cup filled with Hooch, for sinful absolving

Some Bluespace Dust, for removal of stains.

A syringe full of Pump-up, it's security's bane.

Add a can of Space Cola, because we've been paid.

Heat as hot as you can, let the soap be your blade.

Ten units of each reagent create a soap that could topple all others." + default_raw_text = "

The Legend of the Omega Soap



Essence of potato, juice, not grind.
A lizard's tail, turned into wine.
Powder of monkey, to help the workload.
Some Krokodil, because meth would explode.
Nitric acid and Baldium, for organic dissolving.
A cup full of hooch, for sins' absolving.
A dash of bluespace dust, for removal of stains.
A syringe of Pump-Up, Security's worst of pains.
A can of Space Cola, to watch the dirt fade.
Heat as hot as possible, let the soap be your blade.
With ten units of each, the soap that topples all will be made." /obj/item/soap/suicide_act(mob/living/user) user.say(";FFFFFFFFFFFFFFFFUUUUUUUDGE!!", forced="soap suicide") diff --git a/code/game/objects/items/crab17.dm b/code/game/objects/items/crab17.dm index 77407bd7946..fdb179ba55a 100644 --- a/code/game/objects/items/crab17.dm +++ b/code/game/objects/items/crab17.dm @@ -27,9 +27,9 @@ if(isliving(user)) L = user accounts_to_rob -= L.get_bank_account() + var/obj/effect/dumpeet_target/dump_machine = new /obj/effect/dumpeet_target(targetturf, L) for(var/datum/bank_account/B as anything in accounts_to_rob) - B.dumpeet() - new /obj/effect/dumpeet_target(targetturf, L) + B.dumpeet(dump_machine.dump) to_chat(user, span_notice("You have activated Protocol CRAB-17.")) user.log_message("activated Protocol CRAB-17.", LOG_GAME) @@ -67,7 +67,7 @@ */ /obj/structure/checkoutmachine/proc/check_if_finished() for(var/datum/bank_account/B as anything in accounts_to_rob) - if (B.being_dumped) + if(LAZYFIND(B.being_dumped, src)) return FALSE return TRUE @@ -94,13 +94,13 @@ balloon_alert(user, "card has no registered account!") return - if(!card.registered_account.being_dumped) + if(!LAZYFIND(card.registered_account.being_dumped, src)) balloon_alert(user, "funds are already safe!") return to_chat(user, span_warning("You quickly cash out your funds to a more secure banking location. Funds are safu.")) // This is a reference and not a typo accounts_to_rob -= card.registered_account - card.registered_account.stop_dump() + card.registered_account.stop_dump(src) if(check_if_finished()) qdel(src) @@ -112,6 +112,8 @@ return bogdanoff = user internal_account = new /datum/bank_account/remote("CRAB-17", 0, player_account = FALSE) + +/obj/structure/checkoutmachine/proc/setup_siphoning() add_overlay("flaps") add_overlay("hatch") add_overlay("legs_retracted") @@ -232,7 +234,7 @@ */ /obj/structure/checkoutmachine/proc/stop_dumping() for(var/datum/bank_account/B as anything in accounts_to_rob) - B.stop_dump() + B.stop_dump(src) /** * Splits the balance of the internal_account into several smaller piles of cash and scatters them around the area. @@ -274,6 +276,7 @@ /obj/effect/dumpeet_target/Initialize(mapload, user) . = ..() bogdanoff = user + dump = new /obj/structure/checkoutmachine(null, bogdanoff) addtimer(CALLBACK(src, PROC_REF(startLaunch)), 10 SECONDS) sound_to_playing_players('sound/items/dump_it.ogg', 20) deadchat_broadcast("Protocol CRAB-17 has been activated. A space-coin market has been launched at the station!", turf_target = get_turf(src), message_type=DEADCHAT_ANNOUNCEMENT) @@ -283,7 +286,7 @@ */ /obj/effect/dumpeet_target/proc/startLaunch() DF = new /obj/effect/dumpeet_fall(drop_location()) - dump = new /obj/structure/checkoutmachine(null, bogdanoff) + dump.setup_siphoning() priority_announce("The spacecoin bubble has popped! Get to the credit deposit machine at [get_area(src)] and cash out before you lose all of your funds!", sender_override = "CRAB-17 Protocol") animate(DF, pixel_z = -8, time = 5, , easing = LINEAR_EASING) playsound(src, 'sound/items/weapons/mortar_whistle.ogg', 70, TRUE, 6) diff --git a/code/game/objects/items/devices/aicard_evil.dm b/code/game/objects/items/devices/aicard_evil.dm index d5146c0a54a..307748172db 100644 --- a/code/game/objects/items/devices/aicard_evil.dm +++ b/code/game/objects/items/devices/aicard_evil.dm @@ -76,6 +76,7 @@ // create and apply syndie datum var/datum/antagonist/nukeop/nuke_datum = new() nuke_datum.send_to_spawnpoint = FALSE + nuke_datum.give_bonus_tc = FALSE new_ai.mind.add_antag_datum(nuke_datum, op_datum.nuke_team) LAZYADD(new_ai.mind.special_roles, "Syndicate AI") new_ai.add_faction(ROLE_SYNDICATE) diff --git a/code/game/objects/items/devices/broadcast_camera.dm b/code/game/objects/items/devices/broadcast_camera.dm index 5553470aab2..d97ffd5d59e 100644 --- a/code/game/objects/items/devices/broadcast_camera.dm +++ b/code/game/objects/items/devices/broadcast_camera.dm @@ -28,6 +28,8 @@ var/broadcast_name = "Curator News" /// The networks it broadcasts to, default is CAMERANET_NETWORK_CURATOR var/list/camera_networks = list(CAMERANET_NETWORK_CURATOR) + /// Range of the camera + var/camera_range = 7 /// The "virtual" security camera inside of the physical camera var/obj/machinery/camera/internal_camera /// The "virtual" radio inside of the the physical camera, a la microphone @@ -86,6 +88,7 @@ // INTERNAL CAMERA internal_camera = new(wielding_carbon) // Cameras for some reason do not work inside of obj's internal_camera.internal_light = FALSE + internal_camera.view_range = camera_range internal_camera.network = camera_networks internal_camera.c_tag = "LIVE: [broadcast_name]" start_broadcasting_network(camera_networks, "[broadcast_name] is now LIVE!") @@ -126,3 +129,16 @@ /obj/item/broadcast_camera/proc/set_microphone_state() internal_radio.set_broadcasting(active_microphone) + +// Orderable from cargo +/obj/item/broadcast_camera/cargo + slowdown = 0.3 + item_flags = parent_type::item_flags | SLOWS_WHILE_IN_HAND + broadcast_name = "Camera Broadcast" + camera_range = 5 + +/obj/item/broadcast_camera/cargo/Initialize(mapload) + . = ..() + // Gives each cargo camera a unique network id + var/static/cargo_camera_network_id = 0 + camera_networks = list("cargo_camera_id_[cargo_camera_network_id++]") diff --git a/code/game/objects/items/devices/earthcracker.dm b/code/game/objects/items/devices/earthcracker.dm new file mode 100644 index 00000000000..455be3168f2 --- /dev/null +++ b/code/game/objects/items/devices/earthcracker.dm @@ -0,0 +1,178 @@ +#define EARTHCRACKER_READY "ready" +#define EARTHCRACKER_ACTIVE "active" +#define EARTHCRACKER_SPENT "spent" + +/** + * The E-2 Earthcracker, a traitor device that creates intentional weakpoints on the station after use, which can be triggered via explosions. + * See weakpoint.dm for more specifics on their effects. + */ +/obj/item/earthcracker + name = "E-2 Earthcracker" + desc = "A nasty automated pilebunker can be used to create a massive weakpoint in flooring,\ + which can be triggered afterwards by a sufficiently strong enough explosion." + icon = 'icons/obj/devices/tool.dmi' + icon_state = "earthcracker" + base_icon_state = "earthcracker" + /// Is the earthcracker ready to arm, arming, activating, or spent? + var/status = EARTHCRACKER_READY + /// What kind of weakpoint shall you spawn? + var/obj/weakpoint_type = /obj/effect/weakpoint/big + /// The timer for the strike_the_earth activation + var/activation_timer + +/obj/item/earthcracker/Initialize(mapload) + . = ..() + if(!weakpoint_type) + CRASH("An earthcracker spawned without a designated weakpoint!") + register_context() + +/obj/item/earthcracker/attack_self(mob/user, modifiers) + . = ..() + if(status == EARTHCRACKER_READY) + handle_arming(user) + +/obj/item/earthcracker/attack_hand(mob/user, list/modifiers) + . = ..() + if(!anchored) + return NONE + switch(status) + if(EARTHCRACKER_ACTIVE) + if(activation_timer) + return FALSE + var/response = tgui_alert(user, "Activate the earthcracker?", "Activate?", list("Yes", "No")) == "Yes" + if(!response) + return FALSE + if(!user.Adjacent(src)) + return FALSE + flick("[base_icon_state]-active", src) + if(is_mining_level(z)) + activation_timer = addtimer(CALLBACK(src, PROC_REF(mining_act), user), 1.2 SECONDS) + return TRUE + activation_timer = addtimer(CALLBACK(src, PROC_REF(strike_the_earth)), 1.2 SECONDS) + return TRUE + if(EARTHCRACKER_SPENT) + balloon_alert(user, "used up!") + return FALSE + +/obj/item/earthcracker/update_icon_state() + . = ..() + switch(status) + if(EARTHCRACKER_READY) + icon_state = "[base_icon_state]" + if(EARTHCRACKER_ACTIVE) + icon_state = "[base_icon_state]-armed" + if(EARTHCRACKER_SPENT) + icon_state = "[base_icon_state]-spent" + +/obj/item/earthcracker/wrench_act(mob/living/user, obj/item/tool) + if(anchored && status == EARTHCRACKER_SPENT) + balloon_alert(user, "it falls apart") + animate(src, 0.6 SECONDS, alpha = 0, easing = CIRCULAR_EASING|EASE_IN) + addtimer(CALLBACK(src, PROC_REF(post_break)), 0.6 SECONDS) + return ITEM_INTERACT_SUCCESS + if(!anchored && status == EARTHCRACKER_READY) + balloon_alert(user, "arm in hands first!") + return ITEM_INTERACT_SUCCESS + if(anchored && status == EARTHCRACKER_ACTIVE) + balloon_alert(user, "unfastening from the floor...") + if(!tool.use_tool(src, user, 8 SECONDS, volume = 50)) + return ITEM_INTERACT_FAILURE + anchored = FALSE + status = EARTHCRACKER_READY + update_appearance(UPDATE_ICON) + return NONE + +/obj/item/earthcracker/add_context(atom/source, list/context, obj/item/held_item, mob/user) + switch(status) + if(EARTHCRACKER_ACTIVE) + context[SCREENTIP_CONTEXT_LMB] = "Activate device" + if(EARTHCRACKER_SPENT) + if(held_item?.tool_behaviour == TOOL_WRENCH) + context[SCREENTIP_CONTEXT_LMB] = "Disassemble device" + return CONTEXTUAL_SCREENTIP_SET + +/obj/item/earthcracker/examine(mob/user) + . = ..() + if(status == EARTHCRACKER_SPENT) + . += span_warning("This device is toast. You could disassemble the remains using a [EXAMINE_HINT("Wrench")].") + else + . += span_info("This device can be unanchored using a [EXAMINE_HINT("Wrench")].") + +/obj/item/earthcracker/proc/handle_arming(mob/user) + var/turf/arm_location = get_turf(user) + if(!arm_location) + return FALSE + if(isgroundlessturf(arm_location)) + balloon_alert(user, "can't deploy here") + return FALSE + + if(status == EARTHCRACKER_SPENT) + balloon_alert(user, "used up!") + return FALSE + balloon_alert(user, "arming...") + if(!do_after(user, 3 SECONDS, src)) + balloon_alert(user, "failed to arm") + return FALSE + + forceMove(arm_location) + anchored = TRUE + flick("[base_icon_state]-arm", src) + playsound(src, 'sound/items/barcodebeep.ogg', 50, FALSE) + status = EARTHCRACKER_ACTIVE + update_appearance(UPDATE_ICON) + return TRUE + +/// The fun part. We spawn a huge weakpoint here. +/obj/item/earthcracker/proc/strike_the_earth() + if(QDELETED(src)) + return + playsound(src, 'sound/items/weapons/earthcracker_bang.mp3', 75, FALSE, 3) + var/turf/cracked_hull = drop_location() + new weakpoint_type(cracked_hull) + handle_after_activation(cracked_hull) + +/// Cleanup after an earthcracker is activated either for sabotage or mining. +/obj/item/earthcracker/proc/handle_after_activation(turf/cracked_hull) + do_sparks(2, FALSE, src) + cracked_hull.levelupdate() + + status = EARTHCRACKER_SPENT + update_appearance(UPDATE_ICON) + particles = new /particles/smoke/burning/small + activation_timer = null + +/// Called after the earthcracker activates. +/obj/item/earthcracker/proc/post_break() + deconstruct(TRUE) + +/// When this item is used on a mining Z, we perform an action that breaks all rocks in a radius around us, the same as starting an ore vent wave. +/obj/item/earthcracker/proc/mining_act(mob/user) + for(var/i in 1 to 5) + for(var/turf/rock in oview(i)) // This collects a list of rings of turfs (in a growing radius of i) that we'll applying logic to "drill" below. + + if(istype(rock, /turf/closed/mineral)) + if(prob(50 + (i * 8))) + continue + var/turf/closed/mineral/drillable = rock + drillable.gets_drilled(user) + if(prob(50)) + new /obj/effect/decal/cleanable/rubble(rock) + continue + + if(istype(rock, /turf/open/misc/asteroid) && prob(35)) + new /obj/effect/decal/cleanable/rubble(rock) + continue + sleep(0.6 SECONDS) + handle_after_activation() + +/// Small subtype for shenanigans. +/obj/item/earthcracker/small + name = "E-1 Earthcracker" + desc = "A rusty automated pilebunker can be used to create a weakpoint in flooring,\ + which can be triggered afterwards by a sufficiently strong enough explosion.\ + You're pretty sure the mining company that used to make these got bought by Nanotrasen ages ago." + weakpoint_type = /obj/effect/weakpoint + +#undef EARTHCRACKER_READY +#undef EARTHCRACKER_ACTIVE +#undef EARTHCRACKER_SPENT diff --git a/code/game/objects/items/devices/scanners/autopsy_scanner.dm b/code/game/objects/items/devices/scanners/autopsy_scanner.dm index c541e513a0d..5e0376879e7 100644 --- a/code/game/objects/items/devices/scanners/autopsy_scanner.dm +++ b/code/game/objects/items/devices/scanners/autopsy_scanner.dm @@ -54,8 +54,9 @@ var/obj/item/paper/autopsy_report = new(get_turf(src)) autopsy_report.color = "#99ccff" - autopsy_report.name = "autopsy report of [scanned] - [station_time_timestamp()])" - var/final_report_text = "
Autopsy report. Time of Autopsy: [station_time_timestamp()]
" + autopsy_report.name = "autopsy report of [scanned] - [server_timestamp(format = "hh:mm", ic_time = TRUE)]" + var/final_report_text = "
Autopsy report
\ + Time of Autopsy: [UNDERLINED_HTML_TEXT("[server_timestamp(format = "hh:mm", ic_time = TRUE)]", "Shift Time: [round_timestamp(format = "hh:mm")]")]
" //A lot of this is extremely similar to /proc/healthscan() - but with different formatting, no color, and some added/removed info //Does not list quirks/exhaustion/how to repair wounds @@ -240,7 +241,7 @@ autopsy_information += "Coroner's Notes:" //Bottom of the page, anything past here is player-written final_report_text += jointext(autopsy_information, "") - autopsy_report.add_raw_text(final_report_text) + autopsy_report.add_raw_text(final_report_text, advanced_html = TRUE) autopsy_report.update_appearance() user.put_in_hands(autopsy_report) user.balloon_alert(user, "report printed") diff --git a/code/game/objects/items/devices/scanners/health_analyzer.dm b/code/game/objects/items/devices/scanners/health_analyzer.dm index 3578ae15beb..92de16308e1 100644 --- a/code/game/objects/items/devices/scanners/health_analyzer.dm +++ b/code/game/objects/items/devices/scanners/health_analyzer.dm @@ -80,7 +80,7 @@ span_notice("You stupidly try to analyze [scan_turf]'s vitals!"), ) - var/floor_text = "Analyzing results for [scan_turf] ([station_time_timestamp()]):
" + var/floor_text = "Analyzing results for [scan_turf] ([round_timestamp()]):
" floor_text += "Overall status: Unknown
" floor_text += "Subject lacks a brain.
" floor_text += "Body temperature: [scan_turf?.return_air()?.return_temperature() || "???"]
" @@ -168,7 +168,7 @@ oxy_loss += 200 - (oxy_loss + tox_loss + fire_loss + brute_loss) oxy_loss = clamp(oxy_loss, 0, 200) - render_list += "[span_info("Analyzing results for [target] ([station_time_timestamp()]):")]
Overall status: [mob_status]
" + render_list += "[span_info("Analyzing results for [target] ([round_timestamp()]):")]
Overall status: [mob_status]
" if(!advanced && target.has_reagent(/datum/reagent/inverse/technetium)) advanced = TRUE @@ -473,11 +473,12 @@ var/obj/item/paper/medical_report/report_paper = new(get_turf(src)) report_paper.color = "#99ccff" - report_paper.name = "health scan report - [station_time_timestamp()]" - var/report_text = "
Health scan report. Time of retrieval: [station_time_timestamp()]

" + report_paper.name = "health scan report - [server_timestamp(format = "hh:mm", ic_time = TRUE)]" + var/report_text = "
Health scan report
\ + Time of retrieval: [UNDERLINED_HTML_TEXT("[server_timestamp(format = "hh:mm", ic_time = TRUE)]", "Shift Time: [round_timestamp(format = "hh:mm")]")]

" report_text += last_scan_text - report_paper.add_raw_text(report_text) + report_paper.add_raw_text(report_text, advanced_html = TRUE) report_paper.update_appearance() user.put_in_hands(report_paper) diff --git a/code/game/objects/items/devices/table_clock.dm b/code/game/objects/items/devices/table_clock.dm index 0d819536366..c4420a81383 100644 --- a/code/game/objects/items/devices/table_clock.dm +++ b/code/game/objects/items/devices/table_clock.dm @@ -31,8 +31,9 @@ if(broken) . += span_info("It appears to be currently broken. You can use it in-hand to repair it.") else - . += span_info("The current CST (local) time is: [station_time_timestamp()].") - . += span_info("The current TCT (galactic) time is: [time2text(world.realtime, "hh:mm:ss", NO_TIMEZONE)].") + . += span_info("The current NST (local) time is: [server_timestamp(ic_time = TRUE, twelve_hour_clock = user.client?.prefs.read_preference(/datum/preference/toggle/twelve_hour))].") + if(user.is_literate()) + . += span_info("That means it is currently [round_timestamp()] into the shift.") /obj/item/table_clock/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers) . = ..() diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index 0b5574de31c..c1e7f296846 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -33,6 +33,20 @@ attached_device = null return ..() +/obj/item/transfer_valve/examine(mob/user) + . = ..() + if(tank_one) + . += span_notice("A [tank_one] is attached to the primary port.") + if(tank_two) + . += span_notice("A [tank_two] is attached to the secondary port.") + if(!tank_one || !tank_two) + . += span_notice("You could attach a gas tank onto the open port.") + if(attached_device) + . += span_notice("A [attached_device] is attached to the fuse input.") + if(wired) + . += span_notice("It looks like some nutjob added makeshift backpack straps with [EXAMINE_HINT("wires")]...") + . += span_notice("You could cut off the straps with [EXAMINE_HINT(TOOL_WIRECUTTER)].") + /obj/item/transfer_valve/add_context(atom/source, list/context, obj/item/held_item, mob/user) . = ..() @@ -79,58 +93,37 @@ /obj/item/transfer_valve/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) . = ..() - if (!istype(interacting_with, /obj/vehicle/ridden/wheelchair)) - return NONE - var/obj/vehicle/ridden/wheelchair/chair = interacting_with + if(istype(interacting_with, /obj/vehicle/ridden/wheelchair)) + var/obj/vehicle/ridden/wheelchair/chair = interacting_with - if (chair.bomb_attached) - user.balloon_alert(user, "already has a TTV!") - return ITEM_INTERACT_FAILURE - user.balloon_alert(user, "attaching TTV...") - if (!do_after(user, 0.5 SECONDS, chair)) - return ITEM_INTERACT_FAILURE + if (chair.bomb_attached) + user.balloon_alert(user, "already has a TTV!") + return ITEM_INTERACT_FAILURE + user.balloon_alert(user, "attaching TTV...") + if (!do_after(user, 0.5 SECONDS, chair)) + return ITEM_INTERACT_FAILURE - chair.attach_bomb(src) - user.log_message("attached [src] to [chair]", LOG_GAME) - return ITEM_INTERACT_SUCCESS + chair.attach_bomb(src) + user.log_message("attached [src] to [chair]", LOG_GAME) + return ITEM_INTERACT_SUCCESS + else if(istype(interacting_with, /obj/item/tank)) + if(try_attach_tank(interacting_with)) + return ITEM_INTERACT_SUCCESS + else + return ITEM_INTERACT_FAILURE + else if(isassembly(interacting_with)) + if(try_attach_assembly(interacting_with)) + return ITEM_INTERACT_SUCCESS + else + return ITEM_INTERACT_FAILURE + return NONE /obj/item/transfer_valve/attackby(obj/item/item, mob/user, params) if(istype(item, /obj/item/tank)) - if(tank_one && tank_two) - to_chat(user, span_warning("There are already two tanks attached, remove one first!")) - return - - if(!tank_one) - if(!user.transferItemToLoc(item, src)) - return - tank_one = item - to_chat(user, span_notice("You attach the tank to the transfer valve.")) - else if(!tank_two) - if(!user.transferItemToLoc(item, src)) - return - tank_two = item - to_chat(user, span_notice("You attach the tank to the transfer valve.")) - - update_appearance() + try_attach_tank(item, user) //TODO: Have this take an assemblyholder else if(isassembly(item)) - var/obj/item/assembly/A = item - if(A.secured) - to_chat(user, span_notice("The device is secured.")) - return - if(attached_device) - to_chat(user, span_warning("There is already a device attached to the valve, remove it first!")) - return - if(!user.transferItemToLoc(item, src)) - return - attached_device = A - to_chat(user, span_notice("You attach the [item] to the valve controls and secure it.")) - A.holder = src - A.on_attach() - A.toggle_secure() //this calls update_icon(), which calls update_icon() on the holder (i.e. the bomb). - log_bomber(user, "attached a [item.name] to a ttv -", src, null, FALSE) - attacher = user - + try_attach_assembly(item, user) else if(istype(item, /obj/item/stack/cable_coil) && !wired) var/obj/item/stack/cable_coil/coil = item if (coil.get_amount() < 15) @@ -153,6 +146,42 @@ return +/obj/item/transfer_valve/proc/try_attach_tank(obj/item/tank/new_tank, mob/user) + if(!tank_one) + if(!user.transferItemToLoc(new_tank, src)) + return FALSE + tank_one = new_tank + to_chat(user, span_notice("You attach the [new_tank] to the transfer valve's primary port.")) + else if(!tank_two) + if(!user.transferItemToLoc(new_tank, src)) + return FALSE + tank_two = new_tank + to_chat(user, span_notice("You attach the [new_tank] to the transfer valve's secondary port.")) + else + to_chat(user, span_warning("There are already two tanks attached, remove one first!")) + return FALSE + + update_appearance() + return TRUE + +/obj/item/transfer_valve/proc/try_attach_assembly(obj/item/assembly/A, mob/user) + if(A.secured) + to_chat(user, span_notice("The [A] is secured; unsecure it first.")) + return FALSE + if(attached_device) + to_chat(user, span_warning("There is already a device attached to the valve, remove it first!")) + return FALSE + if(!user.transferItemToLoc(A, src)) + return FALSE + attached_device = A + to_chat(user, span_notice("You attach the [A] to the valve controls and secure it.")) + A.holder = src + A.on_attach() + A.toggle_secure() //this calls update_icon(), which calls update_icon() on the holder (i.e. the bomb). + log_bomber(user, "attached a [A.name] to a ttv -", src, null, FALSE) + attacher = user + return TRUE + //These keep attached devices synced up, for example a TTV with a mouse trap being found in a bag so it's triggered, or moving the TTV with an infrared beam sensor to update the beam's direction. /obj/item/transfer_valve/Move() . = ..() diff --git a/code/game/objects/items/dna_injector.dm b/code/game/objects/items/dna_injector.dm index baf4bb85e62..178f67c0b00 100644 --- a/code/game/objects/items/dna_injector.dm +++ b/code/game/objects/items/dna_injector.dm @@ -11,18 +11,34 @@ throw_range = 5 w_class = WEIGHT_CLASS_TINY + /// Modified to damage caused from injection, currently unused though var/damage_coeff = 1 - var/list/fields - var/list/add_mutations = list() - var/list/remove_mutations = list() + /// Adds all mutations in this list to the injected mob, activating it rather than mutating it if possible. + var/list/add_mutations + /// If the injected mob has any mutations in this list activated or mutated, they will be removed. + var/list/remove_mutations + /// Tracks if it's been used + VAR_FINAL/used = FALSE + /// Duration of the mutations added/activated or DNA changes. Does not affect removed mutations. + var/duration = INFINITY + /// A DNA datum that has its fields copied to the target on injection. + var/datum/dna/stored_dna - var/used = FALSE - -/obj/item/dnainjector/Initialize(mapload) +/obj/item/dnainjector/Initialize(mapload, datum/dna/stored_dna, damage_coeff = 1) . = ..() AddElement(/datum/element/update_icon_updates_onmob) if(used) update_appearance() + src.stored_dna = stored_dna + src.damage_coeff = damage_coeff + +/obj/item/dnainjector/Destroy() + if(stored_dna?.holder) + stack_trace("DNA injector got owned DNA somehow") + stored_dna = null + else + QDEL_NULL(stored_dna) + return ..() /obj/item/dnainjector/vv_edit_var(vname, vval) . = ..() @@ -43,27 +59,26 @@ /obj/item/dnainjector/proc/inject(mob/living/carbon/target, mob/user) if(!target.can_mutate()) return FALSE + if(target.stat == DEAD) //prevents dead people from having their DNA changed + to_chat(user, span_notice("You can't modify [target]'s DNA while [target.p_theyre()] dead.")) + return FALSE for(var/removed_mutation in remove_mutations) - target.dna.remove_mutation(removed_mutation, list(MUTATION_SOURCE_ACTIVATED, MUTATION_SOURCE_MUTATOR)) - for(var/added_mutation in add_mutations) - if(added_mutation == /datum/mutation/race) - message_admins("[ADMIN_LOOKUPFLW(user)] injected [key_name_admin(target)] with \the [src] [span_danger("(MONKEY)")]") + target.dna.remove_mutation(removed_mutation, GLOB.standard_mutation_sources) + + for(var/datum/mutation/added_mutation as anything in add_mutations) + if(added_mutation::warn_admins_on_inject && target != user && !ismonkey(target)) + message_admins("[ADMIN_LOOKUPFLW(user)] injected [key_name_admin(target)] with [src] containing [added_mutation::name].") if(target.dna.mutation_in_sequence(added_mutation)) target.dna.activate_mutation(added_mutation) + if(duration != INFINITY) + addtimer(CALLBACK(target.dna, TYPE_PROC_REF(/datum/dna, remove_mutation), added_mutation, MUTATION_SOURCE_ACTIVATED), duration) else target.dna.add_mutation(added_mutation, MUTATION_SOURCE_MUTATOR) - if(fields) - if(fields["name"] && fields["UE"] && fields["blood_type"]) - target.real_name = fields["name"] - target.dna.unique_enzymes = fields["UE"] - target.name = target.real_name - target.set_blood_type(fields["blood_type"]) - if(fields["UI"]) //UI+UE - target.dna.unique_identity = merge_text(target.dna.unique_identity, fields["UI"]) - if(fields["UF"]) - target.dna.unique_features = merge_text(target.dna.unique_features, fields["UF"]) - if(fields["UI"] || fields["UF"]) - target.updateappearance(mutcolor_update = TRUE, mutations_overlay_update = TRUE) + if(duration != INFINITY) + addtimer(CALLBACK(target.dna, TYPE_PROC_REF(/datum/dna, remove_mutation), added_mutation, MUTATION_SOURCE_MUTATOR), duration) + + if(stored_dna) + target.apply_status_effect(/datum/status_effect/temporary_transformation/dna_injector, duration, stored_dna) return TRUE /obj/item/dnainjector/attack(mob/target, mob/user) @@ -100,53 +115,7 @@ update_appearance() /obj/item/dnainjector/timed - var/duration = 60 SECONDS - -/obj/item/dnainjector/timed/inject(mob/living/carbon/target, mob/user) - if(target.stat == DEAD) //prevents dead people from having their DNA changed - to_chat(user, span_notice("You can't modify [target]'s DNA while [target.p_theyre()] dead.")) - return FALSE - if(!target.can_mutate()) - return FALSE - var/endtime = world.time + duration - for(var/mutation in remove_mutations) - target.dna.remove_mutation(mutation, list(MUTATION_SOURCE_ACTIVATED, MUTATION_SOURCE_MUTATOR)) - for(var/mutation in add_mutations) - if(target.dna.get_mutation(mutation)) - continue //Skip permanent mutations we already have. - if(mutation == /datum/mutation/race && !ismonkey(target)) - message_admins("[ADMIN_LOOKUPFLW(user)] injected [key_name_admin(target)] with \the [src] [span_danger("(MONKEY)")]") - target.dna.add_mutation(mutation, MUTATION_SOURCE_TIMED_INJECTOR) - addtimer(CALLBACK(target.dna, TYPE_PROC_REF(/datum/dna, remove_mutation), mutation, MUTATION_SOURCE_TIMED_INJECTOR), duration) - if(fields) - if(fields["name"] && fields["UE"] && fields["blood_type"]) - LAZYINITLIST(target.dna.previous) - if(!target.dna.previous["name"]) - target.dna.previous["name"] = target.real_name - if(!target.dna.previous["UE"]) - target.dna.previous["UE"] = target.dna.unique_enzymes - if(!target.dna.previous["blood_type"]) - target.dna.previous["blood_type"] = target.get_bloodtype() - target.real_name = fields["name"] - target.dna.unique_enzymes = fields["UE"] - target.name = target.real_name - target.set_blood_type(fields["blood_type"]) - LAZYSET(target.dna.temporary_mutations, UE_CHANGED, endtime) - if(fields["UI"]) //UI+UE - LAZYINITLIST(target.dna.previous) - if(!target.dna.previous["UI"]) - target.dna.previous["UI"] = target.dna.unique_identity - target.dna.unique_identity = merge_text(target.dna.unique_identity, fields["UI"]) - LAZYSET(target.dna.temporary_mutations, UI_CHANGED, endtime) - if(fields["UF"]) //UI+UE - LAZYINITLIST(target.dna.previous) - if(!target.dna.previous["UF"]) - target.dna.previous["UF"] = target.dna.unique_features - target.dna.unique_features = merge_text(target.dna.unique_features, fields["UF"]) - LAZYSET(target.dna.temporary_mutations, UF_CHANGED, endtime) - if(fields["UI"] || fields["UF"]) - target.updateappearance(mutcolor_update = TRUE, mutations_overlay_update = TRUE) - return TRUE + duration = 60 SECONDS /obj/item/dnainjector/timed/hulk name = "\improper DNA injector (Hulk)" diff --git a/code/game/objects/items/emags.dm b/code/game/objects/items/emags.dm index 739ba154584..735c7c6a03a 100644 --- a/code/game/objects/items/emags.dm +++ b/code/game/objects/items/emags.dm @@ -86,6 +86,9 @@ color = rgb(40, 130, 255) prox_check = FALSE +/obj/item/card/emag/blue + color = rgb(40, 130, 255) + /obj/item/card/emag/halloween name = "hack-o'-lantern" desc = "It's a pumpkin with a cryptographic sequencer sticking out." diff --git a/code/game/objects/items/floppy_disk.dm b/code/game/objects/items/floppy_disk.dm index 83a5a6d2dca..3b7a75f1fa6 100644 --- a/code/game/objects/items/floppy_disk.dm +++ b/code/game/objects/items/floppy_disk.dm @@ -358,6 +358,20 @@ . = ..() new /obj/item/disk/data(src) +/obj/item/disk/manipulator + name = "manipulator task disk" + desc = "A floppy disk containing manipulator tasks." + var/list/tasks_data = list() + +/obj/item/disk/manipulator/proc/set_tasks(list/new_tasks_data) + if(read_only) + return FALSE + tasks_data = islist(new_tasks_data) ? new_tasks_data : list() + return TRUE + +/obj/item/disk/manipulator/proc/get_tasks() + return tasks_data?.Copy() || list() + #undef STARTING_STICKER #undef MAX_DISK_STACK_SIZE #undef STACK_PIXEL_STEP diff --git a/code/game/objects/items/food/dough.dm b/code/game/objects/items/food/dough.dm index 75fda88fc20..3266f9658c3 100644 --- a/code/game/objects/items/food/dough.dm +++ b/code/game/objects/items/food/dough.dm @@ -46,7 +46,7 @@ /obj/item/food/pizzabread/Initialize(mapload) . = ..() - AddComponent(/datum/component/ingredients_holder, /obj/item/food/pizza, CUSTOM_INGREDIENT_ICON_SCATTER, max_ingredients = 12) + AddComponent(/datum/component/ingredients_holder, /obj/item/food/pizza/custom, CUSTOM_INGREDIENT_ICON_SCATTER, max_ingredients = 12) /obj/item/food/doughslice name = "dough slice" diff --git a/code/game/objects/items/food/packaged.dm b/code/game/objects/items/food/packaged.dm index 95054ec4a1a..597ec3ce60d 100644 --- a/code/game/objects/items/food/packaged.dm +++ b/code/game/objects/items/food/packaged.dm @@ -117,6 +117,7 @@ if(!check_buffability(user)) return ..() apply_buff(user) + return TRUE /obj/item/food/canned/envirochow/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) if(!check_buffability(interacting_with)) diff --git a/code/game/objects/items/food/pizza.dm b/code/game/objects/items/food/pizza.dm index 061a255fd1b..b4e5bdf9406 100644 --- a/code/game/objects/items/food/pizza.dm +++ b/code/game/objects/items/food/pizza.dm @@ -106,6 +106,7 @@ slice.reagents.remove_all() reagents.trans_to(slice, amount = reagents.total_volume / slices_left, no_react = TRUE) + SEND_SIGNAL(src, COMSIG_PIZZA_SLICE_TAKEN, user, slice) slices_left-- if(slices_left <= 0) @@ -116,15 +117,6 @@ remove_filter("pizzaslices") add_filter("pizzaslices", 1, get_slices_filter()) -// Raw Pizza -/obj/item/food/pizza/raw - foodtypes = GRAIN | RAW - slice_type = null - crafting_complexity = FOOD_COMPLEXITY_2 - -/obj/item/food/pizza/raw/make_bakeable() - AddComponent(/datum/component/bakeable, /obj/item/food/pizza, rand(70 SECONDS, 80 SECONDS), TRUE, TRUE) - // Pizza Slice /obj/item/food/pizzaslice name = "bugged pizza slice" @@ -140,6 +132,17 @@ /obj/item/food/pizzaslice/make_processable() AddElement(/datum/element/processable, TOOL_ROLLINGPIN, /obj/item/stack/sheet/pizza, 1, 1 SECONDS, table_required = TRUE, screentip_verb = "Flatten", sound_to_play = SFX_ROLLING_PIN_ROLLING) +/obj/item/food/pizza/custom + name = "pizza" + desc = "A fancy custom pizza." + icon_state = "pizzamargherita" // Colored by the ingredient_holder component + slice_type = /obj/item/food/pizzaslice/custom + +/obj/item/food/pizzaslice/custom + name = "pizza slice" + desc = "A slice of custom fancy pizza." + icon_state = "pizzamargheritaslice" + /obj/item/food/pizza/margherita name = "pizza margherita" desc = "The most cheezy pizza in galaxy." diff --git a/code/game/objects/items/food/sweets.dm b/code/game/objects/items/food/sweets.dm index 4be75cf07fc..e429976657f 100644 --- a/code/game/objects/items/food/sweets.dm +++ b/code/game/objects/items/food/sweets.dm @@ -258,7 +258,7 @@ to_chat(victim, span_warning("[pick("You hear faint whispers.", "You smell ash.", "You feel hot.", "You hear a roar in the distance.")]")) /obj/item/food/bubblegum/bubblegum/suicide_act(mob/living/user) - user.say(";[pick(BUBBLEGUM_HALLUCINATION_LINES)]") + user.say(";[pick(BUBBLEGUM_HALLUCINATION_LINES)]", spans = list(SPAN_COLOSSUS)) return ..() /obj/item/food/gumball diff --git a/code/game/objects/items/grenades/_grenade.dm b/code/game/objects/items/grenades/_grenade.dm index 11e7f3683e2..0d715d8e6d9 100644 --- a/code/game/objects/items/grenades/_grenade.dm +++ b/code/game/objects/items/grenades/_grenade.dm @@ -145,7 +145,7 @@ /obj/item/grenade/proc/log_grenade(mob/user) if(!type_cluster) - log_bomber(user, "has primed a", src, "for detonation", message_admins = dud_flags != NONE) + log_bomber(user, "has primed a", src, "for detonation", message_admins = dud_flags == NONE) /** * arm_grenade (formerly preprime) refers to when a grenade with a standard time fuze is activated, making it go beepbeepbeep and then detonate a few seconds later. diff --git a/code/game/objects/items/grenades/ghettobomb.dm b/code/game/objects/items/grenades/ghettobomb.dm index 9afe5cd4aa6..5dbf5052168 100644 --- a/code/game/objects/items/grenades/ghettobomb.dm +++ b/code/game/objects/items/grenades/ghettobomb.dm @@ -198,6 +198,7 @@ /// Static list of reagent to explosive power var/static/list/fuel_power = list( /datum/reagent/fuel = 0.5, + /datum/reagent/toxin/plasma = 0.75, /datum/reagent/gunpowder = 1, /datum/reagent/nitroglycerin = 2, /datum/reagent/tatp = 2.5, diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm index e9b05a8c08c..89980733fa7 100644 --- a/code/game/objects/items/handcuffs.dm +++ b/code/game/objects/items/handcuffs.dm @@ -420,6 +420,8 @@ slowdown = 7 breakouttime = 30 SECONDS slot_flags = ITEM_SLOT_LEGCUFFED + /// Icon state for the legcuff overlay + var/legcuff_state = "legcuff" /** * # Bear trap diff --git a/code/game/objects/items/inspector.dm b/code/game/objects/items/inspector.dm index bc82fa85b94..4ca2320caa2 100644 --- a/code/game/objects/items/inspector.dm +++ b/code/game/objects/items/inspector.dm @@ -77,7 +77,6 @@ /obj/item/inspector/examine(mob/user) . = ..() - . += span_info("Use in-hand to scan the local area, creating an encrypted security inspection.") . += span_info("Use on an item to scan if it contains, or is, contraband.") if(!cell_cover_open) . += span_notice("Its cell cover is closed. It looks like it could be pried out, but doing so would require an appropriate tool.") diff --git a/code/game/objects/items/robot/items/tools.dm b/code/game/objects/items/robot/items/tools.dm index ce010ca50ec..dbf44a19b86 100644 --- a/code/game/objects/items/robot/items/tools.dm +++ b/code/game/objects/items/robot/items/tools.dm @@ -191,13 +191,20 @@ return ..() /obj/item/borg/cyborg_omnitool/add_context(atom/source, list/context, obj/item/held_item, mob/user) - . = ..() + . = NONE if (!issilicon(user)) return + var/mob/living/silicon/robot/as_cyborg = user if (!(src in as_cyborg.held_items)) context[SCREENTIP_CONTEXT_RMB] = "Select Tool" - return CONTEXTUAL_SCREENTIP_SET + return CONTEXTUAL_SCREENTIP_SET + +/obj/item/borg/cyborg_omnitool/examine(mob/user) + . = ..() + if(reference) + var/obj/item/tool = get_proxy_attacker_for(src, usr) + . += tool.examine(user) /** * Sets the new internal tool to be used @@ -206,8 +213,6 @@ * * obj/item/ref - typepath for the new internal omnitool */ /obj/item/borg/cyborg_omnitool/proc/set_internal_tool(obj/item/tool) - SHOULD_NOT_OVERRIDE(TRUE) - for(var/obj/item/internal_tool as anything in omni_toolkit) if(internal_tool == tool) reference = internal_tool @@ -241,11 +246,14 @@ //if all else fails just make a new one from scratch tool = new reference(user) + //assign the upgraded toolspeed, if engi omnitool upgrade was applied. + tool.toolspeed = initial(tool.toolspeed) - upgraded * 0.3 //the internal tool is considered part of the tool itself, so don't let it be dropped. tool.item_flags |= ABSTRACT ADD_TRAIT(tool, TRAIT_NODROP, INNATE_TRAIT) + //store tool for future use atoms[reference] = tool - tool.toolspeed = initial(tool.toolspeed) - upgraded * 0.3 //and finally assign the upgraded toolspeed, if any. + return tool /obj/item/borg/cyborg_omnitool/attack_self(mob/user) @@ -274,7 +282,8 @@ var/mob/living/silicon/robot/user = usr if (!(src in user.held_items)) attack_self(user) - return ..() + . = ..() + user.select_module(user.held_items.Find(src)) /obj/item/borg/cyborg_omnitool/update_icon_state() if (reference) @@ -322,15 +331,77 @@ /obj/item/screwdriver/cyborg, /obj/item/crowbar/cyborg, /obj/item/multitool/cyborg, + /obj/item/weldingtool/largetank/cyborg, ) +/obj/item/borg/cyborg_omnitool/engineering/Initialize(mapload) + . = ..() + RegisterSignal(src, COMSIG_SILICON_MODULE_ACTIVATION, PROC_REF(welder_toggle)) + +/obj/item/borg/cyborg_omnitool/engineering/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = ..() + if (!issilicon(user) || tool_behaviour != TOOL_WELDER) + return + + context[SCREENTIP_CONTEXT_CTRL_LMB] = "Toggle welder" + return CONTEXTUAL_SCREENTIP_SET + /obj/item/borg/cyborg_omnitool/engineering/examine(mob/user) . = ..() + if(tool_behaviour == TOOL_WELDER) + . += span_notice("Use [EXAMINE_HINT("Ctrl Click")] to toggle welder") - if(tool_behaviour == TOOL_MULTITOOL) - for(var/obj/item/multitool/tool in atoms) - . += "Its multitool buffer contains [tool.buffer]" - break +/obj/item/borg/cyborg_omnitool/engineering/update_overlays() + . = ..() + if(tool_behaviour == TOOL_WELDER) + var/obj/item/weldingtool/tool = atoms[/obj/item/weldingtool/largetank/cyborg] + if(tool?.welding) + . |= tool.update_overlays() + +/obj/item/borg/cyborg_omnitool/engineering/set_internal_tool(obj/item/tool) + if(tool_behaviour == TOOL_WELDER) + welder_toggle(src, FALSE) + + . = ..() + + if(tool_behaviour == TOOL_WELDER) + welder_toggle(src, TRUE) + +/obj/item/borg/cyborg_omnitool/engineering/item_ctrl_click(mob/user) + . = NONE + if(tool_behaviour == TOOL_WELDER) + var/mob/living/silicon/robot/borgy = loc + if(!istype(borgy) || borgy.module_active != src) + return + + welder_toggle(src, null) + return CLICK_ACTION_SUCCESS + +///Reflects internal welder icon onto the omnitool +/obj/item/borg/cyborg_omnitool/engineering/proc/welder_update(source) + PRIVATE_PROC(TRUE) + SIGNAL_HANDLER + + update_appearance(UPDATE_OVERLAYS) + +///Toggles welder on/off when module slot is selected/deselected +/obj/item/borg/cyborg_omnitool/engineering/proc/welder_toggle(datum/omnitool, state) + PRIVATE_PROC(TRUE) + SIGNAL_HANDLER + + if(tool_behaviour == TOOL_WELDER) + var/obj/item/weldingtool/tool = get_proxy_attacker_for(src, usr) + if(isnull(state)) + state = !tool.welding + if(state == tool.welding) + return + + if(state) + RegisterSignal(tool, COMSIG_ATOM_UPDATE_APPEARANCE, PROC_REF(welder_update)) + tool.switched_on(usr) + else + tool.switched_off() + UnregisterSignal(tool, COMSIG_ATOM_UPDATE_APPEARANCE) /obj/item/borg/cyborg_omnitool/botany name = "botanical omni-toolset" diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index fe81a77a273..c69dcb31b10 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -459,10 +459,6 @@ if(!.) return . ADD_TRAIT(cyborg, TRAIT_FASTMED, REF(src)) - for(var/obj/item/borg/cyborg_omnitool/medical/omnitool_upgrade in cyborg.model.modules) - if(omnitool_upgrade.upgraded) - to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!")) - return FALSE for(var/obj/item/borg/cyborg_omnitool/medical/omnitool in cyborg.model.modules) omnitool.set_upgraded(TRUE) @@ -471,7 +467,7 @@ if(!.) return . REMOVE_TRAIT(cyborg, TRAIT_FASTMED, REF(src)) - for(var/obj/item/borg/cyborg_omnitool/omnitool in cyborg.model.modules) + for(var/obj/item/borg/cyborg_omnitool/medical/omnitool in cyborg.model.modules) omnitool.set_upgraded(FALSE) /obj/item/borg/upgrade/engineering_omnitool @@ -486,24 +482,16 @@ /obj/item/borg/upgrade/engineering_omnitool/action(mob/living/silicon/robot/cyborg, mob/living/user = usr) . = ..() if(!.) - return . - for(var/obj/item/borg/cyborg_omnitool/engineering/omnitool_upgrade in cyborg.model.modules) - if(omnitool_upgrade.upgraded) - to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!")) - return FALSE + return for(var/obj/item/borg/cyborg_omnitool/engineering/omnitool in cyborg.model.modules) omnitool.set_upgraded(TRUE) - for(var/obj/item/weldingtool/largetank/cyborg/welder in cyborg.model.modules) - welder.toolspeed = initial(welder.toolspeed) - 0.3 /obj/item/borg/upgrade/engineering_omnitool/deactivate(mob/living/silicon/robot/cyborg, mob/living/user = usr) . = ..() if(!.) - return . - for(var/obj/item/borg/cyborg_omnitool/omnitool in cyborg.model.modules) + return + for(var/obj/item/borg/cyborg_omnitool/engineering/omnitool in cyborg.model.modules) omnitool.set_upgraded(FALSE) - for(var/obj/item/weldingtool/largetank/cyborg/welder in cyborg.model.modules) - welder.toolspeed = initial(welder.toolspeed) /obj/item/borg/upgrade/defib name = "medical cyborg defibrillator" diff --git a/code/game/objects/items/sharpener.dm b/code/game/objects/items/sharpener.dm index daf1bf0ba96..f01ca917f8c 100644 --- a/code/game/objects/items/sharpener.dm +++ b/code/game/objects/items/sharpener.dm @@ -53,7 +53,8 @@ I.wound_bonus = I.wound_bonus + increment //wound_bonus has no cap user.visible_message(span_notice("[user] sharpens [I] with [src]!"), span_notice("You sharpen [I], making it much more deadly than before.")) playsound(src, 'sound/items/unsheath.ogg', 25, TRUE) - I.sharpness = SHARP_EDGED //When you whetstone something, it becomes an edged weapon, even if it was previously dull or pointy + if(!(signal_out & COMPONENT_BLOCK_SHARPEN_SHARPNESS)) + I.sharpness = SHARP_EDGED //When you whetstone something, it becomes an edged weapon, even if it was previously dull or pointy I.throwforce = clamp(I.throwforce + increment, 0, max) I.name = "[prefix] [I.name]" //This adds a prefix and a space to the item's name regardless of what the prefix is desc = "[desc] At least, it used to." diff --git a/code/game/objects/items/stacks/bscrystal.dm b/code/game/objects/items/stacks/bscrystal.dm index 762e9ce4032..c893888eaf3 100644 --- a/code/game/objects/items/stacks/bscrystal.dm +++ b/code/game/objects/items/stacks/bscrystal.dm @@ -13,6 +13,10 @@ refined_type = /obj/item/stack/sheet/bluespace_crystal scan_state = "rock_bscrystal" merge_type = /obj/item/stack/ore/bluespace_crystal + vein_type = ORE_VEIN_SCATTER + vein_distance = 5 + min_vein_size = 1 + max_vein_size = 2 /// The teleport range when crushed/thrown at someone. var/blink_range = 8 diff --git a/code/game/objects/items/stacks/sheets/runed_metal.dm b/code/game/objects/items/stacks/sheets/runed_metal.dm index 674dea391c1..e68a1356d0f 100644 --- a/code/game/objects/items/stacks/sheets/runed_metal.dm +++ b/code/game/objects/items/stacks/sheets/runed_metal.dm @@ -39,8 +39,7 @@ GLOBAL_LIST_INIT(runed_metal_recipes, list( \ req_amount = 3, \ time = 4 SECONDS, \ crafting_flags = CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, \ - desc = span_cult_bold("Daemon Forge: Can make Nar'Sien Hardened Armor, Flagellant's Robes, \ - and Eldritch Longswords. Emits Light."), \ + desc = span_cult_bold("Daemon Forge: Can make Nar'Sien Hardened Armor and Eldritch Longswords. Emits Light."), \ required_noun = "runed metal sheet", \ category = CAT_CULT, \ ), \ diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 43e07364716..d62cca101c2 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -478,8 +478,12 @@ if(isstack(created)) var/obj/item/stack/crafted_stack = created + if(recipe.res_amount > 0 && recipe.req_amount != recipe.res_amount) + var/scale = recipe.req_amount / recipe.res_amount + for(var/mat in result_mats) + result_mats[mat] *= scale crafted_stack.mats_per_unit = SSmaterials.get_material_set_cache(result_mats) - update_custom_materials() + crafted_stack.update_custom_materials() else created.set_custom_materials(result_mats, recipe.req_amount * multiplier) diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index a203d3ad0c0..5f5e9616992 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -60,7 +60,7 @@ icon_state = "bag_of_holding" inhand_icon_state = "holdingpack" resistance_flags = FIRE_PROOF - item_flags = NO_MAT_REDEMPTION + item_flags = NO_MAT_REDEMPTION | BLUESPACE_INTERFERENCE armor_type = /datum/armor/backpack_holding storage_type = /datum/storage/bag_of_holding pickup_sound = null diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index 7a915b2e471..c2bc54dc71a 100644 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -466,7 +466,8 @@ worn_icon_state = "soulstonebelt" storage_type = /datum/storage/wands_belt -/obj/item/storage/belt/wands/full/PopulateContents() +/// Put some wands in that bad boy +/obj/item/storage/belt/wands/full/proc/create_wands() new /obj/item/gun/magic/wand/death(src) new /obj/item/gun/magic/wand/resurrection(src) new /obj/item/gun/magic/wand/fireball(src) //SKYRAT EDIT - Trades polymorph for second fireball @@ -475,10 +476,96 @@ new /obj/item/gun/magic/wand/fireball(src) new /obj/item/gun/magic/wand/shrink(src) +/obj/item/storage/belt/wands/full/PopulateContents() + create_wands() for(var/obj/item/gun/magic/wand/W in contents) //All wands in this pack come in the best possible condition W.max_charges = initial(W.max_charges) W.charges = W.max_charges +/// Filled with budget wands instead of cool ones +/obj/item/storage/belt/wands/full/discount + /// Which wands can appear? + var/static/list/possible_options = list( + /obj/item/gun/magic/wand/animate, + /obj/item/gun/magic/wand/babel, + /obj/item/gun/magic/wand/bald, + /obj/item/gun/magic/wand/door, + /obj/item/gun/magic/wand/fireball, + /obj/item/gun/magic/wand/freeze, + /obj/item/gun/magic/wand/hallucination, + /obj/item/gun/magic/wand/levitate, + /obj/item/gun/magic/wand/pax, + /obj/item/gun/magic/wand/pizza, + /obj/item/gun/magic/wand/plague, + /obj/item/gun/magic/wand/prank, + /obj/item/gun/magic/wand/rebel, + /obj/item/gun/magic/wand/repulse, + /obj/item/gun/magic/wand/swap, + /obj/item/gun/magic/wand/teleport, + /obj/item/gun/magic/wand/tentacles, + /obj/item/gun/magic/wand/zap, + ) + +/obj/item/storage/belt/wands/full/discount/create_wands() + var/list/available_options = possible_options.Copy() + for (var/i in 1 to 6) + if (!length(available_options)) + break + var/wand_path = pick_n_take(available_options) + new wand_path(src) + +/// Not a subtype of bandolier because it acts pretty differently +/obj/item/storage/belt/wand_bandolier + name = "wand bandolier" + desc = "A bandolier for holding a whole lot of wands. If worn on your suit, swaps expended wands for fresh ones on the fly." + icon_state = "bandolier" + inhand_icon_state = "bandolier" + worn_icon_state = "bandolier" + storage_type = /datum/storage/wands_belt + w_class = WEIGHT_CLASS_NORMAL + +/obj/item/storage/belt/wand_bandolier/equipped(mob/user, slot) + . = ..() + if (!(slot & ITEM_SLOT_SUITSTORE)) + return + ADD_CLOTHING_TRAIT(user, TRAIT_GUNFLIP) + RegisterSignal(user, COMSIG_MOB_FIRED_GUN, PROC_REF(on_gun_fired)) + +/obj/item/storage/belt/wand_bandolier/dropped(mob/user) + . = ..() + REMOVE_CLOTHING_TRAIT(user, TRAIT_GUNFLIP) + UnregisterSignal(user, COMSIG_MOB_FIRED_GUN) + +/// After we fire a gun, check if it's a wand. If it is and it's empty, do a swap +/obj/item/storage/belt/wand_bandolier/proc/on_gun_fired(mob/living/wizard, obj/item/gun/magic/wand/old_wand) + SIGNAL_HANDLER + INVOKE_ASYNC(src, PROC_REF(equip_new_wand), wizard, old_wand) + +/obj/item/storage/belt/wand_bandolier/proc/equip_new_wand(mob/living/wizard, obj/item/gun/magic/wand/old_wand) + if (!istype(old_wand)) + return + if (!atom_storage.real_location.contents.len) // no other wands + return + if (old_wand.charges > 1) // It hasn't subtracted yet + return + + var/obj/item/fresh_wand + for (var/obj/item/gun/magic/wand/checked in atom_storage.real_location.contents) + if (checked.charges) + fresh_wand = checked + break + if (!fresh_wand || fresh_wand.on_found()) + return // Nothing to swap with + + wizard.temporarilyRemoveItemFromInventory(old_wand) + if (!wizard.put_in_hands(fresh_wand)) + return + to_chat(wizard, span_notice("You quickly draw [fresh_wand].")) + if (atom_storage.attempt_insert(old_wand, wizard)) + return + old_wand.forceMove(wizard.drop_location()) + to_chat(wizard, span_warning("...and drop [old_wand] on the ground.")) + /obj/item/storage/belt/janitor name = "janibelt" desc = "A belt used to hold most janitorial supplies." diff --git a/code/game/objects/items/storage/boxes/cargo_boxes.dm b/code/game/objects/items/storage/boxes/cargo_boxes.dm index 749873b50a0..a299ab08509 100644 --- a/code/game/objects/items/storage/boxes/cargo_boxes.dm +++ b/code/game/objects/items/storage/boxes/cargo_boxes.dm @@ -13,3 +13,19 @@ /obj/item/stack/wrapping_paper/small = 1, ) generate_items_inside(items_inside,src) + +/obj/item/storage/box/shipping/debug + name = "box of bigger shipping supplies" + desc = "Everything you need to make your own cargo department." + +/obj/item/storage/box/shipping/debug/PopulateContents() + var/list/items_inside = list( + /obj/item/universal_scanner = 1, + /obj/item/stack/package_wrap/small = 2, + /obj/item/stack/wrapping_paper/small = 2, + /obj/item/boulder_beacon = 1, + /obj/item/stack/conveyor/thirty = 1, + /obj/item/conveyor_switch_construct = 1, + /obj/item/construction/plumbing = 1, + ) + generate_items_inside(items_inside,src) diff --git a/code/game/objects/items/storage/garment.dm b/code/game/objects/items/storage/garment.dm index 960ab7c9334..3be99e8d337 100644 --- a/code/game/objects/items/storage/garment.dm +++ b/code/game/objects/items/storage/garment.dm @@ -47,6 +47,7 @@ new /obj/item/clothing/under/rank/captain(src) new /obj/item/clothing/under/rank/captain/skirt(src) new /obj/item/clothing/under/rank/captain/parade(src) + new /obj/item/clothing/under/rank/captain/royal(src) new /obj/item/clothing/suit/armor/vest/capcarapace(src) new /obj/item/clothing/suit/armor/vest/capcarapace/captains_formal(src) new /obj/item/clothing/suit/hooded/wintercoat/captain(src) @@ -56,6 +57,7 @@ new /obj/item/clothing/head/costume/crown/fancy(src) new /obj/item/clothing/head/hats/caphat(src) new /obj/item/clothing/head/hats/caphat/parade(src) + new /obj/item/clothing/head/hats/caphat/bicorne(src) new /obj/item/clothing/neck/cloak/cap(src) new /obj/item/clothing/shoes/laceup(src) new /obj/item/storage/backpack/captain(src) diff --git a/code/game/objects/items/storage/toolboxes/medical.dm b/code/game/objects/items/storage/toolboxes/medical.dm index 0c9323212b6..26630831aef 100644 --- a/code/game/objects/items/storage/toolboxes/medical.dm +++ b/code/game/objects/items/storage/toolboxes/medical.dm @@ -41,4 +41,4 @@ /obj/item/storage/toolbox/medical/coroner/Initialize(mapload) . = ..() - AddElement(/datum/element/bane, mob_biotypes = MOB_UNDEAD, damage_multiplier = 1) //Just in case one of the tennants get uppity + AddComponent(/datum/component/bane, affected_biotypes = MOB_UNDEAD, damage_multiplier = 2) //Just in case one of the tennants get uppity diff --git a/code/game/objects/items/storage/uplink_kits.dm b/code/game/objects/items/storage/uplink_kits.dm index 75aa8ce47a5..8d1260a638b 100644 --- a/code/game/objects/items/storage/uplink_kits.dm +++ b/code/game/objects/items/storage/uplink_kits.dm @@ -491,6 +491,11 @@ new /obj/item/reagent_containers/cup/bottle/amanitin(src) new /obj/item/reagent_containers/syringe(src) +/obj/item/storage/box/syndie_kit/carnivorous_blood/PopulateContents() + new /obj/item/reagent_containers/cup/bottle/carnivorous_blood(src) + new /obj/item/reagent_containers/syringe(src) + new /obj/item/food/meat/slab/human(src) + /obj/item/storage/box/syndie_kit/nuke name = "nuke core extraction kit" desc = "A box containing the equipment and instructions for extracting the plutonium cores of most Nanotrasen nuclear explosives." @@ -798,6 +803,7 @@ var/datum/antagonist/nukeop/nuke_datum = new() nuke_datum.send_to_spawnpoint = FALSE + nuke_datum.give_bonus_tc = FALSE nuke_datum.nukeop_outfit = null human_target.mind?.add_antag_datum(nuke_datum) human_target.add_faction(ROLE_SYNDICATE) diff --git a/code/game/objects/items/tanks/jetpack.dm b/code/game/objects/items/tanks/jetpack.dm index 3a665d903a6..74557295dac 100644 --- a/code/game/objects/items/tanks/jetpack.dm +++ b/code/game/objects/items/tanks/jetpack.dm @@ -73,8 +73,7 @@ /obj/item/tank/jetpack/populate_gas() if(gas_type) var/datum/gas_mixture/our_mix = return_air() - our_mix.assert_gas(gas_type) - our_mix.gases[gas_type][MOLES] = ((6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C)) + our_mix.set_gas(gas_type, ((6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C))) /obj/item/tank/jetpack/ui_action_click(mob/user, action) if(istype(action, /datum/action/item_action/toggle_jetpack)) diff --git a/code/game/objects/items/tanks/tank_types.dm b/code/game/objects/items/tanks/tank_types.dm index 5ecfa9e154e..5f26c569932 100644 --- a/code/game/objects/items/tanks/tank_types.dm +++ b/code/game/objects/items/tanks/tank_types.dm @@ -35,8 +35,7 @@ /obj/item/tank/internals/oxygen/populate_gas() - air_contents.assert_gas(/datum/gas/oxygen) - air_contents.gases[/datum/gas/oxygen][MOLES] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + air_contents.set_gas(/datum/gas/oxygen, (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) /obj/item/tank/internals/oxygen/yellow @@ -68,9 +67,9 @@ force = 10 /obj/item/tank/internals/anesthetic/populate_gas() - air_contents.assert_gases(/datum/gas/oxygen, /datum/gas/nitrous_oxide) - air_contents.gases[/datum/gas/oxygen][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD - air_contents.gases[/datum/gas/nitrous_oxide][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD + air_contents.set_gas(/datum/gas/oxygen, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD) + air_contents.set_gas(/datum/gas/nitrous_oxide, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD) + /obj/item/tank/internals/anesthetic/examine(mob/user) . = ..() @@ -82,8 +81,7 @@ icon_state = "anesthetic_warning" /obj/item/tank/internals/anesthetic/pure/populate_gas() - air_contents.assert_gases(/datum/gas/nitrous_oxide) - air_contents.gases[/datum/gas/nitrous_oxide][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + air_contents.adjust_gas(/datum/gas/nitrous_oxide, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) /* * Plasma @@ -101,8 +99,7 @@ /obj/item/tank/internals/plasma/populate_gas() - air_contents.assert_gas(/datum/gas/plasma) - air_contents.gases[/datum/gas/plasma][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + air_contents.set_gas(/datum/gas/plasma, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) /obj/item/tank/internals/plasma/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers) if(istype(W, /obj/item/flamethrower)) @@ -118,8 +115,7 @@ return ..() /obj/item/tank/internals/plasma/full/populate_gas() - air_contents.assert_gas(/datum/gas/plasma) - air_contents.gases[/datum/gas/plasma][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + air_contents.set_gas(/datum/gas/plasma, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) /obj/item/tank/internals/plasma/empty/populate_gas() return @@ -138,12 +134,10 @@ distribute_pressure = TANK_PLASMAMAN_RELEASE_PRESSURE /obj/item/tank/internals/plasmaman/populate_gas() - air_contents.assert_gas(/datum/gas/plasma) - air_contents.gases[/datum/gas/plasma][MOLES] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + air_contents.set_gas(/datum/gas/plasma, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) /obj/item/tank/internals/plasmaman/full/populate_gas() - air_contents.assert_gas(/datum/gas/plasma) - air_contents.gases[/datum/gas/plasma][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + air_contents.set_gas(/datum/gas/plasma, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) /obj/item/tank/internals/plasmaman/belt @@ -158,8 +152,7 @@ w_class = WEIGHT_CLASS_SMALL //thanks i forgot this /obj/item/tank/internals/plasmaman/belt/full/populate_gas() - air_contents.assert_gas(/datum/gas/plasma) - air_contents.gases[/datum/gas/plasma][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + air_contents.set_gas(/datum/gas/plasma, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) /obj/item/tank/internals/plasmaman/belt/empty/populate_gas() return @@ -186,8 +179,7 @@ /obj/item/tank/internals/emergency_oxygen/populate_gas() - air_contents.assert_gas(/datum/gas/oxygen) - air_contents.gases[/datum/gas/oxygen][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) + air_contents.set_gas(/datum/gas/oxygen, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)) /obj/item/tank/internals/emergency_oxygen/empty/populate_gas() @@ -247,21 +239,18 @@ /obj/item/tank/internals/emergency_oxygen/engi/clown/n2o /obj/item/tank/internals/emergency_oxygen/engi/clown/n2o/populate_gas() - air_contents.assert_gases(/datum/gas/oxygen, /datum/gas/nitrous_oxide) - air_contents.gases[/datum/gas/oxygen][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * 0.95 - air_contents.gases[/datum/gas/nitrous_oxide][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * 0.05 + air_contents.set_gas(/datum/gas/oxygen, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * 0.95) + air_contents.set_gas(/datum/gas/nitrous_oxide, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * 0.05) /obj/item/tank/internals/emergency_oxygen/engi/clown/bz /obj/item/tank/internals/emergency_oxygen/engi/clown/bz/populate_gas() - air_contents.assert_gases(/datum/gas/oxygen, /datum/gas/bz) - air_contents.gases[/datum/gas/oxygen][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * 0.9 - air_contents.gases[/datum/gas/bz][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * 0.1 + air_contents.set_gas(/datum/gas/oxygen,(10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * 0.9) + air_contents.set_gas(/datum/gas/bz,(10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * 0.1) /obj/item/tank/internals/emergency_oxygen/engi/clown/helium distribute_pressure = TANK_CLOWN_RELEASE_PRESSURE + 2 /obj/item/tank/internals/emergency_oxygen/engi/clown/helium/populate_gas() - air_contents.assert_gases(/datum/gas/oxygen, /datum/gas/helium) - air_contents.gases[/datum/gas/oxygen][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * 0.75 - air_contents.gases[/datum/gas/helium][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * 0.25 + air_contents.set_gas(/datum/gas/oxygen, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * 0.75) + air_contents.set_gas(/datum/gas/helium, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * 0.25) diff --git a/code/game/objects/items/teleportation.dm b/code/game/objects/items/teleportation.dm index 9a9edfabe3d..d038a2eb254 100644 --- a/code/game/objects/items/teleportation.dm +++ b/code/game/objects/items/teleportation.dm @@ -406,11 +406,9 @@ var/teleport_distance = rand(minimum_teleport_distance, maximum_teleport_distance) var/turf/destination = get_teleport_loc(current_location, user, teleport_distance) var/bagholdingcheck = FALSE - if(iscarbon(user)) - var/mob/living/carbon/teleporting_guy = user - if(locate(/obj/item/storage/backpack/holding) in teleporting_guy.get_all_gear(INCLUDE_PROSTHETICS|INCLUDE_ABSTRACT|INCLUDE_ACCESSORIES)) + for(var/obj/item/check as anything in user.get_all_contents_type(/obj/item)) + if(check.item_flags & BLUESPACE_INTERFERENCE) bagholdingcheck = TRUE - if(isclosedturf(destination)) if(!triggered_by_emp && !bagholdingcheck) panic_teleport(user, destination) //We're in a wall, engage emergency parallel teleport. @@ -501,7 +499,7 @@ ///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(!user.can_bleed(BLOOD_COVER_TURFS) != BLEED_SPLATTER) + if(user.can_bleed(BLOOD_COVER_TURFS) != BLEED_SPLATTER) return FALSE user.add_splatter_floor(old_location) user.add_splatter_floor(new_location) diff --git a/code/game/objects/items/tools/engineering/weldingtool.dm b/code/game/objects/items/tools/engineering/weldingtool.dm index ad7770a84cc..c3eee46701a 100644 --- a/code/game/objects/items/tools/engineering/weldingtool.dm +++ b/code/game/objects/items/tools/engineering/weldingtool.dm @@ -261,13 +261,13 @@ START_PROCESSING(SSobj, src) else balloon_alert(user, "no fuel!") - switched_off(user) + switched_off() else playsound(loc, deactivation_sound, 50, TRUE) - switched_off(user) + switched_off() /// Switches the welder off -/obj/item/weldingtool/proc/switched_off(mob/user) +/obj/item/weldingtool/proc/switched_off() set_welding(FALSE) force = 3 diff --git a/code/game/objects/items/tools/medical/defib.dm b/code/game/objects/items/tools/medical/defib.dm index 05b31ed295f..ecf01547462 100644 --- a/code/game/objects/items/tools/medical/defib.dm +++ b/code/game/objects/items/tools/medical/defib.dm @@ -122,12 +122,12 @@ /obj/item/defibrillator/attack_hand(mob/user, list/modifiers) if(loc == user) if(user.get_slot_by_item(src) & slot_flags) - ui_action_click() + ui_action_click(user, modifiers) else balloon_alert(user, "equip the unit first!") return else if(istype(loc, /obj/machinery/defibrillator_mount)) - ui_action_click() //checks for this are handled in defibrillator.mount.dm + ui_action_click(user, modifiers) //checks for this are handled in defibrillator.mount.dm return ..() /obj/item/defibrillator/screwdriver_act(mob/living/user, obj/item/tool) diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index ce765778cb6..a4f64946c0e 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -1139,7 +1139,9 @@ /obj/item/toy/clockwork_watch/examine(mob/user) . = ..() - . += span_info("Station Time: [station_time_timestamp()]") + . += span_info("Station Time: [server_timestamp(ic_time = TRUE, twelve_hour_clock = user.client?.prefs.read_preference(/datum/preference/toggle/twelve_hour))]") + if(user.is_literate()) + . += span_info("That means it is currently [round_timestamp()] into the shift.") /* * Toy Dagger diff --git a/code/game/objects/items/weaponry/melee/baton.dm b/code/game/objects/items/weaponry/melee/baton.dm index 3c5f0a4991a..a4ceccaa4eb 100644 --- a/code/game/objects/items/weaponry/melee/baton.dm +++ b/code/game/objects/items/weaponry/melee/baton.dm @@ -1009,22 +1009,19 @@ AddElement(/datum/element/examine_lore, \ lore_hint = span_notice("You can [EXAMINE_HINT("look closer")] to learn a little more about [src]."), \ lore = "The Secure Apprehension Device (sometimes referred to as the SAD in the officer training manuals) is \ - the unholy union of a mace and a cattleprod. This nonlethal device was designed to put a stop to ruffians, \ - scoundrels, ne'er-do-wells and criminals wherever they may rear their ugly heads.
\ + an unholy union of mace and cattleprod. Designed to stop criminals in their tracks, Nanotrasen security members \ + are rarely without their trusty stun baton. Assuming they haven't lost it somewhere.
\
\ - A symbol of Nanotrasen security forces, the stun baton is the primary tool officers employ against the \ - unlawful scum and villainy of the Spinward and abroad. Trained to 'baton first, interrogate later', \ - Nanotrasen security has long since earned itself a mixed reputation. Able to rapidly shut down the \ - central nervous system of a criminal with only a few direct applications of the conductive striking head \ - of the device, few would-be troublemakers want to find themselves on the wrong end of an officer brandishing \ - this baton.
\ + Trained to 'baton first, interrogate later', Nanotrasen security has long since earned itself a mixed reputation. \ + The device is able to rapidly shut down the central nervous system of a criminal with only a few direct applications \ + of the conductive striking head.
\
\ TerraGov law enforcement has avoided the adoption of stun batons due to various ethical dilemmas posed by \ - their usage, largely because of the longterm physical and mental ramifications of being struck by a human cattleprod. \ - Citizens' rights advocacy groups protest against the proliferation of stun batons as a policing tool, \ - arguing that they are 'inhumane' and 'authoritarian'. Nanotrasen, on the other hand, has had no such qualms \ - when deploying stun batons as a compliance measure across all of their existing stations and facilities against \ - unruly members of staff." \ + their utilization. Studies of their usage have shown numerous longterm physical and mental ramifications caused by \ + being struck by a human cattleprod. Citizens' rights advocacy groups protest against the proliferation of stun \ + batons as a policing tool, arguing that they are 'inhumane' and 'authoritarian'. Nanotrasen, on the other hand, \ + has had no such qualms when deploying stun batons as a compliance measure across all of their existing stations \ + and facilities against their own unruly members of staff." \ ) // Contractor Baton @@ -1033,25 +1030,14 @@ AddElement(/datum/element/examine_lore, \ lore_hint = span_notice("You can [EXAMINE_HINT("look closer")] to learn a little more about [src]."), \ lore = "The Contract Acquisition Device (sometimes referred to as the CAD in encrypted correspondence) is \ - one of the more frequently encountered examples of Cybersun Industries weaponry. Extremely similar to Nanotrasen's \ - own Secure Apprehension Device (also simply known as the stun baton), the contractor baton is able to induce \ - CNS disruption in a target to render them helpless. It is also capable of devastating blunt force trauma if \ - used as a bludgeon. The contractor baton is also capable of telescopic deployment, allowing for discretion while \ - making an approach towards a target.
\ + the most frequently encountered example of Cybersun Industries weaponry. Similar in purpose to Nanotrasen's \ + own Secure Apprehension Device, the baton is capable of inducing rapid CNS disruption in a target to render them \ + helpless. It also makes for an effective bludgeon, another quality it shares with the stun baton. To maximize \ + ease of concealment, the baton is also able to be telescopically collapsed, to then be rapidly deployed at the \ + pull of a trigger.
\
\ - The contractor baton is famously associated with contractors, elite Cybersun field agents. While the standard \ - agent would often be tasked with sabotage, terrorism, murder or theft, contractors have the critical task of \ - kidnapping high value personnel. Anyone with the potential to possess classified or sensitive data about Nanotrasen \ - security systems and devices could be a target for Cybersun.
\ -
\ - Extracting this information is most easily performed on living subjects. As such, the contractor baton was designed \ - with nonlethal incapacitation in mind. However, Cybersun Industries has long since found workarounds for extracting \ - data from the recently deceased, should the contractor find themselves with only a corpse left to send back. Death \ - may not spare you from the machinations of Cybersun Industries if they deem you a valuable asset towards their goals.
\ -
\ - Nanotrasen utilizes a number of countermeasures to contractor insurgencies, such as employing selective memory wiping \ - or falsified memory injection, the establishment of 'dummy' command staff through the artificial acceleration \ - of otherwise incompetent but useful crewmembers (whose incompetence will often result in an acceptable degree \ - of operational disruption), which provides convenient scapegoats in the event of a security breach as well as \ - frequent staff turnover and reassignment." \ + The contractor baton is famously associated with contractors, elite Cybersun field agents sent to kidnap and extract \ + high value enemy personnel for interrogation. Anyone with the potential to possess classified or sensitive data about \ + Nanotrasen could find themselves a target for Cybersun. The company relentlessly employs contractors to probe Nanotrasen \ + for vulnerabilities, starting with their employees." \ ) diff --git a/code/game/objects/items/weaponry/melee/misc.dm b/code/game/objects/items/weaponry/melee/misc.dm index 11d951f22a9..b79ff035f20 100644 --- a/code/game/objects/items/weaponry/melee/misc.dm +++ b/code/game/objects/items/weaponry/melee/misc.dm @@ -488,7 +488,18 @@ /obj/effect/decal/cleanable/ants, /obj/item/queen_bee, )) - AddElement(/datum/element/bane, mob_biotypes = MOB_BUG, target_type = /mob/living/basic, damage_multiplier = 0, added_damage = 24, requires_combat_mode = FALSE) + AddComponent(/datum/component/bane, affected_biotypes = MOB_BUG, pre_bane_callback = CALLBACK(src, PROC_REF(bane_check)) ) + +// Different type of bug mobs get different amounts of damage multipliers +/obj/item/melee/flyswatter/proc/bane_check(mob/living/target, mob/living/attacker, list/attack_modifiers) + if(isanimal_or_basicmob(target)) + MODIFY_ATTACK_FORCE(attack_modifiers, 24) + else if(isflyperson(target)) + MODIFY_ATTACK_FORCE(attack_modifiers, 29) + else if(ismoth(target)) + MODIFY_ATTACK_FORCE(attack_modifiers, 9) + else // ?? Whatever + MODIFY_ATTACK_FORCE(attack_modifiers, 14) /obj/item/melee/flyswatter/afterattack(atom/target, mob/user, list/modifiers, list/attack_modifiers) if(is_type_in_typecache(target, splattable)) diff --git a/code/game/objects/items/weaponry/melee/sabre.dm b/code/game/objects/items/weaponry/melee/sabre.dm index 0cc90020800..1507193e3e8 100644 --- a/code/game/objects/items/weaponry/melee/sabre.dm +++ b/code/game/objects/items/weaponry/melee/sabre.dm @@ -34,29 +34,23 @@ bonus_modifier = 5, \ ) // The weight of authority comes down on the tider's crimes. - AddElement(/datum/element/bane, target_type = /mob/living/carbon/human, damage_multiplier = 0.35) - RegisterSignal(src, COMSIG_OBJECT_PRE_BANING, PROC_REF(attempt_bane)) - RegisterSignal(src, COMSIG_OBJECT_ON_BANING, PROC_REF(bane_effects)) - -/** - * If the target reeks of maintenance, the blade can tear through their body with a total of 20 damage. - */ -/obj/item/melee/sabre/proc/attempt_bane(element_owner, mob/living/carbon/criminal) - SIGNAL_HANDLER - var/obj/item/organ/liver/liver = criminal.get_organ_slot(ORGAN_SLOT_LIVER) - if(isnull(liver) || !HAS_TRAIT(liver, TRAIT_MAINTENANCE_METABOLISM)) - return COMPONENT_CANCEL_BANING - -/** - * Assistants should fear this weapon. - */ -/obj/item/melee/sabre/proc/bane_effects(element_owner, mob/living/carbon/human/baned_target) - SIGNAL_HANDLER - baned_target.visible_message( - span_warning("[src] tears through [baned_target] with unnatural ease!"), - span_userdanger("As [src] tears into your body, you feel the weight of authority collapse into your wounds!"), + AddComponent(/datum/component/bane, \ + damage_multiplier = 1.35, \ + should_bane_callback = CALLBACK(src, PROC_REF(bane_check)), \ + on_bane_callback = CALLBACK(src, PROC_REF(bane_message)), \ + label_text = "assistants", \ ) - INVOKE_ASYNC(baned_target, TYPE_PROC_REF(/mob/living/carbon/human, emote), "scream") + +/obj/item/melee/sabre/proc/bane_check(mob/living/target) + var/obj/item/organ/liver/liver = target.get_organ_slot(ORGAN_SLOT_LIVER) + return !isnull(liver) && HAS_TRAIT(liver, TRAIT_MAINTENANCE_METABOLISM) + +/obj/item/melee/sabre/proc/bane_message(mob/living/target, mob/living/attacker) + target.visible_message( + span_warning("[src] tears through [target] with unnatural ease!"), + span_boldwarning("As [src] tears into your body, you feel the weight of authority collapse into your wounds!"), + ) + INVOKE_ASYNC(target, TYPE_PROC_REF(/mob, emote), "scream") /obj/item/melee/sabre/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 || attack_type == OVERWHELMING_ATTACK) diff --git a/code/game/objects/items/weaponry/melee/soulscythe.dm b/code/game/objects/items/weaponry/melee/soulscythe.dm index 35b27736e13..596166d14e0 100644 --- a/code/game/objects/items/weaponry/melee/soulscythe.dm +++ b/code/game/objects/items/weaponry/melee/soulscythe.dm @@ -38,7 +38,7 @@ RegisterSignal(soul, COMSIG_MOB_ATTACK_RANGED, PROC_REF(on_attack)) RegisterSignal(soul, COMSIG_MOB_ATTACK_RANGED_SECONDARY, PROC_REF(on_secondary_attack)) RegisterSignal(src, COMSIG_ATOM_INTEGRITY_CHANGED, PROC_REF(on_integrity_change)) - AddElement(/datum/element/bane, mob_biotypes = MOB_PLANT, damage_multiplier = 0.5, requires_combat_mode = FALSE) + AddComponent(/datum/component/bane, affected_biotypes = MOB_PLANT, damage_multiplier = 1.5) /obj/item/soulscythe/examine(mob/user) . = ..() @@ -263,12 +263,10 @@ /mob/living/basic/soulscythe/Initialize(mapload) . = ..() add_traits(list(TRAIT_ASHSTORM_IMMUNE, TRAIT_SNOWSTORM_IMMUNE, TRAIT_LAVA_IMMUNE), INNATE_TRAIT) - RegisterSignal(src, COMSIG_LIVING_LIFE, PROC_REF(on_life)) -/mob/living/basic/soulscythe/proc/on_life(datum/source, seconds_per_tick) // done like this because there's no need to go through all of life since the item does the work anyways +/mob/living/basic/soulscythe/Life(seconds_per_tick) if(stat == CONSCIOUS) adjust_blood_volume(round(1 * seconds_per_tick), maximum = MAX_BLOOD_LEVEL) - return COMPONENT_LIVING_CANCEL_LIFE_PROCESSING /// Special projectile for the soulscythe. /obj/projectile/soulscythe diff --git a/code/game/objects/items/weaponry/melee/spear.dm b/code/game/objects/items/weaponry/melee/spear.dm index 8eb3c842b30..5f358a7b2f5 100644 --- a/code/game/objects/items/weaponry/melee/spear.dm +++ b/code/game/objects/items/weaponry/melee/spear.dm @@ -459,7 +459,7 @@ /obj/item/spear/dragonator/Initialize(mapload) . = ..() - AddElement(/datum/element/bane, mob_biotypes = MOB_MINING, damage_multiplier = 0, added_damage = 80, requires_combat_mode = FALSE) //For killing really big monsters. + AddComponent(/datum/component/bane, affected_biotypes = MOB_MINING, added_damage = 80) //For killing really big monsters. /* * Untreated Giantslayer , needs to be thrown into lava diff --git a/code/game/objects/items/weaponry/ranged/flamethrower.dm b/code/game/objects/items/weaponry/ranged/flamethrower.dm index 29a410dcb10..c8421c9fe80 100644 --- a/code/game/objects/items/weaponry/ranged/flamethrower.dm +++ b/code/game/objects/items/weaponry/ranged/flamethrower.dm @@ -231,7 +231,8 @@ var/datum/gas_mixture/air_transfer = tank_mix.remove_ratio(release_amount) if(air_transfer.gases[/datum/gas/plasma]) - air_transfer.gases[/datum/gas/plasma][MOLES] *= 5 //Suffering + var/moles = air_transfer.gases[/datum/gas/plasma][MOLES] * 5 //Suffering + air_transfer.set_gas(/datum/gas/plasma, moles) target.assume_air(air_transfer) //Burn it based on transferred gas target.hotspot_expose((tank_mix.temperature*2) + 380,500) @@ -286,8 +287,7 @@ SIGNAL_HANDLER if(ptank) var/datum/gas_mixture/tank_mix = ptank.return_air() - tank_mix.assert_gas(/datum/gas/plasma) - tank_mix.gases[/datum/gas/plasma][MOLES] = (10*ONE_ATMOSPHERE)*ptank.volume/(R_IDEAL_GAS_EQUATION*T20C) + tank_mix.set_gas(/datum/gas/plasma, (10*ONE_ATMOSPHERE)*ptank.volume/(R_IDEAL_GAS_EQUATION*T20C)) else ptank = new /obj/item/tank/internals/plasma/full(src) update_appearance() diff --git a/code/game/objects/items/weaponry/shields.dm b/code/game/objects/items/weaponry/shields.dm index c2fa89a06b8..2f8b5ab46cb 100644 --- a/code/game/objects/items/weaponry/shields.dm +++ b/code/game/objects/items/weaponry/shields.dm @@ -43,6 +43,7 @@ /obj/item/shield/Initialize(mapload) . = ..() AddElement(/datum/element/disarm_attack) + AddElement(/datum/element/cuffable_item) /obj/item/shield/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) var/effective_block_chance = final_block_chance diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 167ca422109..3db7bc1c079 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -357,6 +357,8 @@ GLOBAL_LIST_EMPTY(objects_by_id_tag) /// Returns modifier to how much damage this object does to a target considered vulnerable to "demolition" (other objects, robots, etc) /obj/proc/get_demolition_modifier(obj/target) + if(HAS_TRAIT(target, TRAIT_IGNORE_DEMOLITION)) + return 1 if(HAS_TRAIT(target, TRAIT_INVERTED_DEMOLITION)) return (1 / demolition_mod) return demolition_mod diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm index 7e8d586a4d3..ec0994a5025 100644 --- a/code/game/objects/structures/beds_chairs/chair.dm +++ b/code/game/objects/structures/beds_chairs/chair.dm @@ -629,8 +629,9 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0) fishing_modifier = -21 //it only lives for 25 seconds, so we make them worth it. custom_materials = null -/obj/structure/chair/mime/wrench_act_secondary(mob/living/user, obj/item/weapon) - return NONE +/obj/structure/chair/mime/Initialize(mapload) + . = ..() + AddElement(/datum/element/tool_blocker, TOOL_WRENCH, TOOL_ACT_SECONDARY) /obj/structure/chair/mime/post_buckle_mob(mob/living/M) M.add_offsets(type, z_add = 5) diff --git a/code/game/objects/structures/crates_lockers/closets/bodybag.dm b/code/game/objects/structures/crates_lockers/closets/bodybag.dm index 28c2b6030b3..b911705b010 100644 --- a/code/game/objects/structures/crates_lockers/closets/bodybag.dm +++ b/code/game/objects/structures/crates_lockers/closets/bodybag.dm @@ -159,11 +159,9 @@ content.forceMove(folding_bodybag) if(isliving(content)) to_chat(content, span_userdanger("You're suddenly forced into a tiny, compressed space!")) - if(iscarbon(content)) - var/mob/living/carbon/mob = content - if (mob.dna?.get_mutation(/datum/mutation/dwarfism)) - max_weight_of_contents = max(WEIGHT_CLASS_NORMAL, max_weight_of_contents) - continue + if(HAS_TRAIT(content, TRAIT_DWARF)) + max_weight_of_contents = max(WEIGHT_CLASS_NORMAL, max_weight_of_contents) + continue if(!isitem(content)) max_weight_of_contents = max(WEIGHT_CLASS_BULKY, max_weight_of_contents) continue @@ -297,8 +295,8 @@ air_contents.temperature = T20C air_contents.assert_gases(/datum/gas/oxygen, /datum/gas/nitrogen) - air_contents.gases[/datum/gas/oxygen][MOLES] = (ONE_ATMOSPHERE*50)/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD - air_contents.gases[/datum/gas/nitrogen][MOLES] = (ONE_ATMOSPHERE*50)/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD + air_contents.adjust_gas(/datum/gas/oxygen, (ONE_ATMOSPHERE*50)/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD) + air_contents.adjust_gas(/datum/gas/nitrogen, (ONE_ATMOSPHERE*50)/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD) /obj/structure/closet/body_bag/environmental/nanotrasen name = "elite environmental protection bag" @@ -428,8 +426,8 @@ air_contents.temperature = T20C air_contents.assert_gases(/datum/gas/oxygen, /datum/gas/nitrous_oxide) - air_contents.gases[/datum/gas/oxygen][MOLES] = (ONE_ATMOSPHERE*50)/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD - air_contents.gases[/datum/gas/nitrous_oxide][MOLES] = (ONE_ATMOSPHERE*50)/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD + air_contents.adjust_gas(/datum/gas/oxygen, (ONE_ATMOSPHERE*50)/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD) + air_contents.adjust_gas(/datum/gas/nitrous_oxide, (ONE_ATMOSPHERE*50)/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD) /obj/structure/closet/body_bag/environmental/hardlight name = "hardlight bodybag" @@ -509,11 +507,10 @@ var/inner_temp = T0C - 60 air_contents = null air_contents = new(mol_count) - air_contents.temperature = inner_temp + air_contents.set_temperature(inner_temp) - air_contents.assert_gases(/datum/gas/oxygen, /datum/gas/nitrogen) - air_contents.gases[/datum/gas/oxygen][MOLES] = (ONE_ATMOSPHERE * mol_count) / (R_IDEAL_GAS_EQUATION * inner_temp) * O2STANDARD - air_contents.gases[/datum/gas/nitrogen][MOLES] = (ONE_ATMOSPHERE * mol_count) / (R_IDEAL_GAS_EQUATION * inner_temp) * N2STANDARD + air_contents.set_gas(/datum/gas/oxygen, ((ONE_ATMOSPHERE * mol_count) / (R_IDEAL_GAS_EQUATION * inner_temp) * O2STANDARD)) + air_contents.set_gas(/datum/gas/nitrogen, ((ONE_ATMOSPHERE * mol_count) / (R_IDEAL_GAS_EQUATION * inner_temp) * N2STANDARD)) /obj/structure/closet/body_bag/environmental/stasis/examine_status(mob/user) switch(100 * get_integrity_percentage()) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm b/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm index 3bfee4282c2..66fa776f403 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm @@ -9,6 +9,7 @@ new /obj/item/radio/weather_monitor (src) new /obj/item/radio/headset/heads/qm(src) new /obj/item/megaphone/cargo(src) + new /obj/item/assembly/flash/handheld(src) new /obj/item/tank/internals/emergency_oxygen(src) new /obj/item/universal_scanner(src) new /obj/item/door_remote/quartermaster(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 7e4350c4cb0..b5e287585e2 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -210,6 +210,9 @@ req_one_access = list(ACCESS_BRIG) var/id = null +/obj/structure/closet/secure_closet/brig/holodeck + req_one_access = COMMON_ACCESS + /obj/structure/closet/secure_closet/brig/genpop name = "genpop storage locker" desc = "Used for storing the belongings of genpop's tourists visiting the locals." diff --git a/code/game/objects/structures/crates_lockers/crates/abandoned_crates/abandoned_crates.dm b/code/game/objects/structures/crates_lockers/crates/abandoned_crates/abandoned_crates.dm index 3a17fdc4b8b..61034b9f017 100644 --- a/code/game/objects/structures/crates_lockers/crates/abandoned_crates/abandoned_crates.dm +++ b/code/game/objects/structures/crates_lockers/crates/abandoned_crates/abandoned_crates.dm @@ -76,7 +76,7 @@ ) = 11, list( // Mobs - /mob/living/basic/bot/honkbot = 5, + /mob/living/basic/bot/secbot/honkbot = 5, /mob/living/basic/pet/gondola = 2, /obj/effect/spawner/abandoned_crate/bloodroaches = 1, ) = 8, @@ -188,6 +188,12 @@ return ITEM_INTERACT_SUCCESS +/obj/structure/closet/crate/secure/loot/multitool_act_secondary(mob/living/user, obj/item/tool) + if(!locked) + return + attack_hand(user) + return ITEM_INTERACT_SUCCESS + /// Implements bulls and cows algorithm to compare guess against actual code /obj/structure/closet/crate/secure/loot/proc/bulls_and_cows(guess) var/bulls = 0 diff --git a/code/game/objects/structures/crates_lockers/crates/abandoned_crates/abandoned_crates_loot.dm b/code/game/objects/structures/crates_lockers/crates/abandoned_crates/abandoned_crates_loot.dm index 490b280c66c..943af17cf1f 100644 --- a/code/game/objects/structures/crates_lockers/crates/abandoned_crates/abandoned_crates_loot.dm +++ b/code/game/objects/structures/crates_lockers/crates/abandoned_crates/abandoned_crates_loot.dm @@ -64,7 +64,7 @@ /obj/effect/spawner/abandoned_crate/space_suit loot = list( - /obj/item/borg/upgrade/modkit/aoe/mobs = 1, + /obj/item/borg/upgrade/modkit/cooldown/aoe/mobs = 1, /obj/item/clothing/suit/space = 1, /obj/item/clothing/head/helmet/space = 1 ) diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index 430ae36fb77..6407bb104d9 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -388,7 +388,7 @@ /obj/structure/displaycase/trophy/proc/toggle_historian_mode(mob/user) historian_mode = !historian_mode balloon_alert(user, "[historian_mode ? "enabled" : "disabled"] historian mode.") - playsound(src, 'sound/machines/beep/twobeep.ogg', vary = 50) + playsound(src, 'sound/machines/beep/twobeep.ogg', 10, vary = 50) SStgui.update_uis(src) /obj/structure/displaycase/trophy/toggle_lock(mob/user) diff --git a/code/game/objects/structures/electricchair.dm b/code/game/objects/structures/electricchair.dm index d68457f9bae..ffe4252f6ef 100644 --- a/code/game/objects/structures/electricchair.dm +++ b/code/game/objects/structures/electricchair.dm @@ -8,10 +8,14 @@ /obj/structure/chair/e_chair/Initialize(mapload) . = ..() - var/obj/item/assembly/shock_kit/stored_kit = new(contents) var/mutable_appearance/export_to_component = mutable_appearance('icons/obj/chairs.dmi', "echair_over", OBJ_LAYER, src, appearance_flags = KEEP_APART) export_to_component = color_atom_overlay(export_to_component) - AddComponent(/datum/component/electrified_buckle, (SHOCK_REQUIREMENT_ITEM | SHOCK_REQUIREMENT_LIVE_CABLE | SHOCK_REQUIREMENT_SIGNAL_RECEIVED_TOGGLE), stored_kit, list(export_to_component)) + + AddComponent(\ + /datum/component/electrified_buckle,\ + overlays_to_add = list(export_to_component),\ + shock_flags = (SHOCK_NOGLOVES)\ + ) /obj/structure/chair/e_chair/attackby(obj/item/W, mob/user, list/modifiers, list/attack_modifiers) if(W.tool_behaviour == TOOL_WRENCH) diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index 974425c94ca..4882007ddbb 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -1059,9 +1059,82 @@ /obj/structure/flora/rock/pile/style_random/Initialize(mapload) . = ..() - icon_state = "lavarocks[rand(1, 3)]" + icon_state = "lavarocks[pick(3;1,3;2,1;3)]" update_appearance() +/obj/structure/flora/rock/pile/siderite + icon_state = "lavarocks_siderite1" + +/obj/structure/flora/rock/pile/siderite/get_potential_products() + return list(/obj/item/stack/ore/glass/siderite = 1) + +/obj/structure/flora/rock/pile/siderite/style_2 + icon_state = "lavarocks_siderite2" + +/obj/structure/flora/rock/pile/siderite/style_3 + icon_state = "lavarocks_siderite3" + +/obj/structure/flora/rock/pile/siderite/style_random/Initialize(mapload) + . = ..() + icon_state = "lavarocks_siderite[pick(3;1,3;2,1;3)]" + update_appearance() + +/obj/structure/flora/rock/pile/shale + icon_state = "lavarocks_shale1" + +/obj/structure/flora/rock/pile/shale/style_2 + icon_state = "lavarocks_shale2" + +/obj/structure/flora/rock/pile/shale/style_3 + icon_state = "lavarocks_shale3" + +/obj/structure/flora/rock/pile/shale/style_random/Initialize(mapload) + . = ..() + icon_state = "lavarocks_shale[pick(3;1,3;2,1;3)]" + update_appearance() + +/obj/structure/flora/rock/siderite_growth + name = "siderite growth" + desc = "A natural stalagmite formed of siderite, with thin pointy strands of dirty metal sticking out of the top." + icon_state = "siderite_growth1" + base_icon_state = "siderite_growth" + icon = 'icons/obj/mining_zones/terrain.dmi' + harvest_message_med = "You finish mining the growth." + +/obj/structure/flora/rock/siderite_growth/Initialize(mapload) + . = ..() + icon_state = "[base_icon_state][pick(3;1,3;2,1;3)]" + update_appearance() + AddComponent(/datum/component/seethrough, SEE_THROUGH_MAP_DEFAULT) + +/obj/structure/flora/rock/siderite_growth/get_potential_products() + return list(/obj/item/stack/ore/glass/siderite = 1) + +/obj/structure/flora/rock/volcano + name = "volcanic pore" + desc = "A miniature volcano-like rock formed of the lava slowly pouring from it." + icon_state = "volcano_1" + base_icon_state = "volcano" + harvest_message_med = "You finish mining the pore buildup." + light_range = 3 + light_power = 2.5 + light_color = LIGHT_COLOR_LAVA + +/obj/structure/flora/rock/volcano/Initialize(mapload) + . = ..() + icon_state = "[base_icon_state]_[rand(1, 5)]" + update_appearance() + +/obj/structure/flora/rock/volcano/update_overlays() + . = ..() + . += emissive_appearance(icon, "[icon_state]_e", src, alpha = 200) + +/obj/structure/flora/rock/volcano/after_harvest(user) + var/turf/open/our_turf = loc + if (istype(our_turf)) + our_turf.ChangeTurf(/turf/open/lava/smooth, flags = CHANGETURF_INHERIT_AIR) + return ..() + /obj/structure/flora/rock/pile/jungle icon_state = "rock1" icon = 'icons/obj/fluff/flora/jungleflora.dmi' diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index ec618d60831..77e80e95dc4 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -31,6 +31,7 @@ /obj/structure/grille/Initialize(mapload) . = ..() AddElement(/datum/element/atmos_sensitive, mapload) + register_context() /obj/structure/grille/Destroy() update_cable_icons_on_turf(get_turf(src)) @@ -59,9 +60,19 @@ if(resistance_flags & INDESTRUCTIBLE) return if(anchored) - . += span_notice("It's secured in place with screws. The rods look like they could be cut through.") + . += span_notice("It's secured in place with [EXAMINE_HINT("screws")]. The rods look like they could be [EXAMINE_HINT("cut")] through.") else - . += span_notice("The anchoring screws are unscrewed. The rods look like they could be cut through.") + . += span_notice("The anchoring screws are [EXAMINE_HINT("unscrewed")]. The rods look like they could be [EXAMINE_HINT("cut")] through.") + +/obj/structure/grille/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = ..() + if(held_item?.tool_behaviour == TOOL_WIRECUTTER) + context[SCREENTIP_CONTEXT_RMB] = "Deconstruct" + return CONTEXTUAL_SCREENTIP_SET + if(held_item?.tool_behaviour == TOOL_SCREWDRIVER) + context[SCREENTIP_CONTEXT_LMB] = "[anchored ? "Unanchor" : "Anchor"]" + return CONTEXTUAL_SCREENTIP_SET + return . /obj/structure/grille/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) switch(the_rcd.mode) @@ -199,7 +210,7 @@ return TRUE return FALSE -/obj/structure/grille/wirecutter_act(mob/living/user, obj/item/tool) +/obj/structure/grille/wirecutter_act_secondary(mob/living/user, obj/item/tool) add_fingerprint(user) if(shock(user, 100)) return diff --git a/code/game/objects/structures/guillotine.dm b/code/game/objects/structures/guillotine.dm index 50a9473e19f..0615ea579da 100644 --- a/code/game/objects/structures/guillotine.dm +++ b/code/game/objects/structures/guillotine.dm @@ -244,8 +244,7 @@ var/datum/species/S = victim.dna.species if (istype(S)) - victim.cut_overlays() - victim.update_body_parts_head_only() + victim.render_only_head() victim.remove_overlay(BODY_ADJ_LAYER) victim.pixel_y += -GUILLOTINE_HEAD_OFFSET // Offset their body so it looks like they're in the guillotine victim.layer += GUILLOTINE_LAYER_DIFF diff --git a/code/game/objects/structures/lavaland/geyser.dm b/code/game/objects/structures/lavaland/geyser.dm index bbbc8da76e4..5c790457e44 100644 --- a/code/game/objects/structures/lavaland/geyser.dm +++ b/code/game/objects/structures/lavaland/geyser.dm @@ -72,6 +72,7 @@ return to_chat(user, span_notice("You discovered the geyser and mark it on the GPS system!")) + playsound(src, 'sound/machines/beep/twobeep_high.ogg', 30) SEND_SIGNAL(user, COMSIG_LIVING_DISCOVERED_GEYSER, src) if(discovery_message) to_chat(user, discovery_message) diff --git a/code/game/objects/structures/lavaland/necropolis_tendril.dm b/code/game/objects/structures/lavaland/necropolis_tendril.dm deleted file mode 100644 index e6ca59016ed..00000000000 --- a/code/game/objects/structures/lavaland/necropolis_tendril.dm +++ /dev/null @@ -1,141 +0,0 @@ -//Necropolis Tendrils, which spawn lavaland monsters and break into a chasm when killed -/obj/structure/spawner/lavaland - name = "necropolis tendril" - desc = "A vile tendril of corruption, originating deep underground. Terrible monsters are pouring out of it." - - icon = 'icons/mob/simple/lavaland/nest.dmi' - icon_state = "tendril" - - faction = list(FACTION_MINING, FACTION_ASHWALKER) - max_mobs = 3 - max_integrity = 250 - mob_types = list(/mob/living/basic/mining/watcher) - - move_resist=INFINITY // just killing it tears a massive hole in the ground, let's not move it - anchored = TRUE - resistance_flags = FIRE_PROOF | LAVA_PROOF - var/obj/effect/light_emitter/tendril/emitted_light - scanner_taggable = TRUE - mob_gps_id = "WT" - spawner_gps_id = "Necropolis Tendril" - -/obj/structure/spawner/lavaland/goliath - mob_types = list(/mob/living/basic/mining/goliath) - mob_gps_id = "GL" - -/obj/structure/spawner/lavaland/legion - mob_types = list(/mob/living/basic/mining/legion/spawner_made) - mob_gps_id = "LG" - -/obj/structure/spawner/lavaland/icewatcher - mob_types = list(/mob/living/basic/mining/watcher/icewing) - mob_gps_id = "WT|I" // icewing - -GLOBAL_LIST_INIT(tendrils, list()) -/obj/structure/spawner/lavaland/Initialize(mapload) - . = ..() - emitted_light = new(loc) - for(var/F in RANGE_TURFS(1, src)) - if(ismineralturf(F)) - var/turf/closed/mineral/M = F - M.ScrapeAway(null, CHANGETURF_IGNORE_AIR) - AddComponent(/datum/component/gps, "Eerie Signal") - GLOB.tendrils += src - -/obj/structure/spawner/lavaland/atom_deconstruct(disassembled) - new /obj/effect/collapse(loc) - -/obj/structure/spawner/lavaland/examine(mob/user) - var/list/examine_messages = ..() - examine_messages += span_notice("Once this thing gets hurts enough, it triggers a violent final retaliation.") - examine_messages += span_notice("You'll only have a few moments to run up, grab some loot with an open hand, and get out with it.") - return examine_messages - -/obj/structure/spawner/lavaland/Destroy() - var/last_tendril = TRUE - if(GLOB.tendrils.len>1) - last_tendril = FALSE - - if(last_tendril && !(flags_1 & ADMIN_SPAWNED_1)) - if(SSachievements.achievements_enabled) - for(var/mob/living/L in view(7,src)) - if(L.stat || !L.client) - continue - L.client.give_award(/datum/award/achievement/boss/tendril_exterminator, L) - L.client.give_award(/datum/award/score/tendril_score, L) //Progresses score by one - GLOB.tendrils -= src - QDEL_NULL(emitted_light) - return ..() - -/obj/effect/light_emitter/tendril - set_luminosity = 4 - set_cap = 2.5 - light_color = LIGHT_COLOR_LAVA - -/obj/effect/collapse - name = "collapsing necropolis tendril" - desc = "Get your loot and get clear!" - layer = TABLE_LAYER - icon = 'icons/mob/simple/lavaland/nest.dmi' - icon_state = "tendril" - anchored = TRUE - density = TRUE - /// weakref list of which mobs have gotten their loot from this effect. - var/list/collected = list() - /// a bit of light as to make less unfair deaths from the chasm - var/obj/effect/light_emitter/tendril/emitted_light - -/obj/effect/collapse/Initialize(mapload) - . = ..() - emitted_light = new(loc) - visible_message(span_bolddanger("The tendril writhes in fury as the earth around it begins to crack and break apart! Get back!")) - balloon_alert_to_viewers("interact to grab loot before collapse!", vision_distance = 7) - playsound(loc,'sound/effects/tendril_destroyed.ogg', 200, FALSE, 50, TRUE, TRUE) - addtimer(CALLBACK(src, PROC_REF(collapse)), 5 SECONDS) - -/obj/effect/collapse/examine(mob/user) - var/list/examine_messages = ..() - if(isliving(user)) - if(has_collected(user)) - examine_messages += span_boldnotice("You've grabbed what you can, now get out!") - else - examine_messages += span_boldnotice("You might have some time to grab some goodies with an open hand before it collapses!") - return examine_messages - -/obj/effect/collapse/attack_hand(mob/living/collector, list/modifiers) - . = ..() - if(has_collected(collector)) - to_chat(collector, span_danger("You've already gotten some loot, just get out of there with it!")) - return - visible_message(span_warning("Something falls free of the tendril!")) - var/obj/structure/closet/crate/necropolis/tendril/loot = new /obj/structure/closet/crate/necropolis/tendril(loc) - collector.start_pulling(loot) - collected += WEAKREF(collector) - -/obj/effect/collapse/Destroy() - collected.Cut() - QDEL_NULL(emitted_light) - return ..() - -///Helper proc that resolves weakrefs to determine if collector is in collected list, returning a boolean. -/obj/effect/collapse/proc/has_collected(mob/collector) - for(var/datum/weakref/weakref as anything in collected) - var/mob/living/resolved = weakref.resolve() - //it could have been collector, it could not have been, we don't care - if(!resolved) - continue - if(resolved == collector) - return TRUE - return FALSE - -/obj/effect/collapse/proc/collapse() - for(var/mob/M in range(7,src)) - shake_camera(M, 15, 1) - playsound(get_turf(src),'sound/effects/explosion/explosionfar.ogg', 200, TRUE) - visible_message(span_bolddanger("The tendril falls inward, the ground around it widening into a yawning chasm!")) - for(var/turf/T in RANGE_TURFS(2,src)) - if(HAS_TRAIT(T, TRAIT_NO_TERRAFORM)) - continue - if(!T.density) - T.TerraformTurf(/turf/open/chasm/lavaland, /turf/open/chasm/lavaland, flags = CHANGETURF_INHERIT_AIR) - qdel(src) diff --git a/code/game/objects/structures/lavaland/ore_vent.dm b/code/game/objects/structures/lavaland/ore_vent.dm index f4ef87a2c09..244e88102be 100644 --- a/code/game/objects/structures/lavaland/ore_vent.dm +++ b/code/game/objects/structures/lavaland/ore_vent.dm @@ -1,4 +1,4 @@ -#define MAX_ARTIFACT_ROLL_CHANCE 10 +#define ARTIFACT_ROLL_CHANCE 7 #define MINERAL_TYPE_OPTIONS_RANDOM 4 #define OVERLAY_OFFSET_START 0 #define OVERLAY_OFFSET_EACH 5 @@ -72,7 +72,7 @@ /// What base icon_state do we use for this vent's boulders? var/boulder_icon_state = "boulder" /// Percent chance that this vent will produce an artifact boulder. - var/artifact_chance = 0 + var/artifact_chance = ARTIFACT_ROLL_CHANCE /// We use a cooldown to prevent the wave defense from being started multiple times. COOLDOWN_DECLARE(wave_cooldown) /// We use a cooldown to prevent players from tapping boulders rapidly from vents. @@ -140,6 +140,7 @@ . = ..() if(HAS_TRAIT(user, TRAIT_BOULDER_BREAKER)) produce_boulder(TRUE) + return TRUE /obj/structure/ore_vent/is_buckle_possible(mob/living/target, force, check_loc) . = ..() @@ -160,6 +161,8 @@ . += span_notice("This vent produces [span_bold("large")] boulders containing [ore_string]") else . += span_notice("This vent can be scanned with a [span_bold("Mining Scanner")].") + if(artifact_chance) + . += span_notice("This vent has a low chance to produce an [span_bold("artifact boulder.")] These may contain rare minerals or strange artifacts.") /obj/structure/ore_vent/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) if(is_type_in_list(held_item, scanning_equipment)) @@ -221,8 +224,8 @@ * This also means a large boulder can highroll a boulder with a full stack of 50 sheets of material. * @params ore_floor The number of minerals already rolled. Used to scale the logarithmic function. */ -/obj/structure/ore_vent/proc/ore_quantity_function(ore_floor) - return SHEET_MATERIAL_AMOUNT * max(round(boulder_size * (log(rand(1 + ore_floor, 4 + ore_floor)) ** -1)), 1) +/obj/structure/ore_vent/proc/ore_quantity_function(ore_floor, ore_per_size = HALF_SHEET_MATERIAL_AMOUNT) + return ore_per_size * max(round(boulder_size * (log(rand(1 + ore_floor, 4 + ore_floor)) ** -1)), 1) /** * This confirms that the user wants to start the wave defense event, and that they can start it. @@ -357,7 +360,7 @@ miner.mind?.adjust_experience(/datum/skill/mining, MINING_SKILL_BOULDER_SIZE_XP * boulder_size) if(!user_id_card) continue - var/point_reward_val = (MINER_POINT_MULTIPLIER * boulder_size) - MINER_POINT_MULTIPLIER // We remove the base value of discovering the vent + var/point_reward_val = (MINER_POINT_MULTIPLIER * (boulder_size + 2)) - MINER_POINT_MULTIPLIER // We remove the base value of discovering the vent if(user_id_card.registered_account) user_id_card.registered_account.mining_points += point_reward_val user_id_card.registered_account.bank_card_talk("You have been awarded [point_reward_val] mining points for your efforts.") @@ -525,6 +528,11 @@ var/atom/movable/flick_visual/visual = flick_overlay_view(mutable_appearance('icons/effects/vent_overlays.dmi', selected_mat.name), 4.5 SECONDS) animate(visual, alpha = 0, time = 4.5 SECONDS, easing = CIRCULAR_EASING|EASE_IN) + if(artifact_chance) + var/atom/movable/flick_visual/rare = flick_overlay_view(mutable_appearance('icons/effects/vent_overlays.dmi', "rare_ore"), 4.5 SECONDS) + animate(rare, alpha = 0, time = 4.5 SECONDS, easing = CIRCULAR_EASING|EASE_IN) + + /** * Here is where we handle producing a new boulder, based on the qualities of this ore vent. * Returns the boulder produced. @@ -540,7 +548,8 @@ //produce the boulder var/obj/item/boulder/new_rock if(prob(artifact_chance)) - new_rock = new /obj/item/boulder/artifact(loc) + var/picked_artifact = pick(typesof(/obj/item/boulder/artifact)) + new_rock = new picked_artifact(loc) else new_rock = new /obj/item/boulder(loc) Shake(duration = 1.5 SECONDS) @@ -645,6 +654,10 @@ /datum/material/glass = 1, ) +/obj/structure/ore_vent/starter_resources/Initialize(mapload) + . = ..() + generate_description() + /obj/structure/ore_vent/random // Todo: determine if we need a boulder_size default thats unique from the override performed in vent_size_setup. @@ -653,7 +666,6 @@ if(!unique_vent && !mapload) generate_mineral_breakdown(map_loading = mapload) //Default to random mineral breakdowns, unless this is a unique vent or we're still setting up default vent distribution. generate_description() - artifact_chance = rand(0, MAX_ARTIFACT_ROLL_CHANCE) if(!mapload) vent_size_setup(random = TRUE) // We only do this here specific to random distribution ore vents, and within mapload we handle this manually within SSore_generation. @@ -699,9 +711,9 @@ /datum/material/titanium = 1, /datum/material/silver = 1, /datum/material/gold = 1, - /datum/material/diamond = 1, + /datum/material/diamond = 0.1, /datum/material/uranium = 1, - /datum/material/bluespace = 1, + /datum/material/bluespace = 0.1, /datum/material/plastic = 1, ) defending_mobs = list( @@ -758,6 +770,41 @@ /mob/living/simple_animal/hostile/megafauna/colossus, ) +/obj/structure/ore_vent/debug + name = "debug ore vent" + desc = "How the hell did you get this?." + tapped = TRUE + discovered = TRUE + unique_vent = TRUE + color = "#ff00f2" + boulder_size = BOULDER_SIZE_SMALL + mineral_breakdown = list( + /datum/material/iron = 1, + ) + +/obj/structure/ore_vent/debug/attack_hand(mob/living/user, list/modifiers) + . = ..() + var/datum/material/choice = tgui_input_list(user, "Choose a material to add/remove.", "New material", subtypesof(/datum/material)) + if(!choice) + return + if(mineral_breakdown[choice]) + mineral_breakdown -= choice + balloon_alert_to_viewers("removed [choice::name]") + return + mineral_breakdown += choice + balloon_alert_to_viewers("added [choice::name]") + var/value = tgui_input_number(user, "What weight should it have?", "ore pickweight", 1, 100, 1) + mineral_breakdown[choice] = value + balloon_alert_to_viewers("weighting of [value] added") + generate_description() + +/obj/structure/ore_vent/debug/attack_hand_secondary(mob/user, list/modifiers) + . = ..() + var/choice = tgui_input_list(user, "Choose a vent size.", "New size", list(SMALL_VENT_TYPE, MEDIUM_VENT_TYPE, LARGE_VENT_TYPE)) + if(!choice) + return + vent_size_setup(random = FALSE, force_size = choice, map_loading = FALSE) + /obj/effect/landmark/mining_center name = "Mining Epicenter" icon_state = "mining_epicenter" @@ -772,7 +819,7 @@ GLOB.mining_center += loc return INITIALIZE_HINT_QDEL -#undef MAX_ARTIFACT_ROLL_CHANCE +#undef ARTIFACT_ROLL_CHANCE #undef MINERAL_TYPE_OPTIONS_RANDOM #undef OVERLAY_OFFSET_START #undef OVERLAY_OFFSET_EACH diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index 4b2ba45770c..548cc1d8f80 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -15,6 +15,9 @@ #define PRIDE_MIRROR_OPTIONS list(CHANGE_HAIR, CHANGE_BEARD, CHANGE_RACE, CHANGE_SEX, CHANGE_EYES) #define MAGIC_MIRROR_OPTIONS list(CHANGE_HAIR, CHANGE_BEARD, CHANGE_RACE, CHANGE_SEX, CHANGE_EYES, CHANGE_NAME) +// Chance for the mirror to be haunted at creation +#define ROUNDSTART_CURSED_CHANCE 0.2 + /obj/structure/mirror name = "mirror" desc = "Mirror mirror on the wall, who's the most robust of them all?" @@ -29,7 +32,8 @@ ///Can this mirror be removed from walls with tools? var/deconstructable = TRUE var/list/mirror_options = INERT_MIRROR_OPTIONS - + // Can a revenant be imprisoned in this mirror? + var/cursable = TRUE ///Flags this race must have to be selectable with this type of mirror. var/race_flags = MIRROR_MAGIC ///List of all Races that can be chosen, decided by its Initialize. @@ -57,6 +61,8 @@ ) if(mapload) find_and_mount_on_atom() + if(prob(ROUNDSTART_CURSED_CHANCE) && cursable) + AddComponent(/datum/component/revenant_prison, create_on_release = TRUE) update_choices() register_context() @@ -72,10 +78,12 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror, 28) /obj/structure/mirror/broken icon_state = "mirror_broke" + cursable = FALSE + broken = TRUE + desc = "Oh no, seven years of bad luck!" /obj/structure/mirror/broken/Initialize(mapload) . = ..() - atom_break(null, mapload) MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror/broken, 28) @@ -262,7 +270,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror/broken, 28) return user.set_eye_color(sanitize_hexcolor(new_eye_color)) user.dna.update_ui_block(/datum/dna_block/identity/eye_colors) - user.update_body() + user.update_eyes() to_chat(user, span_notice("You gaze at your new eyes with your new eyes. Perfect!")) /obj/structure/mirror/examine(mob/user) @@ -302,13 +310,12 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror/broken, 28) to_chat(unlucky_dude, span_warning("A chill runs down your spine as [src] shatters...")) unlucky_dude.AddComponent(/datum/component/omen, incidents_left = 7) -/obj/structure/mirror/atom_break(damage_flag, mapload) +/obj/structure/mirror/atom_break(damage_flag) . = ..() if(broken) return icon_state = "mirror_broke" - if(!mapload) - playsound(src, SFX_SHATTER, 70, TRUE) + playsound(src, SFX_SHATTER, 70, TRUE) if(desc == initial(desc)) desc = "Oh no, seven years of bad luck!" broken = TRUE @@ -361,6 +368,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror/broken, 28) icon_state = "magic_mirror" mirror_options = MAGIC_MIRROR_OPTIONS deconstructable = FALSE + cursable = FALSE /obj/structure/mirror/magic/Initialize(mapload) . = ..() @@ -463,3 +471,5 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror/broken, 28) #undef INERT_MIRROR_OPTIONS #undef PRIDE_MIRROR_OPTIONS #undef MAGIC_MIRROR_OPTIONS + +#undef ROUNDSTART_CURSED_CHANCE diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index 0848cfecc37..82485224ad6 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -463,35 +463,28 @@ GLOBAL_LIST_EMPTY(crematoriums) /obj/structure/bodycontainer/crematorium/proc/cremate(mob/user) if(locked) return //don't let you cremate something twice or w/e + // Make sure we don't delete the actual morgue and its tray var/list/conts = get_all_contents() - src - connected - - if(!conts.len) + if(!length(conts)) audible_message(span_hear("You hear a hollow crackle.")) return - else - audible_message(span_hear("You hear a roar as the crematorium activates.")) + audible_message(span_hear("You hear a roar as the crematorium activates.")) + locked = TRUE + update_appearance() - locked = TRUE - update_appearance() + for(var/mob/living/victim in conts) + if(victim.incorporeal_move) //can't cook revenants! + continue - for(var/mob/living/M in conts) - if(M.incorporeal_move) //can't cook revenants! - continue - if (M.stat != DEAD) - M.emote("scream") - if(user) - log_combat(user, M, "cremated") - else - M.log_message("was cremated", LOG_ATTACK) + if (victim.stat != DEAD) + victim.emote("scream") - if(user.stat != DEAD) - user.investigate_log("has died from being cremated.", INVESTIGATE_DEATHS) - M.death(TRUE) - if(!QDELETED(M)) //some animals get automatically deleted on death. - M.ghostize() - qdel(M) + if(user) + log_combat(user, victim, "cremated") + else + victim.log_message("was cremated", LOG_ATTACK) for(var/obj/O in conts) //conts defined above, ignores crematorium and tray // SKYRAT EDIT ADDITION @@ -502,15 +495,32 @@ GLOBAL_LIST_EMPTY(crematoriums) continue qdel(O) - if(!locate(/obj/effect/decal/cleanable/ash) in get_step(src, dir))//prevent pile-up - new/obj/effect/decal/cleanable/ash(src) + if(user.stat != DEAD) + user.investigate_log("has died from being cremated.", INVESTIGATE_DEATHS) - sleep(3 SECONDS) + victim.death(TRUE) + if(!QDELETED(victim)) //some animals get automatically deleted on death. + victim.ghostize() + qdel(victim) - if(!QDELETED(src)) - locked = FALSE - update_appearance() - playsound(src.loc, 'sound/machines/ding.ogg', 50, TRUE) //you horrible people + for(var/obj/to_destroy in conts) // conts defined above, ignores crematorium and tray + // Indestructible atoms should not be destroyed + if(istype(to_destroy, /obj/effect/dummy/phased_mob) || (to_destroy.resistance_flags & INDESTRUCTIBLE)) + continue + qdel(to_destroy) + + addtimer(CALLBACK(src, PROC_REF(unlock)), 3 SECONDS) + +/obj/structure/bodycontainer/crematorium/proc/unlock() + if(QDELETED(src)) + return + + if(!locate(/obj/effect/decal/cleanable/ash) in get_step(src, dir)) // As to prevent pile-up + new /obj/effect/decal/cleanable/ash(src) + + locked = FALSE + update_appearance() + playsound(src.loc, 'sound/machines/ding.ogg', 50, TRUE) // You horrible people /obj/structure/bodycontainer/crematorium/creamatorium name = "creamatorium" @@ -584,8 +594,8 @@ GLOBAL_LIST_EMPTY(crematoriums) if(!istype(O, /obj/structure/closet/body_bag)) return else - var/mob/M = O - if(M.buckled) + var/mob/victim = O + if(victim.buckled) return O.forceMove(src.loc) if (user != O) diff --git a/code/game/objects/structures/mystery_box.dm b/code/game/objects/structures/mystery_box.dm index 7b71200fb47..28700113381 100644 --- a/code/game/objects/structures/mystery_box.dm +++ b/code/game/objects/structures/mystery_box.dm @@ -77,6 +77,7 @@ GLOBAL_LIST_INIT(mystery_magic, list( /obj/item/gun/magic/wand/door, /obj/item/gun/magic/wand/nothing, /obj/item/storage/belt/wands/full, + /obj/item/storage/belt/wands/full/discount, /obj/item/gun/magic/staff/healing, /obj/item/gun/magic/staff/chaos, /obj/item/gun/magic/staff/door, diff --git a/code/game/objects/structures/petrified_statue.dm b/code/game/objects/structures/petrified_statue.dm index e6327a1a811..1f4f76c6768 100644 --- a/code/game/objects/structures/petrified_statue.dm +++ b/code/game/objects/structures/petrified_statue.dm @@ -8,7 +8,7 @@ ///Should we leave a brain behind when the statue is wrecked? var/brain = TRUE ///Time left before the petrification ends and we let the mob free - var/timer = 48 SECONDS + var/timer = 8 MINUTES ///The mob that got medusa'd var/mob/living/petrified_mob @@ -37,7 +37,7 @@ /obj/structure/statue/petrified/process(seconds_per_tick) if(!petrified_mob) STOP_PROCESSING(SSobj, src) - timer -= seconds_per_tick + timer -= seconds_per_tick SECONDS petrified_mob.Stun(4 SECONDS) //So they can't do anything while petrified if(timer <= 0) STOP_PROCESSING(SSobj, src) diff --git a/code/game/objects/structures/signboards/_signboard.dm b/code/game/objects/structures/signboards/_signboard.dm new file mode 100644 index 00000000000..307993a52d8 --- /dev/null +++ b/code/game/objects/structures/signboards/_signboard.dm @@ -0,0 +1,213 @@ +#define INVESTIGATE_SIGNBOARD "signboard" +#define SIGNBOARD_WIDTH (ICON_SIZE_X * 3.5) +#define SIGNBOARD_HEIGHT (ICON_SIZE_Y * 2.5) +#define MAX_SIGN_LEN 106 + +/obj/structure/signboard + name = "sign" + desc = "A foldable sign." + icon = 'icons/obj/signboards.dmi' + icon_state = "sign" + base_icon_state = "sign" + density = TRUE + anchored = TRUE + interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND | INTERACT_ATOM_REQUIRES_DEXTERITY + custom_materials = list(/datum/material/wood = SHEET_MATERIAL_AMOUNT * 5) + /// The image holding this sign's text + var/image/text_image + /// The current text written on the sign + var/sign_text + /// The maximum length of text that can be input onto the sign. + var/max_length = MAX_SIGN_LEN + /// If true, the text cannot be changed by players. + var/locked = FALSE + /// If text should be shown while unanchored. + var/show_while_unanchored = FALSE + /// If TRUE, the sign can be edited without a pen. + var/edit_by_hand = FALSE + +/obj/structure/signboard/Initialize(mapload) + . = ..() + if(sign_text) + set_text(sign_text, force = TRUE) + investigate_log("had its text set on load to \"[sign_text]\"", INVESTIGATE_SIGNBOARD) + update_appearance() + register_context() + +/obj/structure/signboard/Destroy(force) + QDEL_NULL(text_image) + return ..() + +/obj/structure/signboard/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = ..() + if(is_locked(user)) + return + if(held_item?.tool_behaviour == TOOL_WRENCH) + context[SCREENTIP_CONTEXT_LMB] = anchored ? "Unsecure" : "Secure" + return CONTEXTUAL_SCREENTIP_SET + if((edit_by_hand || istype(held_item, /obj/item/pen)) && (anchored || show_while_unanchored)) + context[SCREENTIP_CONTEXT_LMB] = "Set Displayed Text" + if(sign_text) + context[SCREENTIP_CONTEXT_ALT_RMB] = "Clear Sign" + return CONTEXTUAL_SCREENTIP_SET + +/obj/structure/signboard/examine(mob/user) + . = ..() + if(!edit_by_hand) + . += span_notice("You can write on the sign with a pen.") + if(anchored) + . += span_notice("It's secured to the floor, you could use a wrench to unsecure and move it.") + else + . += span_notice("It's unsecured, you could use a wrench to secure it in place.") + if(sign_text) + . += span_boldnotice("\nIt currently displays the following:") + . += span_info(html_encode(sign_text)) + else + . += span_notice("\nIt's blank.") + +/obj/structure/signboard/update_icon_state() + . = ..() + icon_state = "[base_icon_state][sign_text ? "" : "_blank"]" + +/obj/structure/signboard/vv_edit_var(var_name, var_value) + if(var_name == NAMEOF(src, sign_text)) + if(!set_text(var_value, force = TRUE)) + return FALSE + datum_flags |= DF_VAR_EDITED + return TRUE + return ..() + +/obj/structure/signboard/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!istype(tool, /obj/item/pen)) + return NONE + try_set_text(user) + return ITEM_INTERACT_SUCCESS + +/obj/structure/signboard/attack_hand(mob/living/user, list/modifiers) + . = ..() + if(.) + return + if(!edit_by_hand && !user.is_holding_item_of_type(/obj/item/pen)) + balloon_alert(user, "need a pen!") + return TRUE + if(try_set_text(user)) + return TRUE + +/obj/structure/signboard/proc/try_set_text(mob/living/user) + . = FALSE + if(!anchored && !show_while_unanchored) + return FALSE + if(check_locked(user)) + return FALSE + var/new_text = tgui_input_text( + user, + message = "What would you like to set this sign's text to?", + title = full_capitalize(name), + default = sign_text, + max_length = max_length, + multiline = TRUE, + encode = FALSE, + ) + if(QDELETED(src) || !new_text || check_locked(user)) + return FALSE + var/list/filter_result = CAN_BYPASS_FILTER(user) ? null : is_ic_filtered(new_text) + if(filter_result) + REPORT_CHAT_FILTER_TO_USER(user, filter_result) + return FALSE + var/list/soft_filter_result = CAN_BYPASS_FILTER(user) ? null : is_soft_ic_filtered(new_text) + if(soft_filter_result) + if(tgui_alert(user, "Your message contains \"[soft_filter_result[CHAT_FILTER_INDEX_WORD]]\". \"[soft_filter_result[CHAT_FILTER_INDEX_REASON]]\", Are you sure you want to say it?", "Soft Blocked Word", list("Yes", "No")) != "Yes") + return FALSE + message_admins("[ADMIN_LOOKUPFLW(user)] has passed the soft filter for \"[soft_filter_result[CHAT_FILTER_INDEX_WORD]]\" when writing to the sign at [ADMIN_VERBOSEJMP(src)], they may be using a disallowed term. Sign text: \"[html_encode(new_text)]\"") + log_admin_private("[key_name(user)] has passed the soft filter for \"[soft_filter_result[CHAT_FILTER_INDEX_WORD]]\" when writing to the sign at [loc_name(src)], they may be using a disallowed term. Sign text: \"[new_text]\"") + if(set_text(new_text)) + balloon_alert(user, "set text") + investigate_log("([key_name(user)]) set text to \"[sign_text || "(none)"]\"", INVESTIGATE_SIGNBOARD) + return TRUE + +/obj/structure/signboard/click_alt_secondary(mob/user) + . = ..() + if(!sign_text || !can_interact(user) || !user.can_perform_action(src, NEED_DEXTERITY)) + return + if(!edit_by_hand && !user.is_holding_item_of_type(/obj/item/pen)) + balloon_alert(user, "need a pen!") + return + if(check_locked(user)) + return + if(set_text(null)) + balloon_alert(user, "cleared text") + investigate_log("([key_name(user)]) cleared the text", INVESTIGATE_SIGNBOARD) + +/obj/structure/signboard/wrench_act(mob/living/user, obj/item/tool) + . = ..() + if(!anchored || !check_locked(user)) + default_unfasten_wrench(user, tool) + return ITEM_INTERACT_SUCCESS + +/obj/structure/signboard/on_changed_z_level(turf/old_turf, turf/new_turf, same_z_layer, notify_contents) + if(!same_z_layer) + SET_PLANE_EXPLICIT(text_image, ABOVE_GAME_PLANE, src) + return ..() + +/obj/structure/signboard/set_anchored(anchorvalue) + . = ..() + update_text() + +/obj/structure/signboard/proc/is_locked(mob/user) + if(isAdminGhostAI(user)) + return FALSE + return locked + +/obj/structure/signboard/proc/check_locked(mob/user, silent = FALSE) + . = is_locked(user) + if(. && !silent) + balloon_alert(user, "locked!") + +/obj/structure/signboard/proc/should_display_text() + if(QDELETED(src) || !isturf(loc) || !sign_text) + return FALSE + if(!anchored && !show_while_unanchored) + return FALSE + return TRUE + +/obj/structure/signboard/MouseEntered(location, control, params) + . = ..() + if(QDELETED(src) || !should_display_text()) + return + usr.client.images |= text_image + +/obj/structure/signboard/MouseExited(location, control, params) + . = ..() + usr.client.images -= text_image + +/// Creates [text_image] if it doesn't exist, and sets its maptext to [sign_text] +/obj/structure/signboard/proc/update_text() + PROTECTED_PROC(TRUE) // Use set_text instead + var/safe_width = src.bound_width || ICON_SIZE_X + var/safe_height = src.bound_height || ICON_SIZE_Y + var/text_html = MAPTEXT_GRAND9K("[html_encode(sign_text)]") + if(!text_image) + text_image = new + SET_PLANE_EXPLICIT(text_image, ABOVE_GAME_PLANE, src) + text_image.alpha = 192 + text_image.loc = src + text_image.maptext_x = (SIGNBOARD_WIDTH - safe_width) * -0.5 + text_image.maptext_y = safe_height + text_image.maptext_width = SIGNBOARD_WIDTH + text_image.maptext_height = SIGNBOARD_HEIGHT + text_image.maptext = text_html + +/obj/structure/signboard/proc/set_text(new_text, force = FALSE) + . = FALSE + if(QDELETED(src) || (locked && !force)) + return + if(!istext(new_text) && !isnull(new_text)) + CRASH("Attempted to set invalid signtext: [new_text]") + . = TRUE + sign_text = trim(new_text, max_length) + update_text() + update_appearance() + +#undef MAX_SIGN_LEN +#undef SIGNBOARD_HEIGHT +#undef SIGNBOARD_WIDTH diff --git a/code/game/objects/structures/signboards/holosign.dm b/code/game/objects/structures/signboards/holosign.dm new file mode 100644 index 00000000000..2c5c074d127 --- /dev/null +++ b/code/game/objects/structures/signboards/holosign.dm @@ -0,0 +1,239 @@ +/obj/structure/signboard/holosign + name = "holographic sign" + desc = "A holographic signboard, projecting text above it." + icon_state = "holographic_sign" + base_icon_state = "holographic_sign" + layer = ABOVE_MOB_LAYER + density = FALSE + edit_by_hand = TRUE + show_while_unanchored = TRUE + light_range = MINIMUM_USEFUL_LIGHT_RANGE + light_power = 0.3 + light_color = COLOR_CARP_TEAL + light_on = FALSE + custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 5.05, /datum/material/glass = SMALL_MATERIAL_AMOUNT * 0.7) + /// If set, only IDs with this name can (un)lock the sign. + var/registered_owner + /// The current color of the sign. + /// The sign will be greyscale if this is set. + var/current_color + +/obj/structure/signboard/holosign/Initialize(mapload) + . = ..() + if(current_color) + INVOKE_ASYNC(src, PROC_REF(set_color), current_color) + AddComponent(/datum/component/usb_port, list( + /obj/item/circuit_component/holo_signboard, + )) + +/obj/structure/signboard/holosign/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = ..() + var/locked = is_locked(user) + if(istype(held_item, /obj/item/card/emag)) + context[SCREENTIP_CONTEXT_LMB] = "Short Out Locking Mechanisms" + . = CONTEXTUAL_SCREENTIP_SET + else if(!locked && istype(held_item?.GetID(), /obj/item/usb_cable)) + context[SCREENTIP_CONTEXT_LMB] = "Connect USB Cable" + else if(!locked && istype(held_item?.GetID(), /obj/item/card/id)) + context[SCREENTIP_CONTEXT_LMB] = registered_owner ? "Remove ID Lock" : "Lock To ID" + . = CONTEXTUAL_SCREENTIP_SET + if(!locked) + context[SCREENTIP_CONTEXT_RMB] = "Set Sign Color" + . = CONTEXTUAL_SCREENTIP_SET + +/obj/structure/signboard/holosign/update_icon_state() + base_icon_state = current_color ? "[initial(base_icon_state)]_greyscale" : initial(base_icon_state) + . = ..() + if(obj_flags & EMAGGED) + icon_state += "_emag" + +/obj/structure/signboard/holosign/examine(mob/user) + . = ..() + if(obj_flags & EMAGGED) + . += span_warning("
Its locking mechanisms appear to be shorted out!") + else if(registered_owner) + . += span_info("
It is locked to the ID of [span_name(registered_owner)].") + +/obj/structure/signboard/holosign/update_overlays() + . = ..() + if(sign_text) + . += emissive_appearance(icon, "holographic_sign_e", src) + +/obj/structure/signboard/holosign/vv_edit_var(var_name, var_value) + if(var_name == NAMEOF(src, color) || var_name == NAMEOF(src, current_color)) + INVOKE_ASYNC(src, PROC_REF(set_color), var_value) + datum_flags |= DF_VAR_EDITED + return TRUE + return ..() + +/obj/structure/signboard/holosign/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + var/obj/item/item = astype(tool, /obj/item) + var/obj/item/card/id/id = item?.GetID() + if(!istype(id) || !can_interact(user) || !user.can_perform_action(src, NEED_DEXTERITY)) + return NONE + + var/trimmed_id_name = trimtext(id.registered_name) + if(!trimmed_id_name) + balloon_alert(user, "no name on id!") + return ITEM_INTERACT_BLOCKING + if(obj_flags & EMAGGED) + balloon_alert(user, "lock shorted out!") + return ITEM_INTERACT_BLOCKING + if(registered_owner) + if(!check_locked(user)) + registered_owner = null + balloon_alert(user, "id lock removed") + investigate_log("([key_name(user)]) removed id lock", INVESTIGATE_SIGNBOARD) + else + registered_owner = trimmed_id_name + balloon_alert(user, "locked to id") + investigate_log("([key_name(user)]) added id lock for \"[registered_owner]\"", INVESTIGATE_SIGNBOARD) + update_appearance() + return ITEM_INTERACT_SUCCESS + +/obj/structure/signboard/holosign/is_locked(mob/living/user) + . = ..() + if(.) + return + if(registered_owner && isliving(user)) + var/obj/item/card/id/id = user.get_idcard() + if(!istype(id) || QDELING(id)) + return TRUE + return !cmptext(trimtext(id.registered_name), registered_owner) + +/obj/structure/signboard/holosign/set_text(new_text, force) + . = ..() + set_light(l_on = !!sign_text) + +/obj/structure/signboard/holosign/attack_hand_secondary(mob/user, list/modifiers) + . = ..() + if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) + return + if(try_set_color(user)) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + +/obj/structure/signboard/holosign/proc/try_set_color(mob/user) + . = TRUE + if(!can_interact(user) || !user.can_perform_action(src, NEED_DEXTERITY)) + return FALSE + if(check_locked(user)) + return + var/new_color = sanitize_color(tgui_color_picker(user, "Set Sign Color", full_capitalize(name), current_color)) + if(new_color && is_color_dark_with_saturation(new_color, 25)) + balloon_alert(user, "color too dark!") + return + if(check_locked(user)) + return + INVOKE_ASYNC(src, PROC_REF(set_color), new_color) + if(new_color) + balloon_alert(user, "set color to [new_color]") + investigate_log("([key_name(user)]) set the color to [new_color || "(none)"]", INVESTIGATE_SIGNBOARD) + else + balloon_alert(user, "unset color") + investigate_log("([key_name(user)]) cleared the color", INVESTIGATE_SIGNBOARD) + +/obj/structure/signboard/holosign/emag_act(mob/user, obj/item/card/emag/emag_card) + if(obj_flags & EMAGGED) + return FALSE + playsound(src, SFX_SPARKS, vol = 100, vary = TRUE, extrarange = SHORT_RANGE_SOUND_EXTRARANGE) + do_sparks(3, cardinal_only = FALSE, source = src) + balloon_alert(user, "lock broken") + investigate_log("was emagged by [key_name(user)] (previous owner: [registered_owner || "(none)"])", INVESTIGATE_SIGNBOARD) + registered_owner = null + obj_flags |= EMAGGED + update_appearance() + +/obj/structure/signboard/holosign/proc/sanitize_color(color) + . = sanitize_hexcolor(color) + if(!. || . == COLOR_BLACK) + return null + +/obj/structure/signboard/holosign/proc/set_color(new_color) + new_color = sanitize_color(new_color) + if(!new_color) + current_color = null + remove_atom_colour(FIXED_COLOUR_PRIORITY) + else + current_color = new_color + add_atom_colour(new_color, FIXED_COLOUR_PRIORITY) + set_light(l_color = current_color || src::light_color) + update_appearance() + +/obj/item/circuit_component/holo_signboard + display_name = "Holographic Signboard" + desc = "Output text to a signboard, insert
in the message field to linebreak. Set the color to 0, 0, 0 to reset to default." + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + + var/datum/port/input/message + var/datum/port/input/clear + + var/datum/port/output/fail_reason + var/datum/port/output/on_fail + + var/datum/port/input/red + var/datum/port/input/green + var/datum/port/input/blue + var/datum/port/input/set_color + + var/obj/structure/signboard/holosign/connected_display + +/obj/item/circuit_component/holo_signboard/populate_ports() + message = add_input_port("Message", PORT_TYPE_STRING) + clear = add_input_port("Clear", PORT_TYPE_SIGNAL, trigger = PROC_REF(clear_received)) + + fail_reason = add_output_port("Fail Reason", PORT_TYPE_STRING) + on_fail = add_output_port("Failed", PORT_TYPE_SIGNAL) + + red = add_input_port("Red", PORT_TYPE_NUMBER) + green = add_input_port("Green", PORT_TYPE_NUMBER) + blue = add_input_port("Blue", PORT_TYPE_NUMBER) + set_color = add_input_port("Set Color", PORT_TYPE_SIGNAL, trigger = PROC_REF(color_received)) + +/obj/item/circuit_component/holo_signboard/register_usb_parent(atom/movable/shell) + . = ..() + if(istype(shell, /obj/structure/signboard/holosign)) + connected_display = shell + +/obj/item/circuit_component/holo_signboard/input_received(datum/port/input/port) + if(!connected_display) + return + if(length(message.value) > connected_display.max_length) //5000 is a hell of a lot longer than 144. + fail_reason.set_output("Too long ([length(message.value)]/[connected_display.max_length]).") + on_fail.set_output(COMPONENT_SIGNAL) + return + if(is_ic_filtered(message.value)) + fail_reason.set_output("Prohibited content.") + on_fail.set_output(COMPONENT_SIGNAL) + return + + var/edited_message = replacetextEx_char(message.value, "
", "\n") + if(connected_display.set_text(edited_message)) + investigate_log("Circuit USB ([parent.get_creator()]) set text to \"[connected_display.sign_text || "(none)"]\"", INVESTIGATE_SIGNBOARD) + if(is_soft_ic_filtered(message.value)) + message_admins("A circuit component (by [parent.get_creator_admin()]) added a soft filtered message to a signboard. [ADMIN_COORDJMP(src)]") + else + fail_reason.set_output("Connection refused by external endpoint.") + on_fail.set_output(COMPONENT_SIGNAL) + +/obj/item/circuit_component/holo_signboard/proc/clear_received(datum/port/input/port) + if(!connected_display.set_text(null)) + fail_reason.set_output("Connection refused by external endpoint.") + on_fail.set_output(COMPONENT_SIGNAL) + +/obj/item/circuit_component/holo_signboard/proc/color_received(datum/port/input/port) + red.set_value(clamp(red.value, 0, 255)) + blue.set_value(clamp(blue.value, 0, 255)) + green.set_value(clamp(green.value, 0, 255)) + var/signboard_color = rgb(red.value, green.value, blue.value) + if(signboard_color && signboard_color != rgb(0, 0, 0) && is_color_dark_with_saturation(signboard_color, 25)) + fail_reason.set_output("Color too dark to display.") + on_fail.set_output(COMPONENT_SIGNAL) + return + connected_display.set_color(signboard_color) //doesnt have a return so no need to check and error + investigate_log("Circuit USB ([parent.get_creator()]) set the color to [signboard_color || "(none)"]", INVESTIGATE_SIGNBOARD) + +/// Given a color in the format of "#RRGGBB", will return if the color +/// is dark. Value is mixed with Saturation and Brightness from HSV. +/proc/is_color_dark_with_saturation(color, threshold = 25) + var/hsl = rgb2num(color, COLORSPACE_HSL) + return hsl[3] < threshold diff --git a/code/game/objects/structures/signs/signs_interactive.dm b/code/game/objects/structures/signs/signs_interactive.dm index 5ef9031fef9..49ae5ba6c29 100644 --- a/code/game/objects/structures/signs/signs_interactive.dm +++ b/code/game/objects/structures/signs/signs_interactive.dm @@ -1,14 +1,15 @@ /obj/structure/sign/clock name = "wall clock" - desc = "It's your run-of-the-mill wall clock showing both the local Coalition Standard Time and the galactic Treaty Coordinated Time. Perfect for staring at instead of working." + desc = "It's your run-of-the-mill wall clock showing both the local Nanotrasen Standard Time and the galactic Treaty Coordinated Time. Perfect for staring at instead of working." icon_state = "clock" MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sign/clock, 32) /obj/structure/sign/clock/examine(mob/user) . = ..() - . += span_info("The current CST (local) time is: [station_time_timestamp()].") - . += span_info("The current TCT (galactic) time is: [time2text(world.realtime, "hh:mm:ss", 0)].") + . += span_info("The current NST (local) time is: [server_timestamp(ic_time = TRUE, twelve_hour_clock = user.client?.prefs.read_preference(/datum/preference/toggle/twelve_hour))].") + if(user.is_literate()) + . += span_info("That means it is currently [round_timestamp()] into the shift.") /obj/structure/sign/calendar name = "wall calendar" diff --git a/code/game/objects/structures/toiletbong.dm b/code/game/objects/structures/toiletbong.dm index 72549bdbcc7..93e54886e6e 100644 --- a/code/game/objects/structures/toiletbong.dm +++ b/code/game/objects/structures/toiletbong.dm @@ -95,7 +95,7 @@ return FALSE new /obj/item/flamethrower(get_turf(src)) var/obj/item/tank/internals/plasma/ptank = new /obj/item/tank/internals/plasma(get_turf(src)) - ptank.air_contents.gases[/datum/gas/plasma][MOLES] = (0) + ptank.air_contents.set_gas(/datum/gas/plasma, 0) drop_custom_materials() qdel(src) return TRUE diff --git a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm index fe806662dac..30ea69ff0d4 100644 --- a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm +++ b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm @@ -14,9 +14,8 @@ /obj/structure/transit_tube_pod/Initialize(mapload) . = ..() - air_contents.add_gases(/datum/gas/oxygen, /datum/gas/nitrogen) - air_contents.gases[/datum/gas/oxygen][MOLES] = MOLES_O2STANDARD - air_contents.gases[/datum/gas/nitrogen][MOLES] = MOLES_N2STANDARD + var/list/new_gases = list(/datum/gas/oxygen = MOLES_O2STANDARD, /datum/gas/nitrogen = MOLES_N2STANDARD) + air_contents.adjust_multiple_gases(new_gases) air_contents.temperature = T20C /obj/structure/transit_tube_pod/Destroy() diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 0c97edf906e..cdfae783ccb 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -849,17 +849,12 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/window/reinforced/tinted/frosted/spaw flags_1 = PREVENT_CLICK_UNDER_1 resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF -/obj/structure/window/reinforced/shuttle/indestructible/welder_act(mob/living/user, obj/item/tool) - return NONE - -/obj/structure/window/reinforced/shuttle/indestructible/screwdriver_act(mob/living/user, obj/item/tool) - return NONE - -/obj/structure/window/reinforced/shuttle/indestructible/wrench_act(mob/living/user, obj/item/tool) - return NONE - -/obj/structure/window/reinforced/shuttle/indestructible/crowbar_act(mob/living/user, obj/item/tool) - return NONE +/obj/structure/window/reinforced/shuttle/indestructible/Initialize(mapload) + . = ..() + AddElement(/datum/element/tool_blocker, TOOL_WELDER, TOOL_ACT_PRIMARY) + AddElement(/datum/element/tool_blocker, TOOL_SCREWDRIVER, TOOL_ACT_PRIMARY) + AddElement(/datum/element/tool_blocker, TOOL_WRENCH, TOOL_ACT_PRIMARY) + AddElement(/datum/element/tool_blocker, TOOL_CROWBAR, TOOL_ACT_PRIMARY) /obj/structure/window/reinforced/plasma/plastitanium name = "plastitanium window" diff --git a/code/game/turfs/change_turf.dm b/code/game/turfs/change_turf.dm index 230eecabeec..0ad2a59c67b 100644 --- a/code/game/turfs/change_turf.dm +++ b/code/game/turfs/change_turf.dm @@ -163,8 +163,12 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list( if(SSlighting.initialized) // Space tiles should never have lighting objects if(!space_lit) + if(old_lighting_object) + lighting_object = old_lighting_object + vis_contents += lighting_object // Should have a lighting object if we never had one - lighting_object = old_lighting_object || new /datum/lighting_object(src) + else + new /atom/movable/lighting_object(null, src) else if (old_lighting_object) qdel(old_lighting_object, force = TRUE) @@ -311,7 +315,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list( var/list/giver_gases = mix.gases for(var/giver_id in giver_gases) ASSERT_GAS_IN_LIST(giver_id, total_gases) - total_gases[giver_id][MOLES] += giver_gases[giver_id][MOLES] + total.adjust_gas(giver_id, giver_gases[giver_id][MOLES]) total.temperature = energy / heat_cap for(var/id in total_gases) diff --git a/code/game/turfs/closed/minerals.dm b/code/game/turfs/closed/minerals.dm index b2acb199948..3cd2df8e233 100644 --- a/code/game/turfs/closed/minerals.dm +++ b/code/game/turfs/closed/minerals.dm @@ -1,4 +1,5 @@ #define MINING_MESSAGE_COOLDOWN 20 +#define DEFAULT_BORDER_DISTANCE -1 /**********************Mineral deposits**************************/ @@ -27,14 +28,14 @@ temperature = TCMB var/turf/turf_type = /turf/open/misc/asteroid/airless /// The path of the ore stack we spawn when we're mined. - var/obj/item/stack/ore/mineralType = null - /// If we spawn a boulder like on the gulag, we use this in lou of mineralType + var/obj/item/stack/ore/mineral_type = null + /// If we spawn a boulder like on the gulag, we use this in lou of mineral_type var/obj/item/boulder/spawned_boulder = null - /// How much ore we spawn when we're mining a mineralType. - var/mineralAmt = 3 + /// How much ore we spawn when we're mining a mineral_type. + var/mineral_amt = 3 /// The icon of the image we display when we're pinged by a mining scanner, to be overridden if you want to use an alternate file for a subtype. var/scan_icon = 'icons/effects/ore_visuals.dmi' - /// Placeholder for the icon_state of the image we display when we're pinged by a mining scanner + /// Placeholder for the image we display when we're pinged by a mining scanner var/scan_state = "" /// If true, this turf will not call AfterChange during change_turf calls. var/defer_change = FALSE @@ -44,7 +45,10 @@ var/tool_mine_speed = 4 SECONDS /// How long it takes to mine this turf without tools, if it's weak. var/hand_mine_speed = 15 SECONDS - + /// Distance to the nearest open turf + var/open_turf_distance = DEFAULT_BORDER_DISTANCE + /// Wall plane overlay icon state + var/wall_icon_state = "rock" /turf/closed/mineral/Initialize(mapload) . = ..() @@ -53,7 +57,11 @@ // So we draw them as if they were on the game plane, and then overlay a copy onto // The wall plane (so emissives/light masks behave) // I am so sorry - var/static/mutable_appearance/wall_overlay = mutable_appearance('icons/turf/mining.dmi', "rock", appearance_flags = RESET_TRANSFORM) + var/static/list/mutable_appearance/wall_overlays = list() + var/mutable_appearance/wall_overlay = wall_overlays[wall_icon_state] + if (!wall_overlay) + wall_overlay = mutable_appearance('icons/turf/mining.dmi', wall_icon_state, appearance_flags = RESET_TRANSFORM) + wall_overlays[wall_icon_state] = wall_overlay wall_overlay.plane = MUTATE_PLANE(WALL_PLANE, src) overlays += wall_overlay @@ -74,85 +82,138 @@ else if(held_item.tool_behaviour == TOOL_MINING) attackby(held_item, bumping) -/turf/closed/mineral/proc/Spread_Vein() - var/spreadChance = initial(mineralType.spreadChance) - if(spreadChance) - for(var/dir in GLOB.cardinals) - if(prob(spreadChance)) - var/turf/T = get_step(src, dir) - var/turf/closed/mineral/random/M = T - if(istype(M) && !M.mineralType) - M.Change_Ore(mineralType) +/turf/closed/mineral/proc/spread_vein(ore_type) + if(!ispath(ore_type, /obj/item/stack/ore)) + change_ore(ore_type) + return -/turf/closed/mineral/proc/Change_Ore(ore_type, random = 0) - if(random) - mineralAmt = rand(1, 5) - if(ispath(ore_type, /obj/item/stack/ore)) // If it has a scan_state, switch to it - var/obj/item/stack/ore/the_ore = ore_type - scan_state = initial(the_ore.scan_state) // I SAID. SWITCH. TO. IT. - mineralType = ore_type // Everything else assumes that this is typed correctly so don't set it to non-ores thanks. - if(ispath(ore_type, /obj/item/boulder)) + var/obj/item/stack/ore/ore_path = ore_type + if (!ore_path::vein_type) + change_ore(ore_type) + return + + // No need to recalculate ore vein size lists every time we want to spawn one + var/static/list/vein_sizes = null + if (!vein_sizes) + vein_sizes = list() + + var/min_vein_size = ore_path::min_vein_size + var/max_vein_size = ore_path::max_vein_size + if (!vein_sizes[ore_path]) + var/list/ore_sizes = list() + // Larger veins are rarer by default + for (var/i in min_vein_size to max_vein_size) + ore_sizes["[i]"] = max_vein_size - i + 1 + vein_sizes[ore_path] = ore_sizes + + var/vein_size = text2num(pick_weight(vein_sizes[ore_path])) + + switch (ore_path::vein_type) + if (ORE_VEIN_CLUSTER) + for (var/turf/closed/mineral/rock in range(vein_size, src)) + if (rock.mineral_type) + continue + + var/spread_prob = 100 + // Easiest way to check for different rock types + if (rock.base_icon_state != base_icon_state) + spread_prob = 50 + + if (rock == src || prob(spread_prob * sqrt(max(0, 1 - sqrt((x - rock.x) ** 2 + (y - rock.y) ** 2) / vein_size)))) + rock.change_ore(ore_path) + + if (ORE_VEIN_SCATTER) + var/list/turf/closed/mineral/rocks = list() + for (var/turf/closed/mineral/rock in range(vein_size, src)) + if (rock.base_icon_state != base_icon_state && prob(50)) + continue + if (!rock.mineral_type) + rocks += rock + + for (var/i in 1 to rand(min_vein_size ** 2, max_vein_size ** 2)) + var/turf/closed/mineral/rock = pick_n_take(rocks) + if (istype(rock)) + rock.change_ore(ore_path, FALSE) + rock.mineral_amt = 1 + + if (ORE_VEIN_PLAIN) + var/list/turf/closed/mineral/rocks = list() + for (var/turf/closed/mineral/rock in range(vein_size, src)) + if (rock.base_icon_state != base_icon_state && prob(50)) + continue + if (!rock.mineral_type) + rocks += rock + + if (!length(rocks)) + return + + var/turf/first_end = pick(rocks) + var/first_dist = get_dist(src, first_end) + var/second_dist = vein_size - first_dist + var/turf/second_end = locate(x - round((first_end.x - x) / first_dist * second_dist, 1), y - round((first_end.y - y) / first_dist * second_dist, 1), z) + if (!istype(second_end)) + second_end = src + + rocks.Cut() + for (var/turf/closed/mineral/rock in range(1, second_end)) + if (!rock.mineral_type) + rocks += rock + + if (!length(rocks)) + return + + second_end = pick(rocks) + for (var/turf/closed/mineral/rock in get_line(first_end, src) + get_line(second_end, src)) + rock.change_ore(ore_path) + if (rock == src || prob(100 / get_dist(src, rock))) + var/turf/closed/mineral/other_rock = get_step(rock, pick(GLOB.cardinals)) + if (istype(other_rock) && !other_rock.mineral_type) + other_rock.change_ore(ore_path) + + if (ORE_VEIN_BRANCH) + for (var/branch in 1 to rand(3, 5)) + var/list/turf/closed/mineral/rocks = list() + for (var/turf/closed/mineral/rock in range(vein_size, src)) + if (rock.base_icon_state != base_icon_state && prob(50)) + continue + if (!rock.mineral_type) + rocks += rock + + if (!length(rocks)) + continue + + for (var/turf/closed/mineral/rock in get_line(src, pick(rocks))) + if (!rock.mineral_type) + rock.change_ore(ore_path) + +/turf/closed/mineral/proc/change_ore(ore_type, random = TRUE) + if (ispath(ore_type, /obj/item/boulder)) scan_state = "rock_boulder" // Yes even the lowly boulder has a scan state spawned_boulder = /obj/item/boulder/gulag_expanded + return -/** - * Returns the distance to the nearest ore vent, where ore vents are tracked in SSore_generation's possible vents list. - * Returns 0 if we're not on lavaland, and as we're using get_dist, our range is limited to 127 tiles. - */ -/turf/closed/mineral/proc/prox_to_vent() - if(!is_mining_level(z)) - return 0 + if (random) + mineral_amt = rand(1, 5) - var/distance = 128 // Max distance for a get_dist is 127 - for(var/obj/structure/ore_vent/vent as anything in SSore_generation.possible_vents) - if(vent.z != src.z) - continue //Silly - var/temp_distance = get_dist(src, vent) - if(temp_distance < distance) - distance = temp_distance - return distance + if (!ispath(ore_type, /obj/item/stack/ore)) + return -/** - * Returns the chance of ore spawning in this turf, based on proximity to a vent. - * See mining defines for the chances and distance defines. - */ -/turf/closed/mineral/proc/proximity_ore_chance() - var/distance = prox_to_vent() - if(distance == 0) //We asked for a random chance but we could not successfully find a vent, so 0. - return 0 + var/obj/item/stack/ore/the_ore = ore_type + scan_state = initial(the_ore.scan_state) // If it has a scan_state, switch to it + mineral_type = ore_type // Everything else assumes that this is typed correctly so don't set it to non-ores thanks. - if(distance < VENT_PROX_VERY_HIGH) - return VENT_CHANCE_VERY_HIGH - if(distance < VENT_PROX_HIGH) - return VENT_CHANCE_HIGH - if(distance < VENT_PROX_MEDIUM) - return VENT_CHANCE_MEDIUM - if(distance < VENT_PROX_LOW) - return VENT_CHANCE_LOW - if(distance < VENT_PROX_FAR) - return VENT_CHANCE_FAR - return 0 - -/** - * Returns the amount of ore to spawn in this turf, based on proximity to a vent. - * If for some reason we have a distance of zero (like being off mining Z levels), we return a random amount between 1 and 5 instead. - */ -/turf/closed/mineral/proc/scale_ore_to_vent() - var/distance = prox_to_vent() - if(distance == 0) // We're not on lavaland or similar failure condition - return rand(1,5) - - if(distance < VENT_PROX_VERY_HIGH) - return ORE_WALL_VERY_HIGH - if(distance < VENT_PROX_HIGH) - return ORE_WALL_HIGH - if(distance < VENT_PROX_MEDIUM) - return ORE_WALL_MEDIUM - if(distance < VENT_PROX_LOW) - return ORE_WALL_LOW - if(distance < VENT_PROX_FAR) - return ORE_WALL_FAR - return 0 +/turf/closed/mineral/proc/flash_scan() + var/obj/effect/temp_visual/mining_overlay/scan_overlay = locate(/obj/effect/temp_visual/mining_overlay) in src + if(scan_overlay) + deltimer(scan_overlay.timerid) + scan_overlay.timerid = QDEL_IN_STOPPABLE(scan_overlay, scan_overlay.duration) + animate(scan_overlay, alpha = 0, time = scan_overlay.duration, easing = scan_overlay.easing_style) + return + scan_overlay = new(src) + var/mutable_appearance/scan_state_overlay = mutable_appearance(scan_icon, scan_state) + scan_state_overlay.pixel_x = 224 + scan_state_overlay.pixel_y = 224 + scan_overlay.add_overlay(scan_state_overlay) /turf/closed/mineral/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) if(turf_type) @@ -161,7 +222,6 @@ return TRUE return ..() - /turf/closed/mineral/attackby(obj/item/I, mob/user, list/modifiers, list/attack_modifiers, exp_multiplier = 1) if (!ISADVANCEDTOOLUSER(user)) to_chat(usr, span_warning("You don't have the dexterity to do this!")) @@ -212,22 +272,23 @@ /turf/closed/mineral/proc/gets_drilled(mob/user, exp_multiplier = 0) if(istype(user)) SEND_SIGNAL(user, COMSIG_MOB_MINED, src, exp_multiplier) - if(mineralType && (mineralAmt > 0)) - new mineralType(src, mineralAmt) - SSblackbox.record_feedback("tally", "ore_mined", mineralAmt, mineralType) + if(mineral_type && (mineral_amt > 0)) + new mineral_type(src, mineral_amt) + SSblackbox.record_feedback("tally", "ore_mined", mineral_amt, mineral_type) if(spawned_boulder) var/obj/item/boulder/wall_boulder = new spawned_boulder(src) wall_boulder.platform_lifespan = PLATFORM_LIFE_GULAG if(ishuman(user)) var/mob/living/carbon/human/H = user if(exp_multiplier) - if (mineralType && (mineralAmt > 0)) - H.mind.adjust_experience(/datum/skill/mining, initial(mineralType.mine_experience) * mineralAmt * exp_multiplier) + if (mineral_type && (mineral_amt > 0)) + H.mind.adjust_experience(/datum/skill/mining, initial(mineral_type.mine_experience) * mineral_amt * exp_multiplier) else H.mind.adjust_experience(/datum/skill/mining, 4 * exp_multiplier) for(var/obj/effect/temp_visual/mining_overlay/M in src) qdel(M) + var/flags = NONE var/old_type = type if(defer_change) // TODO: make the defer change var a var for any changeturf flag @@ -237,15 +298,24 @@ playsound(src, 'sound/effects/break_stone.ogg', 50, TRUE) //beautiful destruction mined.update_visuals() +/// When the turf gets drilled from an AOE explosion +/// Has a chance of not being drilled based on own hardness +/turf/closed/mineral/proc/drill_aoe(mob/user, exp_multiplier = 0) + var/speed_change = /turf/closed/mineral::tool_mine_speed / tool_mine_speed + // Probability scaling isn't linear to still mine somewhat reliably in dense rocks + // Rocks with ores always get broken by AOE + if (speed_change >= 1 || mineral_type || spawned_boulder || prob(100 * (1 - (1 - sqrt(speed_change)) * 1.5))) + return gets_drilled(user, exp_multiplier) + /turf/closed/mineral/attack_alien(mob/living/carbon/alien/user, list/modifiers) balloon_alert(user, "digging...") playsound(src, 'sound/effects/break_stone.ogg', 50, TRUE) - if(do_after(user, 4 SECONDS, target = src)) + if(do_after(user, tool_mine_speed, target = src)) gets_drilled(user) /turf/closed/mineral/attack_hulk(mob/living/carbon/human/H) ..() - if(do_after(H, 5 SECONDS, target = src)) + if(do_after(H, tool_mine_speed * 1.25, target = src)) playsound(src, 'sound/effects/meteorimpact.ogg', 100, TRUE) H.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk") gets_drilled(H) @@ -259,27 +329,69 @@ if(target == src) gets_drilled() return TRUE + + var/hardness = /turf/closed/mineral::tool_mine_speed / tool_mine_speed switch(severity) if(EXPLODE_DEVASTATE) gets_drilled() if(EXPLODE_HEAVY) - if(prob(90)) + if(prob(90 * hardness)) gets_drilled() if(EXPLODE_LIGHT) - if(prob(75)) + if(prob(75 * hardness)) gets_drilled() return TRUE /turf/closed/mineral/blob_act(obj/structure/blob/B) - if(prob(50)) + if(prob(50 * /turf/closed/mineral::tool_mine_speed / tool_mine_speed)) gets_drilled() +/proc/calculate_rock_edges() + var/cardinals = GLOB.cardinals.Copy() // i'm sorry + for(var/mining_z in SSmapping.levels_by_trait(ZTRAIT_MINING)) + var/list/adjacent_minerals = list() + for(var/turf/open/open_turf in Z_TURFS(mining_z)) + for (var/neighbour_dir in cardinals) + var/turf/neighbour = get_step(open_turf, neighbour_dir) + if (!ismineralturf(neighbour)) + continue + + var/turf/closed/mineral/rock = neighbour + if(rock.open_turf_distance != DEFAULT_BORDER_DISTANCE) + continue + + rock.open_turf_distance = 1 + adjacent_minerals |= rock + CHECK_TICK + + var/index = 1 + while(index <= length(adjacent_minerals)) + var/turf/closed/mineral/rock = adjacent_minerals[index] + index += 1 + for (var/neighbour_dir in cardinals) + var/turf/neighbour = get_step(rock, neighbour_dir) + if (!ismineralturf(neighbour)) + continue + + var/turf/closed/mineral/rock_neighbour = neighbour + // Don't need to check if we're closer because we're doing BFS fill + if(rock_neighbour.open_turf_distance == DEFAULT_BORDER_DISTANCE) + rock_neighbour.open_turf_distance = rock.open_turf_distance + 1 + adjacent_minerals += rock_neighbour + CHECK_TICK + /turf/closed/mineral/random /// What are the base odds that this turf spawns a mineral in the wall on initialize? - var/mineralChance = 13 - /// Does this mineral determine its random chance and mineral contents based on proximity to a vent? Overrides mineralChance and mineralAmt. - var/proximity_based = FALSE + var/mineral_chance = 7 + /// Does this turf's chance of spawning ore increase with distance to open air? + var/exposure_based = FALSE + /// Chance of spawning a specific mineral per type, cached for speed + var/static/list/mineral_chances_by_type = list() + /// Chance of spawning a specific mineral per type per depth + var/static/list/mineral_chances_by_depth = list() + /// Sum of ore spawn probabilities per type per depth + var/static/list/spawn_chances_by_depth = list() /// Returns a list of the chances for minerals to spawn. /// Will only run once, and will then be cached. @@ -287,62 +399,124 @@ return list( /obj/item/stack/ore/bananium = check_holidays(APRIL_FOOLS) ? 3 : 0, /obj/item/stack/ore/bluespace_crystal = 1, - /obj/item/stack/ore/diamond = 1, - /obj/item/stack/ore/gold = 10, - /obj/item/stack/ore/iron = 40, - /obj/item/stack/ore/plasma = 20, - /obj/item/stack/ore/silver = 12, - /obj/item/stack/ore/titanium = 11, + /obj/item/stack/ore/diamond = 2, + /obj/item/stack/ore/gold = 8, + /obj/item/stack/ore/iron = 18, // Iron and plasma are this low due to how much they spread into veins + /obj/item/stack/ore/plasma = 12, + /obj/item/stack/ore/silver = 8, + /obj/item/stack/ore/titanium = 8, /obj/item/stack/ore/uranium = 5, /turf/closed/mineral/gibtonite = 4, ) /turf/closed/mineral/random/Initialize(mapload) - var/static/list/mineral_chances_by_type = list() - . = ..() - var/dynamic_prob = mineralChance - var/ore_amount = rand(1,5) - if(proximity_based) - dynamic_prob = proximity_ore_chance() // We assign the chance of ore spawning based on probability. - ore_amount = scale_ore_to_vent() - if (prob(dynamic_prob)) - var/list/spawn_chance_list = mineral_chances_by_type[type] - if (isnull(spawn_chance_list)) - mineral_chances_by_type[type] = expand_weights(mineral_chances()) - spawn_chance_list = mineral_chances_by_type[type] - var/path = pick(spawn_chance_list) - if(ispath(path, /turf)) - var/stored_flags = 0 - if(turf_flags & NO_RUINS) - stored_flags |= NO_RUINS - var/turf/T = ChangeTurf(path,null,CHANGETURF_IGNORE_AIR) - T.flags_1 |= stored_flags + if (exposure_based) + SSore_generation.ore_turfs += src + return - if(ismineralturf(T)) - var/turf/closed/mineral/M = T - M.turf_type = src.turf_type - M.mineralAmt = ore_amount - GLOB.post_ore_random["[M.mineralAmt]"] += 1 - src = M - M.levelupdate() - else - src = T - T.levelupdate() + var/list/spawn_chance_list = mineral_chances_by_type[type] + if (isnull(spawn_chance_list)) + mineral_chances_by_type[type] = expand_weights(mineral_chances()) + spawn_chance_list = mineral_chances_by_type[type] - else - Change_Ore(path, FALSE) - Spread_Vein(path) - mineralAmt = ore_amount - GLOB.post_ore_manual["[mineralAmt]"] += 1 + if (prob(mineral_chance)) + spawn_ore(pick(spawn_chance_list)) - if(mineralType && !mineralAmt) - stack_trace("Mineral turf with mineralAmt being zero initialized at [src.x], [src.y], [src.z] ([get_area(src)])") +/turf/closed/mineral/random/proc/randomize_ore() +#ifdef TESTING + if (open_turf_distance == -1) + color = COLOR_BLUE + else + color = BlendRGB(COLOR_GREEN, COLOR_RED, clamp((open_turf_distance - 1) / 5, 0, 0.99)) + maptext_x = 4 + maptext_y = 4 + maptext = MAPTEXT_TINY_UNICODE("[open_turf_distance]") +#endif + + var/list/spawn_type_list = mineral_chances_by_depth[type] + if (isnull(spawn_type_list)) + spawn_type_list = list() + mineral_chances_by_depth[type] = spawn_type_list + + var/list/ore_depth_chances = spawn_chances_by_depth[type] + if (isnull(ore_depth_chances)) + ore_depth_chances = list() + spawn_chances_by_depth[type] = ore_depth_chances + + var/list/spawn_chance_list = spawn_type_list["[open_turf_distance]"] + var/ore_depth_chance = ore_depth_chances["[open_turf_distance]"] + if (isnull(spawn_chance_list)) + spawn_chance_list = mineral_chances() + var/total_spawn_sum = 0 + var/base_spawn_sum = 0 + var/lowest_factor = 1 + for (var/obj/item/stack/ore/ore_type as anything in spawn_chance_list) + if (!spawn_chance_list[ore_type]) + continue + base_spawn_sum += spawn_chance_list[ore_type] + if (!ispath(ore_type, /obj/item/stack/ore)) + total_spawn_sum += spawn_chance_list[ore_type] + continue + + var/depth_factor = 1 / (1 + abs(ore_type::vein_distance - open_turf_distance)) + lowest_factor = clamp(ceil(1 / (spawn_chance_list[ore_type] * depth_factor)), lowest_factor, ORE_CHANCE_PRECISION) + spawn_chance_list[ore_type] *= depth_factor + total_spawn_sum += spawn_chance_list[ore_type] + + for (var/obj/item/stack/ore/ore_type as anything in spawn_chance_list) + spawn_chance_list[ore_type] = floor(spawn_chance_list[ore_type] * lowest_factor) + + ore_depth_chance = mineral_chance * total_spawn_sum / base_spawn_sum + + LAZYSET(SSore_generation.ore_spread_probabilities[type], "[open_turf_distance]", spawn_chance_list.Copy() + list("chance" = ore_depth_chance, "count" = 0)) + + spawn_chance_list = expand_weights(spawn_chance_list) + + spawn_type_list["[open_turf_distance]"] = spawn_chance_list + ore_depth_chances["[open_turf_distance]"] = ore_depth_chance + + SSore_generation.ore_spread_probabilities[type]["[open_turf_distance]"]["count"] += 1 + if (prob(ore_depth_chance)) + spawn_ore(pick(spawn_chance_list)) + +/turf/closed/mineral/random/proc/spawn_ore(ore_path) + if (!SSore_generation.ores_generated[ore_path]) + SSore_generation.ores_generated[ore_path] = 0 + SSore_generation.ores_generated[ore_path] += 1 + + if(!ispath(ore_path, /turf)) + change_ore(ore_path) + if (!ispath(ore_path, /obj/item/stack/ore)) + return + var/obj/item/stack/ore/ore_type = ore_path + if (prob(ore_type::spread_chance)) + spread_vein(ore_path) + return + + var/stored_flags = 0 + if(turf_flags & NO_RUINS) + stored_flags |= NO_RUINS + var/turf/new_turf = ChangeTurf(ore_path, null, CHANGETURF_IGNORE_AIR) + new_turf.flags_1 |= stored_flags + + if(ismineralturf(new_turf)) + src = new_turf + new_turf.levelupdate() + return + + var/turf/closed/mineral/new_rock = new_turf + new_rock.turf_type = src.turf_type + src = new_rock + new_rock.levelupdate() + + if(mineral_type && !mineral_amt) + stack_trace("Mineral turf with mineral_amt being zero initialized at [src.x], [src.y], [src.z] ([get_area(src)])") /turf/closed/mineral/random/high_chance icon_state = "rock_highchance" - mineralChance = 25 - proximity_based = FALSE + mineral_chance = 14 + exposure_based = FALSE /turf/closed/mineral/random/high_chance/mineral_chances() return list( @@ -356,11 +530,12 @@ ) /turf/closed/mineral/random/high_chance/volcanic + name = "basalt" turf_type = /turf/open/misc/asteroid/basalt/lava_land_surface baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface initial_gas_mix = LAVALAND_DEFAULT_ATMOS defer_change = TRUE - proximity_based = FALSE + exposure_based = FALSE /turf/closed/mineral/random/high_chance/volcanic/mineral_chances() return list( @@ -375,15 +550,15 @@ /turf/closed/mineral/random/low_chance icon_state = "rock_lowchance" - mineralChance = 6 + mineral_chance = 2 /turf/closed/mineral/random/low_chance/mineral_chances() return list( /obj/item/stack/ore/bluespace_crystal = 1, /obj/item/stack/ore/diamond = 1, /obj/item/stack/ore/gold = 4, - /obj/item/stack/ore/iron = 40, - /obj/item/stack/ore/plasma = 15, + /obj/item/stack/ore/iron = 30, + /obj/item/stack/ore/plasma = 10, /obj/item/stack/ore/silver = 6, /obj/item/stack/ore/titanium = 4, /obj/item/stack/ore/uranium = 2, @@ -393,13 +568,13 @@ //extremely low chance of rare ores, meant mostly for populating stations with large amounts of asteroid /turf/closed/mineral/random/stationside icon_state = "rock_nochance" - mineralChance = 4 + mineral_chance = 1 /turf/closed/mineral/random/stationside/mineral_chances() return list( /obj/item/stack/ore/diamond = 1, /obj/item/stack/ore/gold = 3, - /obj/item/stack/ore/iron = 50, + /obj/item/stack/ore/iron = 30, /obj/item/stack/ore/plasma = 3, /obj/item/stack/ore/silver = 4, /obj/item/stack/ore/titanium = 5, @@ -407,24 +582,82 @@ ) /turf/closed/mineral/random/volcanic + name = "basalt" turf_type = /turf/open/misc/asteroid/basalt/lava_land_surface baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface initial_gas_mix = LAVALAND_DEFAULT_ATMOS defer_change = TRUE - proximity_based = FALSE //SKYRAT EDIT: Original TRUE - mineralChance = 5 + exposure_based = TRUE + mineral_chance = 7 // N% functionally, 7.17% default, accounts for ~65% turfs /turf/closed/mineral/random/volcanic/mineral_chances() return list( /obj/item/stack/ore/bluespace_crystal = 1, - /obj/item/stack/ore/diamond = 1, - /obj/item/stack/ore/gold = 10, - /obj/item/stack/ore/iron = 40, - /obj/item/stack/ore/plasma = 20, - /obj/item/stack/ore/silver = 12, + /obj/item/stack/ore/diamond = 2, + /obj/item/stack/ore/gold = 8, + /obj/item/stack/ore/iron = 16, + /obj/item/stack/ore/plasma = 10, + /obj/item/stack/ore/silver = 8, /obj/item/stack/ore/titanium = 11, - /obj/item/stack/ore/uranium = 5, - /turf/closed/mineral/gibtonite/volcanic = 4, + /obj/item/stack/ore/uranium = 7, + /turf/closed/mineral/gibtonite/volcanic = 2, + ) + +/turf/closed/mineral/random/volcanic/red_rock + name = "siderite" + icon = MAP_SWITCH('icons/turf/walls/red_rock.dmi', 'icons/turf/mining.dmi') + icon_state = "red_rock" + base_icon_state = "red_rock" + transform = MAP_SWITCH(TRANSLATE_MATRIX(-8, -8), matrix()) + smoothing_groups = SMOOTH_GROUP_CLOSED_TURFS + SMOOTH_GROUP_RED_ROCK_WALLS + canSmoothWith = SMOOTH_GROUP_RED_ROCK_WALLS + tool_mine_speed = 5 SECONDS // 25% harder than basalt + hand_mine_speed = 17 SECONDS + mineral_chance = 8 // N% functionally, 6.67% default, accounts for ~22% turfs + wall_icon_state = "red_rock" + turf_type = /turf/open/misc/asteroid/basalt/smooth/siderite/lava_land_surface + baseturfs = /turf/open/misc/asteroid/basalt/smooth/siderite/lava_land_surface + +/turf/closed/mineral/random/volcanic/red_rock/mineral_chances() + return list( + // Cannot spawn these two + // /obj/item/stack/ore/bluespace_crystal = 0, + // /obj/item/stack/ore/diamond = 0, + /obj/item/stack/ore/gold = 2, + /obj/item/stack/ore/iron = 32, // Iron and plasma are this low due to how much they spread into veins + /obj/item/stack/ore/plasma = 6, + /obj/item/stack/ore/silver = 14, + /obj/item/stack/ore/titanium = 25, + /obj/item/stack/ore/uranium = 3, + /turf/closed/mineral/gibtonite/volcanic/red_rock = 1, + ) + +/turf/closed/mineral/random/volcanic/shale + name = "shale" + icon = MAP_SWITCH('icons/turf/walls/shale.dmi', 'icons/turf/mining.dmi') + icon_state = "shale" + base_icon_state = "shale" + transform = MAP_SWITCH(TRANSLATE_MATRIX(-8, -8), matrix()) + smoothing_groups = SMOOTH_GROUP_CLOSED_TURFS + SMOOTH_GROUP_SHALE_WALLS + canSmoothWith = SMOOTH_GROUP_SHALE_WALLS + tool_mine_speed = 7 SECONDS // 75% harder than basalt + hand_mine_speed = 20 SECONDS + mineral_chance = 8 // N% functionally, 7.01% default, accounts for ~13% turfs + wall_icon_state = "shale" + turf_type = /turf/open/misc/asteroid/basalt/smooth/shale/lava_land_surface + baseturfs = /turf/open/misc/asteroid/basalt/smooth/shale/lava_land_surface + +/turf/closed/mineral/random/volcanic/shale/mineral_chances() + return list( + /obj/item/stack/ore/bluespace_crystal = 1.5, + /obj/item/stack/ore/diamond = 3, + /obj/item/stack/ore/gold = 12, + /obj/item/stack/ore/iron = 10, // Iron and plasma are this low due to how much they spread into veins + /obj/item/stack/ore/plasma = 28, + /obj/item/stack/ore/silver = 4, + /obj/item/stack/ore/titanium = 8, + /obj/item/stack/ore/uranium = 14, + /turf/closed/mineral/gibtonite/volcanic/shale = 3, ) /turf/closed/mineral/random/snow @@ -439,11 +672,11 @@ baseturfs = /turf/open/misc/asteroid/snow/icemoon initial_gas_mix = ICEMOON_DEFAULT_ATMOS weak_turf = TRUE - proximity_based = FALSE //SKYRAT EDIT: Original TRUE + exposure_based = TRUE -/turf/closed/mineral/random/snow/Change_Ore(ore_type, random = 0) +/turf/closed/mineral/random/snow/change_ore(ore_type, random = TRUE) . = ..() - if(mineralType) + if(mineral_type) icon = 'modular_zubbers/icons/turf/walls/icerock_wall.dmi' // BUBBER EDIT icon_state = "icerock_wall-0" base_icon_state = "icerock_wall" @@ -452,11 +685,11 @@ /turf/closed/mineral/random/snow/mineral_chances() return list( /obj/item/stack/ore/bluespace_crystal = 1, - /obj/item/stack/ore/diamond = 1, - /obj/item/stack/ore/gold = 10, - /obj/item/stack/ore/iron = 40, - /obj/item/stack/ore/plasma = 20, - /obj/item/stack/ore/silver = 12, + /obj/item/stack/ore/diamond = 2, + /obj/item/stack/ore/gold = 8, + /obj/item/stack/ore/iron = 22, + /obj/item/stack/ore/plasma = 12, + /obj/item/stack/ore/silver = 8, /obj/item/stack/ore/titanium = 11, /obj/item/stack/ore/uranium = 5, /turf/closed/mineral/gibtonite/ice/icemoon = 4, @@ -471,7 +704,7 @@ /turf/closed/mineral/random/snow/underground baseturfs = /turf/open/misc/asteroid/snow/icemoon // abundant ore - mineralChance = 20 + mineral_chance = 11 /turf/closed/mineral/random/snow/underground/mineral_chances() return list( @@ -479,8 +712,8 @@ /obj/item/stack/ore/bluespace_crystal = 2, /obj/item/stack/ore/diamond = 4, /obj/item/stack/ore/gold = 20, - /obj/item/stack/ore/iron = 20, - /obj/item/stack/ore/plasma = 20, + /obj/item/stack/ore/iron = 10, // Iron and plasma are this low due to how much they spread into veins, + /obj/item/stack/ore/plasma = 14, /obj/item/stack/ore/silver = 24, /obj/item/stack/ore/titanium = 22, /obj/item/stack/ore/uranium = 10, @@ -488,7 +721,7 @@ ) /turf/closed/mineral/random/snow/high_chance - proximity_based = FALSE + exposure_based = FALSE /turf/closed/mineral/random/snow/high_chance/mineral_chances() return list( @@ -511,6 +744,7 @@ ) /turf/closed/mineral/random/labormineral/volcanic + name = "basalt" turf_type = /turf/open/misc/asteroid/basalt/lava_land_surface baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface initial_gas_mix = LAVALAND_DEFAULT_ATMOS @@ -542,19 +776,20 @@ /turf/closed/mineral/gibtonite/ice/icemoon = 2, ) -/turf/closed/mineral/random/labormineral/ice/Change_Ore(ore_type, random = 0) +/turf/closed/mineral/random/labormineral/ice/change_ore(ore_type, random = TRUE) . = ..() - if(mineralType) + if(mineral_type) icon = 'modular_zubbers/icons/turf/walls/icerock_wall.dmi' // BUBBER EDIT icon_state = "icerock_wall-0" base_icon_state = "icerock_wall" smoothing_flags = SMOOTH_BITMASK | SMOOTH_BORDER /turf/closed/mineral/iron - mineralType = /obj/item/stack/ore/iron + mineral_type = /obj/item/stack/ore/iron scan_state = "rock_iron" /turf/closed/mineral/iron/volcanic + name = "basalt" turf_type = /turf/open/misc/asteroid/basalt/lava_land_surface baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface initial_gas_mix = LAVALAND_DEFAULT_ATMOS @@ -571,20 +806,22 @@ defer_change = TRUE /turf/closed/mineral/uranium - mineralType = /obj/item/stack/ore/uranium + mineral_type = /obj/item/stack/ore/uranium scan_state = "rock_uranium" /turf/closed/mineral/uranium/volcanic + name = "basalt" turf_type = /turf/open/misc/asteroid/basalt/lava_land_surface baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface initial_gas_mix = LAVALAND_DEFAULT_ATMOS defer_change = TRUE /turf/closed/mineral/diamond - mineralType = /obj/item/stack/ore/diamond + mineral_type = /obj/item/stack/ore/diamond scan_state = "rock_diamond" /turf/closed/mineral/diamond/volcanic + name = "basalt" turf_type = /turf/open/misc/asteroid/basalt/lava_land_surface baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface initial_gas_mix = LAVALAND_DEFAULT_ATMOS @@ -601,20 +838,22 @@ defer_change = TRUE /turf/closed/mineral/gold - mineralType = /obj/item/stack/ore/gold + mineral_type = /obj/item/stack/ore/gold scan_state = "rock_gold" /turf/closed/mineral/gold/volcanic + name = "basalt" turf_type = /turf/open/misc/asteroid/basalt/lava_land_surface baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface initial_gas_mix = LAVALAND_DEFAULT_ATMOS defer_change = TRUE /turf/closed/mineral/silver - mineralType = /obj/item/stack/ore/silver + mineral_type = /obj/item/stack/ore/silver scan_state = "rock_silver" /turf/closed/mineral/silver/volcanic + name = "basalt" turf_type = /turf/open/misc/asteroid/basalt/lava_land_surface baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface initial_gas_mix = LAVALAND_DEFAULT_ATMOS @@ -626,20 +865,22 @@ initial_gas_mix = ICEMOON_DEFAULT_ATMOS /turf/closed/mineral/titanium - mineralType = /obj/item/stack/ore/titanium + mineral_type = /obj/item/stack/ore/titanium scan_state = "rock_titanium" /turf/closed/mineral/titanium/volcanic + name = "basalt" turf_type = /turf/open/misc/asteroid/basalt/lava_land_surface baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface initial_gas_mix = LAVALAND_DEFAULT_ATMOS defer_change = TRUE /turf/closed/mineral/plasma - mineralType = /obj/item/stack/ore/plasma + mineral_type = /obj/item/stack/ore/plasma scan_state = "rock_plasma" /turf/closed/mineral/plasma/volcanic + name = "basalt" turf_type = /turf/open/misc/asteroid/basalt/lava_land_surface baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface initial_gas_mix = LAVALAND_DEFAULT_ATMOS @@ -656,22 +897,24 @@ defer_change = TRUE /turf/closed/mineral/bananium - mineralType = /obj/item/stack/ore/bananium - mineralAmt = 3 + mineral_type = /obj/item/stack/ore/bananium + mineral_amt = 3 scan_state = "rock_bananium" /turf/closed/mineral/bananium/volcanic + name = "basalt" turf_type = /turf/open/misc/asteroid/basalt/lava_land_surface baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface initial_gas_mix = LAVALAND_DEFAULT_ATMOS defer_change = TRUE /turf/closed/mineral/bscrystal - mineralType = /obj/item/stack/ore/bluespace_crystal - mineralAmt = 1 + mineral_type = /obj/item/stack/ore/bluespace_crystal + mineral_amt = 1 scan_state = "rock_bscrystal" /turf/closed/mineral/bscrystal/volcanic + name = "basalt" turf_type = /turf/open/misc/asteroid/basalt/lava_land_surface baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface initial_gas_mix = LAVALAND_DEFAULT_ATMOS @@ -688,11 +931,46 @@ initial_gas_mix = AIRLESS_ATMOS /turf/closed/mineral/volcanic/lava_land_surface + name = "basalt" turf_type = /turf/open/misc/asteroid/basalt/lava_land_surface baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface defer_change = TRUE -/turf/closed/mineral/ash_rock //wall piece +/// Rock type which replaces itself with whichever rock would've been generated by the biome underneath +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace + icon = 'icons/turf/mining.dmi' + icon_state = "volcanic_biome" + smoothing_flags = NONE + /// Area type to whose generator we try to default to + var/default_area = /area/lavaland/surface/outdoors/unexplored/danger + +/turf/closed/mineral/volcanic/lava_land_surface/biome_replace/Initialize(mapload) + . = ..() + // Just spawn a normal lavaland rock if we fail to get a mapgen, such as being spawned over lava + var/supposed_type = /turf/closed/mineral/volcanic/lava_land_surface + var/area/cur_area = loc + var/datum/map_generator/cave_generator/map_generator = cur_area?.get_generator() + if (!map_generator) + cur_area = GLOB.areas_by_type[default_area] + map_generator = cur_area?.get_generator() + + if (istype(map_generator)) + var/biome = map_generator.get_biome_for_turf(src) + if (biome) + var/datum/biome/generating_biome = SSmapping.biomes[biome] + supposed_type = generating_biome.closed_turf_type + + var/cur_flags = turf_flags + var/turf/new_turf = ChangeTurf(supposed_type, flags = CHANGETURF_FORCEOP | CHANGETURF_INHERIT_AIR) + if(cur_flags & NO_RUINS) + new_turf.turf_flags |= NO_RUINS + +/// A turf that can't we can't build openspace chasms on or spawn ruins in. +/turf/closed/mineral/volcanic/lava_land_surface/do_not_chasm + turf_flags = NO_RUINS + +/// Wall piece +/turf/closed/mineral/ash_rock name = "rock" icon = 'icons/turf/mining.dmi' icon = MAP_SWITCH('icons/turf/walls/rock_wall.dmi', 'icons/turf/mining.dmi') @@ -753,14 +1031,24 @@ /turf/closed/mineral/asteroid name = "iron rock" - icon_state = "redrock" - icon = MAP_SWITCH('icons/turf/walls/red_wall.dmi', 'icons/turf/mining.dmi') - base_icon_state = "red_wall" + icon = MAP_SWITCH('icons/turf/walls/red_rock.dmi', 'icons/turf/mining.dmi') + icon_state = "red_rock" + base_icon_state = "red_rock" + layer = EDGED_TURF_LOWER_LAYER + transform = MAP_SWITCH(TRANSLATE_MATRIX(-8, -8), matrix()) + smoothing_groups = SMOOTH_GROUP_CLOSED_TURFS + SMOOTH_GROUP_RED_ROCK_WALLS + canSmoothWith = SMOOTH_GROUP_RED_ROCK_WALLS + wall_icon_state = "red_rock" /turf/closed/mineral/random/stationside/asteroid name = "iron rock" - icon = MAP_SWITCH('icons/turf/walls/red_wall.dmi', 'icons/turf/mining.dmi') - base_icon_state = "red_wall" + icon = MAP_SWITCH('icons/turf/walls/red_rock.dmi', 'icons/turf/mining.dmi') + icon_state = "red_rock" + base_icon_state = "red_rock" + transform = MAP_SWITCH(TRANSLATE_MATRIX(-8, -8), matrix()) + smoothing_groups = SMOOTH_GROUP_CLOSED_TURFS + SMOOTH_GROUP_RED_ROCK_WALLS + canSmoothWith = SMOOTH_GROUP_RED_ROCK_WALLS + wall_icon_state = "red_rock" /turf/closed/mineral/random/stationside/asteroid/porus name = "porous iron rock" @@ -775,7 +1063,7 @@ //GIBTONITE /turf/closed/mineral/gibtonite - mineralAmt = 1 + mineral_amt = 1 MAP_SWITCH(, icon_state = "rock_Gibtonite_inactive") scan_state = "rock_gibtonite" var/det_time = 8 //Countdown till explosion, but also rewards the player for how close you were to detonation when you defuse it @@ -803,60 +1091,68 @@ user.visible_message(span_danger("[user] hit gibtonite with [attacking_item.name], launching [user.p_them()] back!"), span_danger("You've struck gibtonite! Your [attacking_item.name] launched you back!")) /turf/closed/mineral/gibtonite/proc/explosive_reaction(mob/user = null) - if(stage == GIBTONITE_UNSTRUCK) - activated_overlay = mutable_appearance('icons/turf/smoothrocks_overlays.dmi', "rock_Gibtonite_inactive", ON_EDGED_TURF_LAYER) //shows in gaps between pulses if there are any - add_overlay(activated_overlay) - name = "gibtonite deposit" - desc = "An active gibtonite reserve. Run!" - stage = GIBTONITE_ACTIVE - visible_message(span_danger("There's gibtonite inside! It's going to explode!")) + if(stage != GIBTONITE_UNSTRUCK) + return - var/notify_admins = !is_mining_level(z) + activated_overlay = mutable_appearance('icons/turf/smoothrocks_overlays.dmi', "rock_Gibtonite_inactive", ON_EDGED_TURF_LAYER) //shows in gaps between pulses if there are any + activated_overlay.pixel_x = 2 + activated_overlay.pixel_y = 2 + add_overlay(activated_overlay) + name = "gibtonite deposit" + desc = "An active gibtonite reserve. Run!" + stage = GIBTONITE_ACTIVE + visible_message(span_danger("There's gibtonite inside! It's going to explode!")) - if(user) - log_bomber(user, "has triggered a gibtonite deposit reaction via", src, null, notify_admins) - else - log_bomber(null, "An explosion has triggered a gibtonite deposit reaction via", src, null, notify_admins) + var/notify_admins = !is_mining_level(z) - countdown(notify_admins) + if(user) + log_bomber(user, "has triggered a gibtonite deposit reaction via", src, null, notify_admins) + else + log_bomber(null, "An explosion has triggered a gibtonite deposit reaction via", src, null, notify_admins) + + countdown(notify_admins) /turf/closed/mineral/gibtonite/proc/countdown(notify_admins = FALSE) set waitfor = FALSE - while(istype(src, /turf/closed/mineral/gibtonite) && stage == GIBTONITE_ACTIVE && det_time > 0 && mineralAmt >= 1) - flick_overlay_view(mutable_appearance('icons/turf/smoothrocks_overlays.dmi', "rock_Gibtonite_active", ON_EDGED_TURF_LAYER + 0.1), 0.5 SECONDS) //makes the animation pulse one time per tick + while(istype(src, /turf/closed/mineral/gibtonite) && stage == GIBTONITE_ACTIVE && det_time > 0 && mineral_amt >= 1) + var/mutable_appearance/boom_overlay = mutable_appearance('icons/turf/smoothrocks_overlays.dmi', "rock_Gibtonite_active", ON_EDGED_TURF_LAYER + 0.1) + boom_overlay.pixel_x = 2 + boom_overlay.pixel_y = 2 + flick_overlay_view(boom_overlay, 0.5 SECONDS) //makes the animation pulse one time per tick det_time-- sleep(0.5 SECONDS) if(istype(src, /turf/closed/mineral/gibtonite)) - if(stage == GIBTONITE_ACTIVE && det_time <= 0 && mineralAmt >= 1) + if(stage == GIBTONITE_ACTIVE && det_time <= 0 && mineral_amt >= 1) var/turf/bombturf = get_turf(src) - mineralAmt = 0 + mineral_amt = 0 stage = GIBTONITE_DETONATE explosion(bombturf, devastation_range = 1, heavy_impact_range = 3, light_impact_range = 5, flame_range = 0, flash_range = 0, adminlog = notify_admins, explosion_cause = src) /turf/closed/mineral/gibtonite/proc/defuse(mob/living/defuser) - if(stage == GIBTONITE_ACTIVE) - cut_overlay(activated_overlay) - activated_overlay.icon_state = "rock_Gibtonite_inactive" - add_overlay(activated_overlay) - desc = "An inactive gibtonite reserve. The ore can be extracted." - stage = GIBTONITE_STABLE - if(det_time < 0) - det_time = 0 - visible_message(span_notice("The chain reaction stopped! The gibtonite had [det_time] reactions left till the explosion!")) - if(defuser) - SEND_SIGNAL(defuser, COMSIG_LIVING_DEFUSED_GIBTONITE, det_time) + if(stage != GIBTONITE_ACTIVE) + return + cut_overlay(activated_overlay) + activated_overlay.icon_state = "rock_Gibtonite_inactive" + add_overlay(activated_overlay) + desc = "An inactive gibtonite reserve. The ore can be extracted." + stage = GIBTONITE_STABLE + if(det_time < 0) + det_time = 0 + visible_message(span_notice("The chain reaction stopped! The gibtonite had [det_time] reactions left till the explosion!")) + if(defuser) + SEND_SIGNAL(defuser, COMSIG_LIVING_DEFUSED_GIBTONITE, det_time) /turf/closed/mineral/gibtonite/gets_drilled(mob/user, exp_multiplier = 0, triggered_by_explosion = FALSE) if(istype(user)) SEND_SIGNAL(user, COMSIG_MOB_MINED, src, exp_multiplier) - if(stage == GIBTONITE_UNSTRUCK && mineralAmt >= 1) //Gibtonite deposit is activated + if(stage == GIBTONITE_UNSTRUCK && mineral_amt >= 1) //Gibtonite deposit is activated playsound(src,'sound/effects/hit_on_shattered_glass.ogg',50,TRUE) explosive_reaction(user) return - if(stage == GIBTONITE_ACTIVE && mineralAmt >= 1) //Gibtonite deposit goes kaboom + if(stage == GIBTONITE_ACTIVE && mineral_amt >= 1) //Gibtonite deposit goes kaboom var/turf/bombturf = get_turf(src) - mineralAmt = 0 + mineral_amt = 0 stage = GIBTONITE_DETONATE explosion(bombturf, devastation_range = 1, heavy_impact_range = 2, light_impact_range = 5, flame_range = 0, flash_range = 0, adminlog = FALSE, explosion_cause = src) if(stage == GIBTONITE_STABLE) //Gibtonite deposit is now benign and extractable. Depending on how close you were to it blowing up before defusing, you get better quality ore. @@ -877,11 +1173,36 @@ mined.update_visuals() /turf/closed/mineral/gibtonite/volcanic + name = "basalt" turf_type = /turf/open/misc/asteroid/basalt/lava_land_surface baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface initial_gas_mix = LAVALAND_DEFAULT_ATMOS defer_change = TRUE +/turf/closed/mineral/gibtonite/volcanic/red_rock + name = "siderite" + icon = MAP_SWITCH('icons/turf/walls/red_rock.dmi', 'icons/turf/mining.dmi') + icon_state = "red_rock" + base_icon_state = "red_rock" + transform = MAP_SWITCH(TRANSLATE_MATRIX(-8, -8), matrix()) + smoothing_groups = SMOOTH_GROUP_CLOSED_TURFS + SMOOTH_GROUP_RED_ROCK_WALLS + canSmoothWith = SMOOTH_GROUP_RED_ROCK_WALLS + tool_mine_speed = 5 SECONDS // 25% harder than basalt + hand_mine_speed = 17 SECONDS + wall_icon_state = "red_rock" + +/turf/closed/mineral/gibtonite/volcanic/shale + name = "shale" + icon = MAP_SWITCH('icons/turf/walls/shale.dmi', 'icons/turf/mining.dmi') + icon_state = "shale" + base_icon_state = "shale" + transform = MAP_SWITCH(TRANSLATE_MATRIX(-8, -8), matrix()) + smoothing_groups = SMOOTH_GROUP_CLOSED_TURFS + SMOOTH_GROUP_SHALE_WALLS + canSmoothWith = SMOOTH_GROUP_SHALE_WALLS + tool_mine_speed = 7 SECONDS // 75% harder than basalt + hand_mine_speed = 20 SECONDS + wall_icon_state = "shale" + /turf/closed/mineral/gibtonite/volcanic/airless turf_type = /turf/open/misc/asteroid/basalt baseturfs = /turf/open/misc/asteroid/basalt @@ -904,7 +1225,7 @@ initial_gas_mix = ICEMOON_DEFAULT_ATMOS /turf/closed/mineral/strong - name = "Very strong rock" + name = "very strong rock" desc = "Seems to be stronger than the other rocks in the area. Only a master of mining techniques could destroy this." turf_type = /turf/open/misc/asteroid/basalt/lava_land_surface baseturfs = /turf/open/misc/asteroid/basalt/lava_land_surface @@ -958,3 +1279,4 @@ return FALSE #undef MINING_MESSAGE_COOLDOWN +#undef DEFAULT_BORDER_DISTANCE diff --git a/code/game/turfs/open/asteroid.dm b/code/game/turfs/open/asteroid.dm index 9675f0c45d3..9ac571c2e6d 100644 --- a/code/game/turfs/open/asteroid.dm +++ b/code/game/turfs/open/asteroid.dm @@ -186,9 +186,34 @@ GLOBAL_LIST_EMPTY(dug_up_basalt) /turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins turf_flags = NO_RUINS -/// A turf that can't we can't build openspace chasms on or spawn ruins in. -/turf/closed/mineral/volcanic/lava_land_surface/do_not_chasm - turf_flags = NO_RUINS +/// Variant for ruins which replaces itself with the floor of a biome it generates in +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace + icon = 'icons/turf/mining.dmi' + icon_state = "basalt_biome" + smoothing_flags = NONE + /// Area type to whose generator we try to default to + var/default_area = /area/lavaland/surface/outdoors/unexplored/danger + +/turf/open/misc/asteroid/basalt/lava_land_surface/biome_replace/Initialize(mapload) + . = ..() + // Just spawn a normal lavaland rock if we fail to get a mapgen, such as being spawned over lava + var/supposed_type = /turf/open/misc/asteroid/basalt/lava_land_surface + var/area/cur_area = loc + var/datum/map_generator/cave_generator/map_generator = cur_area?.get_generator() + if (!map_generator) + cur_area = GLOB.areas_by_type[default_area] + map_generator = cur_area?.get_generator() + + if (istype(map_generator)) + var/biome = map_generator.get_biome_for_turf(src) + if (biome) + var/datum/biome/generating_biome = SSmapping.biomes[biome] + supposed_type = generating_biome.open_turf_type + + var/cur_flags = turf_flags + var/turf/new_turf = ChangeTurf(supposed_type, flags = CHANGETURF_FORCEOP | CHANGETURF_INHERIT_AIR) + if(cur_flags & NO_RUINS) + new_turf.turf_flags |= NO_RUINS /turf/open/misc/asteroid/lowpressure initial_gas_mix = OPENTURF_LOW_PRESSURE @@ -201,6 +226,77 @@ GLOBAL_LIST_EMPTY(dug_up_basalt) turf_type = /turf/open/misc/asteroid/airless worm_chance = 0 +/turf/open/misc/asteroid/basalt/smooth + smoothing_flags = SMOOTH_BITMASK + layer = MID_TURF_LAYER + floor_variance = 0 + transform = MAP_SWITCH(TRANSLATE_MATRIX(-8, -8), matrix()) + /// DMI used by unsmoothed turfs for variance + var/variant_dmi = null + /// Amount of variants this turf has + var/variant_num = 8 + +/turf/open/misc/asteroid/basalt/smooth/set_smoothed_icon_state(new_junction) + . = ..() + if (new_junction == 255 && variant_dmi) + icon = variant_dmi + icon_state = "[base_icon_state][rand(1, variant_num)]" + else + icon = initial(icon) + +/turf/open/misc/asteroid/basalt/smooth/update_overlays() + . = ..() + if (smoothing_junction != 255 && variant_dmi) + . = list(mutable_appearance(variant_dmi, "[base_icon_state][rand(1, variant_num)]")) + . + +/turf/open/misc/asteroid/basalt/smooth/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) + . = ..() + if (!.) + return + if(!smoothing_flags) + return + underlay_appearance.transform = transform + +/turf/open/misc/asteroid/basalt/smooth/siderite + name = "siderite floor" + baseturfs = /turf/open/misc/asteroid/basalt/smooth/siderite + icon = 'icons/turf/floors/siderite.dmi' + damaged_dmi = 'icons/turf/floors/siderite_variants.dmi' + variant_dmi = 'icons/turf/floors/siderite_variants.dmi' + icon_state = "siderite-255" + base_icon_state = "siderite" + layer = HIGH_TURF_LAYER + smoothing_groups = SMOOTH_GROUP_TURF_OPEN + SMOOTH_GROUP_FLOOR_SIDERITE + canSmoothWith = SMOOTH_GROUP_FLOOR_SIDERITE + SMOOTH_GROUP_CLOSED_TURFS + dig_result = /obj/item/stack/ore/glass/siderite + +/turf/open/misc/asteroid/basalt/smooth/siderite/lava_land_surface + initial_gas_mix = LAVALAND_DEFAULT_ATMOS + planetary_atmos = TRUE + baseturfs = /turf/open/lava/smooth/lava_land_surface + +/turf/open/misc/asteroid/basalt/smooth/siderite/lava_land_surface/no_ruins + turf_flags = NO_RUINS + +/turf/open/misc/asteroid/basalt/smooth/shale + name = "shale floor" + baseturfs = /turf/open/misc/asteroid/basalt/smooth/shale + icon = 'icons/turf/floors/shale.dmi' + damaged_dmi = 'icons/turf/floors/shale_variants.dmi' + variant_dmi = 'icons/turf/floors/shale_variants.dmi' + icon_state = "shale-255" + base_icon_state = "shale" + smoothing_groups = SMOOTH_GROUP_TURF_OPEN + SMOOTH_GROUP_FLOOR_SHALE + canSmoothWith = SMOOTH_GROUP_FLOOR_SHALE + SMOOTH_GROUP_CLOSED_TURFS + +/turf/open/misc/asteroid/basalt/smooth/shale/lava_land_surface + initial_gas_mix = LAVALAND_DEFAULT_ATMOS + planetary_atmos = TRUE + baseturfs = /turf/open/lava/smooth/lava_land_surface + +/turf/open/misc/asteroid/basalt/smooth/shale/lava_land_surface/no_ruins + turf_flags = NO_RUINS + /turf/open/misc/asteroid/snow gender = PLURAL name = "snow" diff --git a/code/game/turfs/open/floor/plating.dm b/code/game/turfs/open/floor/plating.dm index 2a440db7c74..7718f4b143e 100644 --- a/code/game/turfs/open/floor/plating.dm +++ b/code/game/turfs/open/floor/plating.dm @@ -150,6 +150,10 @@ upgradable = FALSE attachment_holes = FALSE +/turf/open/floor/plating/foam/Initialize(mapload) + . = ..() + AddElement(/datum/element/tool_blocker, TOOL_WELDER, TOOL_ACT_PRIMARY) + /turf/open/floor/plating/foam/burn_tile() return //jetfuel can't melt steel foam @@ -197,9 +201,6 @@ ScrapeAway(flags = CHANGETURF_INHERIT_AIR) return TRUE -/turf/open/floor/plating/foam/welder_act(mob/living/user, obj/item/I) - return NONE // Fuck you - //reinforced plating deconstruction states #define PLATE_INTACT 0 #define PLATE_BOLTS_LOOSENED 1 diff --git a/code/game/turfs/open/openspace.dm b/code/game/turfs/open/openspace.dm index f72423d1432..68c60752d4e 100644 --- a/code/game/turfs/open/openspace.dm +++ b/code/game/turfs/open/openspace.dm @@ -191,7 +191,7 @@ if(!ismineralturf(T) || !drill_below) return var/turf/closed/mineral/M = T - M.mineralAmt = 0 + M.mineral_amt = 0 M.gets_drilled() baseturfs = /turf/open/openspace/icemoon //This is to ensure that IF random turf generation produces a openturf, there won't be other turfs assigned other than openspace. diff --git a/code/game/turfs/open/river.dm b/code/game/turfs/open/river.dm index 2540699c586..07450383bef 100644 --- a/code/game/turfs/open/river.dm +++ b/code/game/turfs/open/river.dm @@ -5,7 +5,6 @@ #define RANDOM_LOWER_Y 50 /proc/spawn_rivers(target_z, nodes, turf_type, whitelist_area, min_x = RANDOM_LOWER_X, min_y = RANDOM_LOWER_Y, max_x = RANDOM_UPPER_X, max_y = RANDOM_UPPER_Y) - var/list/river_nodes = list() var/num_spawned = 0 var/width = max_x - min_x var/height = max_y - min_y @@ -16,19 +15,19 @@ var/area/A = get_area(T) if(!istype(A, whitelist_area) || (T.turf_flags & NO_LAVA_GEN)) possible_locs -= T - else - river_nodes += new /obj/effect/landmark/river_waypoint(T) - num_spawned++ + continue + new /obj/effect/landmark/river_waypoint(T) + num_spawned++ //make some randomly pathing rivers - for(var/obj/effect/landmark/river_waypoint/waypoints as anything in river_nodes) + for(var/obj/effect/landmark/river_waypoint/waypoints as anything in GLOB.river_waypoint_list["[target_z]"]) if (waypoints.z != target_z || waypoints.connected) continue waypoints.connected = TRUE // Workaround around ChangeTurf that's safe because of when this proc is called var/turf/cur_turf = get_turf(waypoints) cur_turf = new turf_type(cur_turf) - var/turf/target_turf = get_turf(pick(river_nodes - waypoints)) + var/turf/target_turf = get_turf(pick(GLOB.river_waypoint_list["[target_z]"] - waypoints)) if(!target_turf) break var/detouring = FALSE @@ -55,20 +54,28 @@ cur_dir = get_dir(cur_turf, target_turf) cur_turf = get_step(cur_turf, cur_dir) continue - else - // Workaround around ChangeTurf that's safe because of when this proc is called - var/turf/river_turf = new turf_type(cur_turf) - river_turf.Spread(25, 11, whitelist_area) - for(var/waypoints_spawned in river_nodes) - qdel(waypoints_spawned) + // Workaround around ChangeTurf that's safe because of when this proc is called + var/turf/river_turf = new turf_type(cur_turf) + river_turf.Spread(25, 11, whitelist_area) + for(var/obj/effect/landmark/river_waypoint/waypoint as anything in GLOB.river_waypoint_list["[target_z]"]) + qdel(waypoint) + + GLOB.river_waypoint_list -= "[target_z]" /obj/effect/landmark/river_waypoint name = "river waypoint" var/connected = FALSE invisibility = INVISIBILITY_ABSTRACT +/obj/effect/landmark/river_waypoint/Initialize(mapload) + . = ..() + LAZYADD(GLOB.river_waypoint_list["[z]"], src) + +/obj/effect/landmark/river_waypoint/Destroy() + LAZYREMOVE(GLOB.river_waypoint_list["[z]"], src) + return ..() /turf/proc/Spread(probability = 30, prob_loss = 25, whitelisted_area) if(probability <= 0) diff --git a/code/game/turfs/open/water.dm b/code/game/turfs/open/water.dm index 35678cc45ad..ecf75011189 100644 --- a/code/game/turfs/open/water.dm +++ b/code/game/turfs/open/water.dm @@ -138,6 +138,20 @@ /turf/open/water/lavaland_atmos initial_gas_mix = LAVALAND_DEFAULT_ATMOS +/turf/open/water/lavaland_atmos/basalt + icon = 'icons/turf/floors/water_lavaland.dmi' + icon_state = "water_lavaland-255" + base_icon_state = "water_lavaland" + smoothing_flags = SMOOTH_BITMASK | SMOOTH_BORDER + smoothing_groups = SMOOTH_GROUP_TURF_OPEN + SMOOTH_GROUP_FLOOR_WATER_LAVALAND + canSmoothWith = SMOOTH_GROUP_FLOOR_WATER_LAVALAND + fishing_datum = /datum/fish_source/ocean + +/turf/open/water/lavaland_atmos/basalt/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/water/beach/tizira desc = "Shallow water. It somehow reminds you of lizardfolk." icon_state = "tizira_water" diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index ca126bc69b5..7c70b219709 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -67,7 +67,7 @@ GLOBAL_LIST_EMPTY(station_turfs) var/tmp/lighting_corners_initialised = FALSE ///Our lighting object. - var/tmp/datum/lighting_object/lighting_object + var/tmp/atom/movable/lighting_object/lighting_object ///Lighting Corner datums. var/tmp/datum/lighting_corner/lighting_corner_NE var/tmp/datum/lighting_corner/lighting_corner_SE diff --git a/code/game/world.dm b/code/game/world.dm index ec5f3fd1c9e..3523d674f3e 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -126,12 +126,7 @@ GLOBAL_VAR(restart_counter) * All atoms in both compiled and uncompiled maps are initialized() */ /world/New() - log_world("World loaded at [time_stamp()]!") - - // From a really fucking old commit (91d7150) - // I wanted to move it but I think this needs to be after /world/New is called but before any sleeps? - // - Dominion/Cyberboss - GLOB.timezoneOffset = world.timezone * 36000 + log_world("World loaded at [server_timestamp()]!") // First possible sleep() InitTgs() @@ -170,8 +165,6 @@ GLOBAL_VAR(restart_counter) // Initialize RETA system - code/modules/reta/reta_system.dm reta_init_config() - LoadVerbs(/datum/verbs/menu) - if(fexists(RESTART_COUNTER_PATH)) GLOB.restart_counter = text2num(trim(file2text(RESTART_COUNTER_PATH))) fdel(RESTART_COUNTER_PATH) @@ -246,7 +239,7 @@ GLOBAL_VAR(restart_counter) GLOB.picture_logging_prefix += "R_[GLOB.round_id]_" GLOB.picture_log_directory += "[GLOB.round_id]" else - var/timestamp = replacetext(time_stamp(), ":", ".") + var/timestamp = replacetext(server_timestamp(), ":", ".") GLOB.log_directory += "[timestamp]" GLOB.public_log_directory += "[timestamp]" // BUBBER EDIT ADDITION GLOB.picture_log_directory += "[timestamp]" @@ -379,14 +372,14 @@ GLOBAL_VAR_INIT(last_maptick_time, 0) return #else if(check_hard_reboot()) - log_world("World hard rebooted at [time_stamp()]") + log_world("World hard rebooted at [server_timestamp()]") shutdown_logging() // See comment below. QDEL_NULL(Tracy) QDEL_NULL(Debugger) TgsEndProcess() return ..() - log_world("World rebooted at [time_stamp()]") + log_world("World rebooted at [server_timestamp()]") shutdown_logging() // Past this point, no logging procs can be used, at risk of data loss. QDEL_NULL(Tracy) @@ -443,7 +436,7 @@ GLOBAL_VAR_INIT(last_maptick_time, 0) else if(SSticker.current_state == GAME_STATE_SETTING_UP) new_status += "
Starting: Now" else if(SSticker.IsRoundInProgress()) - new_status += "
Time: [time2text(STATION_TIME_PASSED(), "hh:mm", NO_TIMEZONE)]" + new_status += "
Time: [round_timestamp("hh:mm")]" if(SSshuttle?.emergency && SSshuttle?.emergency?.mode != (SHUTTLE_IDLE || SHUTTLE_ENDGAME)) new_status += " | Shuttle: [SSshuttle.emergency.getModeStr()] [SSshuttle.emergency.getTimerStr()]" else if(SSticker.current_state == GAME_STATE_FINISHED) diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm index 75c5176c844..b118b0beb4a 100644 --- a/code/modules/admin/admin_investigate.dm +++ b/code/modules/admin/admin_investigate.dm @@ -10,7 +10,7 @@ var/mob/living/source_mob = src source += " ([source_mob.ckey ? source_mob.ckey : "*no key*"])" - WRITE_FILE(F, "[time_stamp(format = "YYYY-MM-DD hh:mm:ss")] [REF(src)] ([x],[y],[z]) || [source] [message]
") + WRITE_FILE(F, "[server_timestamp(format = "YYYY-MM-DD hh:mm:ss")] [REF(src)] ([x],[y],[z]) || [source] [message]
") ADMIN_VERB(investigate_show, R_NONE, "Investigate", "Browse various detailed logs.", ADMIN_CATEGORY_GAME) var/static/list/investigates = list( diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 77af0c72fb9..62f07be0679 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -1,3 +1,6 @@ + +#define STEALTH_MODE_TRAIT "stealth_mode" + /client/proc/add_admin_verbs() control_freak = CONTROL_FREAK_SKIN | CONTROL_FREAK_MACROS SSadmin_verbs.assosciate_admin(src) @@ -27,31 +30,93 @@ ADMIN_VERB(admin_ghost, R_ADMIN, "AGhost", "Become a ghost without DNR.", ADMIN_ ghost.reenter_corpse() BLACKBOX_LOG_ADMIN_VERB("Admin Reenter") else if(isnewplayer(user.mob)) - to_chat(user, "Error: Aghost: Can't admin-ghost whilst in the lobby. Join or Observe first.", confidential = TRUE) + to_chat(user, span_warning("Error: Aghost: Can't admin-ghost whilst in the lobby. Join or Observe first."), confidential = TRUE) return FALSE else //ghostize log_admin("[key_name(user)] admin ghosted.") message_admins("[key_name_admin(user)] admin ghosted.") var/mob/body = user.mob - body.ghostize(TRUE, TRUE) + var/mob/dead/observer/ghost = body.ghostize(TRUE, TRUE) user.init_verbs() if(body && !body.key) body.key = "@[user.key]" //Haaaaaaaack. But the people have spoken. If it breaks; blame adminbus + // Carry over invisimin to their aghost + var/is_stealth_mode = user.holder.fakekey + var/is_invisimin = HAS_TRAIT_FROM(body, TRAIT_INVISIMIN, ADMIN_TRAIT) + if(is_stealth_mode || is_invisimin) + if(is_invisimin) + ADD_TRAIT(ghost, TRAIT_INVISIMIN, ADMIN_TRAIT) + ghost.SetInvisibility(INVISIBILITY_ADMIN, INVISIBILITY_SOURCE_INVISIMIN, INVISIBILITY_PRIORITY_ADMIN) + else + ghost.SetInvisibility(INVISIBILITY_ABSTRACT, INVISIBILITY_SOURCE_STEALTHMODE, INVISIBILITY_PRIORITY_ADMIN) + ghost.name = " " + ghost.mouse_opacity = MOUSE_OPACITY_TRANSPARENT + ghost.alpha = 0 + ghost.remove_from_all_data_huds() + ADD_TRAIT(ghost, TRAIT_ORBITING_FORBIDDEN, is_invisimin ? ADMIN_TRAIT : STEALTH_MODE_TRAIT) + QDEL_NULL(ghost.orbiters) + BLACKBOX_LOG_ADMIN_VERB("Admin Ghost") ADMIN_VERB(invisimin, R_ADMIN, "Invisimin", "Toggles ghost-like invisibility.", ADMIN_CATEGORY_GAME) + // Toggle OFF if(HAS_TRAIT(user.mob, TRAIT_INVISIMIN)) - REMOVE_TRAIT(user.mob, TRAIT_INVISIMIN, ADMIN_TRAIT) + user.mob.remove_traits(list( + TRAIT_INVISIMIN, + TRAIT_ORBITING_FORBIDDEN, + TRAIT_MOVE_PHASING, + TRAIT_PIERCEIMMUNE, + TRAIT_INVISIBLE_TO_CAMERA, + ), ADMIN_TRAIT) user.mob.add_to_all_human_data_huds() user.mob.RemoveInvisibility(INVISIBILITY_SOURCE_INVISIMIN) to_chat(user, span_adminnotice(span_bold("Invisimin off. Invisibility reset.")), confidential = TRUE) + if(isobserver(user.mob) && !user.holder.fakekey) // Set the alpha back if we're not still stealth mode + user.mob.alpha = initial(user.mob.alpha) return - ADD_TRAIT(user.mob, TRAIT_INVISIMIN, ADMIN_TRAIT) + // Toggle ON + user.mob.add_traits(list( + TRAIT_INVISIMIN, + TRAIT_ORBITING_FORBIDDEN, + TRAIT_MOVE_PHASING, + TRAIT_PIERCEIMMUNE, + TRAIT_INVISIBLE_TO_CAMERA, + ), ADMIN_TRAIT) user.mob.remove_from_all_data_huds() - user.mob.SetInvisibility(INVISIBILITY_OBSERVER, INVISIBILITY_SOURCE_INVISIMIN, INVISIBILITY_PRIORITY_ADMIN) - to_chat(user, span_adminnotice(span_bold("Invisimin on. You are now as invisible as a ghost.")), confidential = TRUE) + user.mob.SetInvisibility(INVISIBILITY_ADMIN, INVISIBILITY_SOURCE_INVISIMIN, INVISIBILITY_PRIORITY_ADMIN) + if(isobserver(user.mob)) + user.mob.alpha = 0 + QDEL_NULL(user.mob.orbiters) + to_chat(user, span_adminnotice(span_bold("Invisimin on. You are now invisible to players and ghosts.")), confidential = TRUE) + +ADMIN_VERB(toggle_admin_esp, R_ADMIN, "Toggle Admin ESP", "Toggle to be able to see ghosts and invisimins.", ADMIN_CATEGORY_GAME) + // Toggle OFF + if(HAS_TRAIT(user.mob, TRAIT_ADMIN_ESP)) + if(isliving(user.mob)) + var/mob/living/living_user = user.mob + living_user.remove_status_effect(/datum/status_effect/admin_esp) + else if(isobserver(user.mob)) + user.mob.set_invis_see(SEE_INVISIBLE_OBSERVER) + else + user.mob.set_invis_see(SEE_INVISIBLE_LIVING) + REMOVE_TRAIT(user.mob, TRAIT_ADMIN_ESP, ADMIN_TRAIT) + to_chat(user.mob, span_adminnotice("Admin ESP off. You will no longer see [isliving(user.mob) ? "ghosts or " : ""]invisimins."), confidential = TRUE) + return + + // Toggle ON + if(isliving(user.mob)) + var/mob/living/living_user = user.mob + living_user.apply_status_effect(/datum/status_effect/admin_esp) + else if(ismob(user.mob)) + user.mob.set_invis_see(SEE_INVISIBLE_ADMIN) + else + to_chat(user.mob, span_warning("Admin ESP only works if you are in a mob!"), confidential = TRUE) + return + + ADD_TRAIT(user.mob, TRAIT_ADMIN_ESP, ADMIN_TRAIT) + to_chat(user.mob, span_adminnotice("Admin ESP on. You will now be able to see [isliving(user.mob) ? "ghosts and " : ""]invisimins."), confidential = TRUE) ADMIN_VERB(check_antagonists, R_ADMIN, "Check Antagonists", "See all antagonists for the round.", ADMIN_CATEGORY_GAME) user.holder.check_antagonists() @@ -141,8 +206,6 @@ ADMIN_VERB(stealth, R_STEALTH, "Stealth Mode", "Toggle stealth.", ADMIN_CATEGORY BLACKBOX_LOG_ADMIN_VERB("Stealth Mode") -#define STEALTH_MODE_TRAIT "stealth_mode" - /client/proc/enable_stealth_mode() var/new_key = ckeyEx(stripped_input(usr, "Enter your desired display name.", "Fake Key", key, 26)) if(!new_key) @@ -165,7 +228,8 @@ ADMIN_VERB(stealth, R_STEALTH, "Stealth Mode", "Toggle stealth.", ADMIN_CATEGORY holder.fakekey = null if(isobserver(mob)) mob.RemoveInvisibility(INVISIBILITY_SOURCE_STEALTHMODE) - mob.alpha = initial(mob.alpha) + if(!HAS_TRAIT_FROM(mob, TRAIT_INVISIMIN, ADMIN_TRAIT)) // Don't reset our alpha if we're also invisimin'd + mob.alpha = initial(mob.alpha) if(mob.mind) if(mob.mind.ghostname) mob.name = mob.mind.ghostname @@ -180,8 +244,6 @@ ADMIN_VERB(stealth, R_STEALTH, "Stealth Mode", "Toggle stealth.", ADMIN_CATEGORY log_admin("[key_name(usr)] has turned stealth mode OFF") message_admins("[key_name_admin(usr)] has turned stealth mode OFF") -#undef STEALTH_MODE_TRAIT - ADMIN_VERB(drop_bomb, R_FUN, "Drop Bomb", "Cause an explosion of varying strength at your location", ADMIN_CATEGORY_FUN) var/list/choices = list("Small Bomb (1, 2, 3, 3)", "Medium Bomb (2, 3, 4, 4)", "Big Bomb (3, 5, 7, 5)", "Maxcap", "Custom Bomb") var/choice = tgui_input_list(user, "What size explosion would you like to produce? NOTE: You can do all this rapidly and in an IC manner (using cruise missiles!) with the Config/Launch Supplypod verb. WARNING: These ignore the maxcap", "Drop Bomb", choices) @@ -803,11 +865,18 @@ ADMIN_VERB(give_ai_speech, R_FUN, "Give Random AI Speech", ADMIN_VERB_NO_DESCRIP return our_controller.planning_subtrees = list(GLOB.ai_subtrees[/datum/ai_planning_subtree/random_speech/blackboard]) + our_controller.planning_subtrees +ADMIN_VERB(open_event_logger, R_DEBUG, "Open Event Logger", "Open the event logger interface.", ADMIN_CATEGORY_DEBUG) + GLOB.event_logger.ui_interact(user.mob) + ADMIN_VERB(new_blackmarket_item, R_BUILD, "Create Black Market Item", "Add an item to the black market for purchase.", ADMIN_CATEGORY_EVENTS, object as text) + if(!object) + to_chat(user, span_boldwarning("Failed! Provide a full or partial typepath!")) + return //first: have admins select a typepath for the item they want to offer. var/obj/chosen = pick_closest_path(object, make_types_fancy(subtypesof(/obj))) // second: poll admins for the name, description, price, and quantity. - + if(isnull(chosen)) + return var/name = tgui_input_text(user, "Name of the item to sell?", "Item listing name", "Arcane Object", max_length = MAX_NAME_LEN) if(isnull(name)) return @@ -842,5 +911,9 @@ ADMIN_VERB(new_blackmarket_item, R_BUILD, "Create Black Market Item", "Add an it SSmarket.initialize_admin_item(admin_item) log_admin("[key_name(user)] created a new black market item: [name] ([chosen]) for [price] credits, of quantity [quantity].") + message_admins("[key_name(user)] created a new black market item: [name] ([chosen]) for [price] credits, of quantity [quantity].") BLACKBOX_LOG_ADMIN_VERB("Create Black Market Item") + + +#undef STEALTH_MODE_TRAIT diff --git a/code/modules/admin/event_logger.dm b/code/modules/admin/event_logger.dm new file mode 100644 index 00000000000..cd943db8d30 --- /dev/null +++ b/code/modules/admin/event_logger.dm @@ -0,0 +1,551 @@ +/// Global event logger datum, accessible anywhere for debug logging. +GLOBAL_DATUM_INIT(event_logger, /datum/event_logger, new()) + +/// Enables event logging for a datum. If display_on is supplied then it will report the events as if theyre happening on that datum +/datum/proc/enable_evlogging(datum/display_on = null) + if(display_on) + GLOB.event_logger.display_map[REF(src)] = REF(display_on) + if(datum_flags & DF_EVLOGGING) + return + datum_flags |= DF_EVLOGGING + SEND_SIGNAL(src, COMSIG_EVLOGGING_ENABLED) + +/// Disables event logging for a datum. If display_on was supplied during enable_evlogging, it will also remove the display mapping. +/datum/proc/disable_evlogging() + GLOB.event_logger.display_map -= REF(src) + if(!(datum_flags & DF_EVLOGGING)) + return + datum_flags &= ~DF_EVLOGGING + SEND_SIGNAL(src, COMSIG_EVLOGGING_DISABLED) + + +///Datum that holds info for a single track of events in the logger. Each track represents a datum that is being tracked. This track is shown in the timeline and when selected shows information on the track. +/datum/event_logger_track + /// Display name for this track row. + var/name + /// String ref key used to identify this track. + var/ref + /// List of event assoc lists: id, tick, category, kind, info, + kind-specific fields. + var/list/events = list() + /// Assoc list of string (Title) -> string (Info) displayed in the info panel when this track is selected. + var/list/info = list() + +/datum/event_logger_track/New(track_ref, track_name, list/info_data = list()) + ref = track_ref + name = track_name + info = info_data + +/datum/event_logger_track/Destroy() + events = null + info = null + return ..() + +///Datum for the event logger. One of these is made, and everyone shares it. So be nice. This keeps tracks of everything related to the logger +/datum/event_logger + /// Whether the logger is actively recording. + var/running = FALSE + /// world.time at which logging first started (null until first start). + var/time_start = null + /// Assoc list: category name -> enabled (TRUE/FALSE). + var/list/categories = list() + /// Assoc list: category name -> hex color, assigned when a category is first seen. + var/list/category_colors = list() + + /// List of colors we use for categories. We loop around once we run out + var/list/category_palette = list( + "#4fc3f7", "#81c784", "#ffb74d", "#e57373", "#ba68c8", + "#4dd0e1", "#fff176", "#f06292", "#a1887f", "#90a4ae", + ) + /// Assoc list: ref string -> /datum/event_logger_track + var/list/tracks = list() + /// Assoc list: string event id -> event assoc list, for quick look-up when selecting events + var/list/events_by_id = list() + /// Incrementing id assigned to each logged event. + var/next_event_id = 0 + /// Ref string of the currently selected track (for the info panel). + var/selected_ref = null + /// Assoc list: mob -> list of /image, for overlay cleanup. + var/list/user_overlays = list() + /// The mob currently waiting to click a target for pick-target mode, or null. + var/mob/awaiting_pick_user = null + /// Assoc list: REF(source datum) -> REF(display datum). Events from the source appear under the display datum's track. + var/list/display_map = list() + +/datum/event_logger/Destroy() + _clear_all_overlays() + QDEL_LIST_ASSOC_VAL(tracks) + tracks = null + categories = null + user_overlays = null + display_map = null + return ..() + +/datum/event_logger/proc/start() + if(running) + return + running = TRUE + if(isnull(time_start)) + time_start = world.time + +/datum/event_logger/proc/stop() + running = FALSE + +/// Enter pick-target mode: the next atom the user clicks gets DF_EVLOGGING set. +/datum/event_logger/proc/toggle_pick_target(mob/user) + if(awaiting_pick_user) + _end_pick_target() + else + awaiting_pick_user = user + RegisterSignal(user, COMSIG_MOB_CLICKON, PROC_REF(on_pick_target_click)) + +/// Signal handler: fired when the user clicks something while in pick-target mode. +/datum/event_logger/proc/on_pick_target_click(mob/source, atom/clicked, list/modifiers) + SIGNAL_HANDLER + clicked.enable_evlogging() + _end_pick_target() + return NONE + +/// Ends pick-target mode, unregistering the click signal and clearing the awaiting_pick_user var. +/datum/event_logger/proc/_end_pick_target() + if(isnull(awaiting_pick_user)) + return + UnregisterSignal(awaiting_pick_user, COMSIG_MOB_CLICKON) + awaiting_pick_user = null + +/// Ensures a track exists for ref_string. Safe to call multiple times. +/datum/event_logger/proc/add_track(ref_string, track_name, list/info_data) + if(tracks[ref_string]) + return + tracks[ref_string] = new /datum/event_logger_track(ref_string, track_name, info_data) + +/// Internal: Sets the event up, making a track if necesary. Also turns the instance into a REF() at this point +/datum/event_logger/proc/_add_event(datum/source, list/event_data) + if(!running) + return + // Resolve display routing: if source has a display_on target, log under that datum's track instead + var/datum/display_target + var/display_ref = display_map[REF(source)] + if(display_ref) + display_target = locate(display_ref) + if(!display_target) // display_on was deleted, remove the stale entry. Yeah this is a bit lame, but I felt like registering QDEL might be more of a hassle if we're using REF() anyway. Feel free to @ me over it + display_map -= REF(source) + + var/datum/track_datum = display_target || source + var/ref_string = REF(track_datum) + if(!tracks[ref_string]) + var/track_name + if(isatom(track_datum)) + var/atom/resolved_atom = track_datum + track_name = "[ref_string] [resolved_atom] [track_datum.type]" + else + track_name = "[ref_string] [track_datum.type]" + add_track(ref_string, track_name, null) + var/datum/event_logger_track/track = tracks[ref_string] + event_data["id"] = ++next_event_id + event_data["tick"] = world.time + var/category = event_data["category"] + if(!isnull(category) && isnull(categories[category])) + categories[category] = TRUE + + var/selected_index = (length(category_colors) + 1) % (length(category_palette) + 1) + + category_colors[category] = category_palette[selected_index] + track.events += list(event_data) + events_by_id["[event_data["id"]]"] = event_data + SEND_SIGNAL(source, COMSIG_EVLOG_EVENT_ADDED, track, event_data) + if(display_target) + SEND_SIGNAL(display_target, COMSIG_EVLOG_EVENT_ADDED, track, event_data) + +/// Log a plain text event. Has no world-visuals, just puts text into the menu +/datum/event_logger/proc/log_event_text(datum/source, category, info_string) + _add_event(source, list( + "log_type" = EVLOG_TYPE_TEXT, + "category" = category, + "info" = info_string, + )) + +/// Log a location event (highlights a single tile). I should remove this one as turfs does the same thing essentially +/datum/event_logger/proc/log_event_location(datum/source, category, info_string, turf/T) + _add_event(source, list( + "log_type" = EVLOG_TYPE_LOCATION, + "category" = category, + "info" = info_string, + "x" = T.x, + "y" = T.y, + "z" = T.z, + )) + +/// Log a turfs event (highlights a set of tiles). +/datum/event_logger/proc/log_event_turfs(datum/source, category, info_string, list/turfs) + var/list/coords = list() + for(var/turf/T as anything in turfs) + coords += list(list("x" = T.x, "y" = T.y, "z" = T.z)) + _add_event(source, list( + "log_type" = EVLOG_TYPE_TURFS, + "category" = category, + "info" = info_string, + "coords" = coords, + )) + +/// Log a line event (draws a line between 2 turfs). +/datum/event_logger/proc/log_event_lines(datum/source, category, info_string, turf/A, turf/B) + _add_event(source, list( + "log_type" = EVLOG_TYPE_LINES, + "category" = category, + "info" = info_string, + "x1" = A.x, + "y1" = A.y, + "z1" = A.z, + "x2" = B.x, + "y2" = B.y, + "z2" = B.z, + )) + +/// Log a path event (renders directional arrows + start/end markers for a list of turfs in order from start to finish). +/datum/event_logger/proc/log_event_path(datum/source, category, info_string, list/turfs) + var/list/coords = list() + for(var/turf/T as anything in turfs) + coords += list(list("x" = T.x, "y" = T.y, "z" = T.z)) + _add_event(source, list( + "log_type" = EVLOG_TYPE_PATH, + "category" = category, + "info" = info_string, + "coords" = coords, + )) + +/// Log a maptext event (renders a floating text label at the turf when selected). text_string is the string to display at the turf. +/datum/event_logger/proc/log_event_maptext(datum/source, category, info_string, turf/T, text_string) + _add_event(source, list( + "log_type" = EVLOG_TYPE_MAPTEXT, + "category" = category, + "info" = info_string, + "x" = T.x, + "y" = T.y, + "z" = T.z, + "text" = text_string, + )) + +/// Remove all overlays for a specific user. +/datum/event_logger/proc/_clear_user_overlays(mob/user) + if(!user_overlays[user]) + return + if(user.client) + user.client.images -= user_overlays[user] + user_overlays -= user + +/// Remove all overlays for all users. +/datum/event_logger/proc/_clear_all_overlays() + for(var/mob/user as anything in user_overlays) + _clear_user_overlays(user) + +/// Push world-space highlight overlays to the user's client for the given events. +/datum/event_logger/proc/_apply_event_overlays(mob/user, list/events_to_show) + _clear_user_overlays(user) + if(!user.client || !length(events_to_show)) + return + + var/list/images = list() + + for(var/list/evt as anything in events_to_show) + var/color = get_category_color(evt["category"]) + var/log_type = evt["log_type"] + + if(log_type == EVLOG_TYPE_LOCATION) + var/turf/found_turf = locate(evt["x"], evt["y"], evt["z"]) + if(found_turf) + images += _make_tile_image(found_turf, "box_overlay", color, 0.3) + + else if(log_type == EVLOG_TYPE_TURFS) + var/list/coords = evt["coords"] + for(var/list/coord as anything in coords) + var/turf/found_turf = locate(coord["x"], coord["y"], coord["z"]) + if(found_turf) + images += _make_tile_image(found_turf, "box_overlay", color, 0.3) + + else if(log_type == EVLOG_TYPE_LINES) + var/turf/turf_A = locate(evt["x1"], evt["y1"], evt["z1"]) + var/turf/turf_B = locate(evt["x2"], evt["y2"], evt["z2"]) + if(turf_A && turf_B && turf_A != turf_B) + images += _make_line_images(turf_A, turf_B, color) + + //Use SSPathfinder to render the full path + else if(log_type == EVLOG_TYPE_PATH) + var/list/path_turfs = list() + var/list/coords = evt["coords"] + for(var/list/coord as anything in coords) + var/turf/found_turf = locate(coord["x"], coord["y"], coord["z"]) + if(found_turf) + path_turfs += found_turf + images += SSpathfinder.render_path_images_full(path_turfs) + + //Draw maptext on a turf which lets us show important events in-world + else if(log_type == EVLOG_TYPE_MAPTEXT) + var/turf/found_turf = locate(evt["x"], evt["y"], evt["z"]) + if(found_turf) + var/image/img = image('icons/turf/debug.dmi', found_turf, "circle", PATH_DEBUG_LAYER) + SET_PLANE_EXPLICIT(img, BALLOON_CHAT_PLANE, found_turf) + img.color = color + img.maptext = MAPTEXT(evt["text"]) + img.maptext_width = 200 + img.maptext_height = 64 + img.maptext_x = 0 + img.maptext_y = 32 + images += img + + if(length(images)) + user_overlays[user] = images + user.client.images += images + +///Draw a line of images similar to beams but client-side. I couldn't find anything like this yet so here we are. Maybe making this a global is a good idea. +/datum/event_logger/proc/_make_line_images(turf/turf_A, turf/turf_B, color) + var/list/images = list() + var/beam_icon = 'icons/turf/debug.dmi' + var/beam_icon_state = "beam" + + var/origin_px = turf_A.pixel_x + turf_A.pixel_w + var/origin_py = turf_A.pixel_y + turf_A.pixel_z + var/target_px = turf_B.pixel_x + turf_B.pixel_w + var/target_py = turf_B.pixel_y + turf_B.pixel_z + + var/Angle = get_angle_raw(turf_A.x, turf_A.y, origin_px, origin_py, turf_B.x, turf_B.y, target_px, target_py) + var/matrix/rot_matrix = matrix() + rot_matrix.Turn(Angle) + + var/DX = (ICON_SIZE_X * turf_B.x + target_px) - (ICON_SIZE_X * turf_A.x + origin_px) + var/DY = (ICON_SIZE_Y * turf_B.y + target_py) - (ICON_SIZE_Y * turf_A.y + origin_py) + var/line_length = round(sqrt(DX ** 2 + DY ** 2)) + + for(var/N in 0 to line_length - 1 step 32) + var/Pixel_x + var/Pixel_y + if(DX == 0) + Pixel_x = 0 + else + Pixel_x = round(sin(Angle) + ICON_SIZE_X * sin(Angle) * (N + 16) / 32) + if(DY == 0) + Pixel_y = 0 + else + Pixel_y = round(cos(Angle) + ICON_SIZE_Y * cos(Angle) * (N + 16) / 32) + + var/final_x = turf_A.x + var/final_y = turf_A.y + if(abs(Pixel_x) > ICON_SIZE_X) + final_x += Pixel_x > 0 ? round(Pixel_x / ICON_SIZE_X) : ceil(Pixel_x / ICON_SIZE_X) + Pixel_x %= ICON_SIZE_X + if(abs(Pixel_y) > ICON_SIZE_Y) + final_y += Pixel_y > 0 ? round(Pixel_y / ICON_SIZE_Y) : ceil(Pixel_y / ICON_SIZE_Y) + Pixel_y %= ICON_SIZE_Y + + var/turf/seg_turf = locate(final_x, final_y, turf_A.z) + if(!seg_turf) + continue + + var/image/img = image(beam_icon, seg_turf, beam_icon_state, PATH_DEBUG_LAYER) + SET_PLANE_EXPLICIT(img, BALLOON_CHAT_PLANE, seg_turf) + if(N + 32 > line_length) + // Terminal segment: crop the icon to avoid overshooting the target + var/icon/clipped = new(beam_icon, beam_icon_state) + clipped.DrawBox(null, 1, (line_length - N), 32, 32) + img.icon = clipped + img.color = color + img.transform = rot_matrix + img.pixel_x = origin_px + Pixel_x + img.pixel_y = origin_py + Pixel_y + images += img + + return images + + +/// Creates a single coloured tile overlay image. +/datum/event_logger/proc/_make_tile_image(turf/selected_turf, icon_state, color, alpha_fraction) + var/image/img = image('icons/turf/debug.dmi', selected_turf, icon_state, PATH_DEBUG_LAYER) + SET_PLANE_EXPLICIT(img, BALLOON_CHAT_PLANE, selected_turf) + img.color = color + img.alpha = round(alpha_fraction * 255) + return img + +/// Returns the hex color string for a category, or white if unknown. +/datum/event_logger/proc/get_category_color(category) + return category_colors[category] || "#ffffff" + +/// Clears all tracks, categories and overlays. +/datum/event_logger/proc/clear() + _clear_all_overlays() + QDEL_LIST_ASSOC_VAL(tracks) + tracks = list() + events_by_id = list() + categories = list() + category_colors = list() + next_event_id = 0 + selected_ref = null + time_start = null + running = FALSE + +///Tgui stuff below!! + + +/datum/event_logger/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/simple/chat_dark), + ) + +/datum/event_logger/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "EventLogger", "Event Logger") + ui.open() + +/datum/event_logger/ui_close(mob/user) + . = ..() + _clear_user_overlays(user) + if(awaiting_pick_user == user) + _end_pick_target() + +/datum/event_logger/ui_state(mob/user) + return ADMIN_STATE(R_DEBUG) + +/datum/event_logger/ui_data(mob/user) + var/list/data = list() + + data["running"] = running + data["time_start"] = time_start + data["time_current"] = world.time + data["selected_ref"] = selected_ref + data["awaiting_pick"] = !isnull(awaiting_pick_user) + + // Categories + var/list/cats = list() //meow + for(var/cat, enabled in categories) + cats += list(list("name" = cat, "enabled" = enabled)) + data["categories"] = cats + + // Tracks + var/list/track_list = list() + for(var/ref, track_val in tracks) + var/datum/event_logger_track/track = track_val + + // Converts track info to a list for tgui + var/list/info_pairs = list() + for(var/title, entry in track.info) + info_pairs += list(list("title" = title, "entry" = entry)) + + track_list += list(list( + "name" = track.name, + "ref" = track.ref, + "events" = track.events, + "info" = info_pairs, + )) + data["tracks"] = track_list + + return data + +/datum/event_logger/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + if(.) + return + + var/mob/user = ui.user + + switch(action) + if("toggle_running") //Start or stop the logger + if(running) + stop() + else + start() + return TRUE + + if("toggle_category") //Enable categories + var/cat = params["name"] + if(!isnull(categories[cat])) + categories[cat] = !categories[cat] + return TRUE + + if("select_track") //Select a track on the timeline + selected_ref = params["ref"] + return TRUE + + if("select_events") ///We selected events on the timeline, clear old overlays, add new ones. + var/list/ids = params["ids"] + if(!islist(ids) || !length(ids)) + _clear_user_overlays(user) + return TRUE + + var/list/matched = list() + for(var/id in ids) + var/list/evt = events_by_id["[id]"] + if(evt) + matched += list(evt) + + _apply_event_overlays(user, matched) + return TRUE + + if("clear") + clear() + return TRUE + + if("start_pick_target") + toggle_pick_target(user) + return TRUE + + if("disable_evlogging") + var/track_ref = params["ref"] + var/datum/target = locate(track_ref) + if(!target) + return FALSE + if(tgui_alert(user, "Stop tracking [target]?", "Confirm", list("Stop Tracking", "Cancel")) != "Stop Tracking") + return FALSE + target.disable_evlogging() + return TRUE + + if("remove_track") // Removes a track and all its events from the logger entirely, and stops tracking the datum + var/track_ref = params["ref"] + var/datum/event_logger_track/track = tracks[track_ref] + if(!track) + return FALSE + // Remove all events from events_by_id + for(var/list/evt as anything in track.events) + events_by_id -= "[evt["id"]]" + // Disable evlogging on the datum if it still exists + var/datum/target = locate(track_ref) + if(target) + target.disable_evlogging() + // Clear overlays and deselect if this was the selected track + _clear_user_overlays(user) + if(selected_ref == track_ref) + selected_ref = null + qdel(track) + tracks -= track_ref + return TRUE + + if("teleport_to_event") + var/target_id = params["id"] + var/list/found_evt = events_by_id["[target_id]"] + if(!found_evt) + return FALSE + var/dest_x + var/dest_y + var/dest_z + switch(found_evt["log_type"]) + if(EVLOG_TYPE_LOCATION, EVLOG_TYPE_MAPTEXT) + dest_x = found_evt["x"] + dest_y = found_evt["y"] + dest_z = found_evt["z"] + if(EVLOG_TYPE_TURFS, EVLOG_TYPE_PATH) + var/list/coords = found_evt["coords"] + if(!length(coords)) + return FALSE + var/list/first = coords[1] + dest_x = first["x"] + dest_y = first["y"] + dest_z = first["z"] + if(EVLOG_TYPE_LINES) + dest_x = found_evt["x1"] + dest_y = found_evt["y1"] + dest_z = found_evt["z1"] + else + return FALSE + var/turf/dest = locate(dest_x, dest_y, dest_z) + if(!dest) + return FALSE + user.forceMove(dest) + return TRUE diff --git a/code/modules/admin/greyscale_modify_menu.dm b/code/modules/admin/greyscale_modify_menu.dm index 0aef316b250..f309d79a6b6 100644 --- a/code/modules/admin/greyscale_modify_menu.dm +++ b/code/modules/admin/greyscale_modify_menu.dm @@ -348,7 +348,7 @@ This is highly likely to cause massive amounts of lag as every object in the gam return while(initial(current.greyscale_config) == initial(parent.greyscale_config)) current = parent - parent = type2parent(current) + parent = current::parent_type config_owner_type = current /// Used for spray painting items in the gags_recolorable component diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm index 18b96318f06..3b78e552740 100644 --- a/code/modules/admin/holder2.dm +++ b/code/modules/admin/holder2.dm @@ -36,6 +36,7 @@ GLOBAL_PROTECT(href_token) var/datum/particle_editor/particle_test var/datum/colorblind_tester/color_test var/datum/plane_master_debug/plane_debug + var/datum/appearance_debugger/appearance_debug var/obj/machinery/computer/libraryconsole/admin_only_do_not_map_in_you_fucker/library_manager var/datum/pathfind_debug/path_debug var/datum/spawn_menu/spawn_menu @@ -98,6 +99,7 @@ GLOBAL_PROTECT(href_token) GLOB.admin_datums[target] = src deadmined = FALSE plane_debug = new(src) + appearance_debug = new(src) if (GLOB.directory[target]) associate(GLOB.directory[target]) //find the client for a ckey if they are connected and associate them with us @@ -109,6 +111,7 @@ GLOBAL_PROTECT(href_token) GLOB.deadmins[target] = src GLOB.admin_datums -= target QDEL_NULL(plane_debug) + QDEL_NULL(appearance_debug) QDEL_NULL(path_debug) deadmined = TRUE @@ -119,6 +122,7 @@ GLOBAL_PROTECT(href_token) add_verb(client, /client/proc/readmin) client.disable_combo_hud() client.update_special_keybinds() + client.set_stat_panel() /datum/admins/proc/associate(client/client) if(IsAdminAdvancedProcCall()) @@ -159,6 +163,7 @@ GLOBAL_PROTECT(href_token) owner.init_verbs() //re-initialize the verb list owner.update_special_keybinds() GLOB.admins |= client + client.set_stat_panel() try_give_profiling() diff --git a/code/modules/admin/smites/hitsplat.dm b/code/modules/admin/smites/hitsplat.dm new file mode 100644 index 00000000000..dd4fcacb18a --- /dev/null +++ b/code/modules/admin/smites/hitsplat.dm @@ -0,0 +1,20 @@ +/datum/smite/hitsplat + name = "Hitsplat" + +/datum/smite/hitsplat/effect(client/user, mob/living/target) + . = ..() + target.AddComponent(/datum/component/hitsplat, /obj/effect/overlay/vis/hitsplat/lore_accurate) + + +// Dragon dagger spec spam. +/datum/smite/hitsplat/stackout + name = "Stackout (Hitsplat)" + +/datum/smite/hitsplat/stackout/effect(client/user, mob/living/target) + . = ..() + for(var/attack in 1 to 4) + playsound(target, SFX_SWING_HIT, 50, TRUE) + target.apply_damage(rand(0, 50)) + target.apply_damage(rand(0, 50)) + // dragon dagger has a 4 tick attack + sleep(2.4 SECONDS) diff --git a/code/modules/admin/spawn_panel/spawn_handling.dm b/code/modules/admin/spawn_panel/spawn_handling.dm index 265dd6c38da..46ba9534f1f 100644 --- a/code/modules/admin/spawn_panel/spawn_handling.dm +++ b/code/modules/admin/spawn_panel/spawn_handling.dm @@ -96,8 +96,8 @@ pod = new() for(var/i in 1 to amount) - if(istype(atom_to_spawn, /turf)) - var/turf/original_turf = target + if(ispath(atom_to_spawn, /turf)) + var/turf/original_turf = get_turf(target) //Get_turf is required here, because if target is not a turf we are cooked chat. var/turf/created_turf = original_turf.ChangeTurf(atom_to_spawn.type) if(created_turf && atom_name) created_turf.name = atom_name diff --git a/code/modules/admin/spawn_panel/spawn_panel.dm b/code/modules/admin/spawn_panel/spawn_panel.dm index a5cc42a4391..cdde4d0b902 100644 --- a/code/modules/admin/spawn_panel/spawn_panel.dm +++ b/code/modules/admin/spawn_panel/spawn_panel.dm @@ -196,9 +196,9 @@ admin_client.mouse_pointer_icon = admin_client.mouse_override_icon admin_client.click_intercept = src - winset(admin_client, "mapwindow.map", "right-click=true") + winset(admin_client, SKIN_MAPWINDOW_MAP, "right-click=true") else - winset(admin_client, "mapwindow.map", "right-click=false") + winset(admin_client, SKIN_MAPWINDOW_MAP, "right-click=false") var/mob/holder_mob = admin_client.mob holder_mob?.update_mouse_pointer() diff --git a/code/modules/admin/sql_ban_system.dm b/code/modules/admin/sql_ban_system.dm index 61c7078c745..b8ceed13924 100644 --- a/code/modules/admin/sql_ban_system.dm +++ b/code/modules/admin/sql_ban_system.dm @@ -426,6 +426,7 @@ ROLE_MALF, ROLE_NINJA, ROLE_OPERATIVE, + ROLE_CLOWN_OPERATIVE, ROLE_OVERTHROW, ROLE_PARADOX_CLONE, ROLE_REV, diff --git a/code/modules/admin/verbs/admin_newscaster.dm b/code/modules/admin/verbs/admin_newscaster.dm index e300150659b..ec96d8babce 100644 --- a/code/modules/admin/verbs/admin_newscaster.dm +++ b/code/modules/admin/verbs/admin_newscaster.dm @@ -311,7 +311,7 @@ ADMIN_VERB(access_news_network, R_ADMIN, "Access Newscaster Network", "Allows yo var/datum/feed_comment/new_feed_comment = new /datum/feed_comment new_feed_comment.author = "Centcom Official" new_feed_comment.body = comment_text - new_feed_comment.time_stamp = station_time_timestamp() + new_feed_comment.time_stamp = round_timestamp() current_message.comments += new_feed_comment GLOB.news_network.last_action ++ usr.log_message("(as an admin) commented on message [current_message.return_body(-1)] -- [current_message.body]", LOG_COMMENT) diff --git a/code/modules/admin/verbs/admingame.dm b/code/modules/admin/verbs/admingame.dm index 18829cca129..afbecb5946b 100644 --- a/code/modules/admin/verbs/admingame.dm +++ b/code/modules/admin/verbs/admingame.dm @@ -315,7 +315,7 @@ ADMIN_VERB(respawn_character, R_ADMIN, "Respawn Character", "Respawn a player th if(record_found)//If they have a record we can determine a few things. new_character.real_name = record_found.name - new_character.gender = LOWER_TEXT(record_found.gender) + new_character.gender = record_found.gender new_character.age = record_found.age var/datum/dna/found_dna = record_found.locked_dna new_character.hardset_dna(found_dna.unique_identity, found_dna.mutation_index, null, record_found.name, record_found.blood_type, new record_found.species_type, found_dna.features) @@ -514,6 +514,7 @@ ADMIN_VERB(lag_switch_panel, R_ADMIN, "Show Lag Switches", "Display the controls dat += "
Measures below can be bypassed with a special trait
" dat += "Slowmode say verb (informs world): [SSlag_switch.measures[SLOWMODE_SAY] ? "On" : "Off"]
" dat += "Disable runechat: [SSlag_switch.measures[DISABLE_RUNECHAT] ? "On" : "Off"] - trait applies to speaker
" + dat += "Disable dead runechat: [SSlag_switch.measures[DISABLE_DEAD_RUNECHAT] ? "On" : "Off"] - trait applies to speaker
" dat += "Disable examine icons: [SSlag_switch.measures[DISABLE_USR_ICON2HTML] ? "On" : "Off"] - trait applies to examiner
" dat += "Disable parallax: [SSlag_switch.measures[DISABLE_PARALLAX] ? "On" : "Off"] - trait applies to character
" dat += "Disable footsteps: [SSlag_switch.measures[DISABLE_FOOTSTEPS] ? "On" : "Off"] - trait applies to character
" diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 066d3c6bf00..45574518486 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -291,7 +291,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) "PLAYERS" = player_count, "ROUND STATE" = round_state, "ROUND ID" = GLOB.round_id, - "ROUND TIME" = ROUND_TIME(), + "ROUND TIME" = round_timestamp(), "MESSAGE" = message, "ADMINS" = admin_text, ) @@ -377,9 +377,9 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) heard_by_no_admins = FALSE send2adminchat(initiator_ckey, "Ticket #[id]: Answered by [key_name(usr)]") - ticket_interactions += "[time_stamp()]: [formatted_message]" + ticket_interactions += "[server_timestamp()]: [formatted_message]" if (!isnull(player_message)) - player_interactions += "[time_stamp()]: [player_message]" + player_interactions += "[server_timestamp()]: [player_message]" //Removes the ahelp verb and returns it after 2 minutes /datum/admin_help/proc/TimeoutVerb() @@ -610,9 +610,9 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) dat += "[FOURSPACES][TicketHref("Refresh", ref_src)][FOURSPACES][TicketHref("Re-Title", ref_src, "retitle")]" if(state != AHELP_ACTIVE) dat += "[FOURSPACES][TicketHref("Reopen", ref_src, "reopen")]" - dat += "

Opened at: [gameTimestamp(wtime = opened_at)] (Approx [DisplayTimeText(world.time - opened_at)] ago)" + dat += "

Opened at: [round_timestamp(wtime = opened_at)] (Approx [DisplayTimeText(world.time - opened_at)] ago)" if(closed_at) - dat += "
Closed at: [gameTimestamp(wtime = closed_at)] (Approx [DisplayTimeText(world.time - closed_at)] ago)" + dat += "
Closed at: [round_timestamp(wtime = closed_at)] (Approx [DisplayTimeText(world.time - closed_at)] ago)" dat += "

" if(initiator) dat += "Actions: [FullMonty(ref_src)]
" @@ -725,9 +725,9 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) else dat += "UNKNOWN" dat += "\n[FOURSPACES]Refresh" - dat += "

Opened at: [gameTimestamp("hh:mm:ss", opened_at)] (Approx [DisplayTimeText(world.time - opened_at)] ago)" + dat += "

Opened at: [round_timestamp("hh:mm:ss", opened_at)] (Approx [DisplayTimeText(world.time - opened_at)] ago)" if(closed_at) - dat += "
Closed at: [gameTimestamp("hh:mm:ss", closed_at)] (Approx [DisplayTimeText(world.time - closed_at)] ago)" + dat += "
Closed at: [round_timestamp("hh:mm:ss", closed_at)] (Approx [DisplayTimeText(world.time - closed_at)] ago)" dat += "

" dat += "
Log:

" for (var/interaction in player_interactions) diff --git a/code/modules/admin/verbs/appearance_debugger/appearance_debugger.dm b/code/modules/admin/verbs/appearance_debugger/appearance_debugger.dm new file mode 100644 index 00000000000..32c29a9e540 --- /dev/null +++ b/code/modules/admin/verbs/appearance_debugger/appearance_debugger.dm @@ -0,0 +1,243 @@ +/// Allows developers to see a breakdown of an atom or a specific target and edit some of the values +/datum/appearance_debugger + var/datum/admins/owner + /// Currently debugged atom or mutable appearance, hence /datum + var/datum/debug_target + /// A list of copies of the currently debugged appearance and its children for access from the UI + var/list/mutable_appearance/appearance_copies + /// Assoc list of ref -> appearance as to prevent refreshing of dynamic appearances + var/list/mutable_appearance/appearance_cache + /// Mapview used to display the hovered over appearance + var/atom/movable/screen/map_view/proxy_view_hover + /// Mapview used to display the selected appearance + var/atom/movable/screen/map_view/proxy_view_selected + /// Assoc list of ref -> list of atoms to be displayed in said ref atom's vis_contents + var/list/atom/movable/fake_vis + /// Should we display a popup that the appearance in-game has updated? + var/update_warning = FALSE + +/datum/appearance_debugger/New(datum/admins/owner) + src.owner = owner + proxy_view_hover = new() + proxy_view_hover.generate_view("appearance_debugger_[REF(owner)]_proxy_hover") + proxy_view_selected = new() + proxy_view_selected.generate_view("appearance_debugger_[REF(owner)]_proxy_selected") + +/datum/appearance_debugger/Destroy() + if (owner) + owner.appearance_debug = null + owner = null + if (fake_vis) + for (var/ref_id in fake_vis) + var/list/all_fakes = fake_vis[ref_id] + QDEL_LIST(all_fakes) + fake_vis.Cut() + QDEL_NULL(proxy_view_hover) + QDEL_NULL(proxy_view_selected) + return ..() + +/datum/appearance_debugger/proc/get_appearance_data(atom/appearance_owner) + var/mutable_appearance/target = appearance_owner + if (isatom(appearance_owner)) + target = appearance_cache["[REF(appearance_owner)]"] || new /mutable_appearance(appearance_owner.appearance) + appearance_cache["[REF(appearance_owner)]"] = target + if (!fake_vis["[REF(appearance_owner)]"] && (ismovable(appearance_owner) || isturf(appearance_owner))) + var/atom/movable/as_movable = appearance_owner + var/list/false_vis_contents = list() + fake_vis["[REF(appearance_owner)]"] = false_vis_contents + for (var/atom/something in (isturf(as_movable) ? (as_movable.vis_contents + as_movable.contents) : as_movable.vis_contents)) + var/atom/movable/mimic = new() + mimic.appearance = new /mutable_appearance(something.appearance) + false_vis_contents += mimic + + var/list/data = list( + "type" = isatom(appearance_owner) ? "atom" : (isimage(appearance_owner) ? "image" : "appearance"), + "alpha" = target.alpha, + "flags" = target.appearance_flags, + "blend_mode" = target.blend_mode, + "color" = target.color, + "dir" = target.dir, + "icon" = length("[target.icon]") ? "[target.icon]" : null, + "icon_state" = target.icon_state, + "invisibility" = target.invisibility, + "layer" = target.layer, + "name" = target.name, + "maptext" = target.maptext, + "maptext_width" = target.maptext_width, + "maptext_height" = target.maptext_height, + "maptext_x" = target.maptext_x, + "maptext_y" = target.maptext_y, + "mouse_opacity" = target.mouse_opacity, + "pixel_x" = target.pixel_x, + "pixel_y" = target.pixel_y, + "pixel_w" = target.pixel_w, + "pixel_z" = target.pixel_z, + "plane" = target.plane, + "plane_true" = PLANE_TO_TRUE(target.plane), + "render_source" = target.render_source, + "render_target" = target.render_target, + "screen_loc" = target.screen_loc, + ) + + if (!(target in appearance_copies)) + appearance_copies += target + data["id"] = length(appearance_copies) + else + data["id"] = appearance_copies.Find(target) + + var/list/filter_data = list() + for (var/list/our_filter as anything in target.filter_data) + filter_data += list(our_filter) + data["filters"] = filter_data + + var/list/underlay_data = list() + for (var/mutable_appearance/underlay as anything in target.underlays) + underlay_data += list(get_appearance_data(underlay)) + data["underlays"] = underlay_data + + var/list/overlay_data = list() + for (var/mutable_appearance/overlay as anything in target.overlays) + overlay_data += list(get_appearance_data(overlay)) + data["overlays"] = overlay_data + + // Display previews if it is either an instance icon or a file and we have icon_state set + if ((isicon(target.icon) && !isfile(target.icon)) || (target.icon && target.icon_state)) + var/icon/used_icon = icon(target.icon, target.icon_state, (isimage(target) && target.dir) ? target.dir : SOUTH, frame = 1) + if (istext(target.color)) + used_icon.Blend(target.color, ICON_MULTIPLY) + data["embed_icon"] = icon2base64(used_icon) + + data["transform"] = list(target.transform.a, target.transform.b, target.transform.c, target.transform.d, target.transform.e, target.transform.f) + // Turfs aren't movables but they still can have vis_flags/contents so lets just count them as such + if (ismovable(appearance_owner) || isturf(appearance_owner)) + var/atom/movable/as_movable = appearance_owner + data["vis_flags"] = as_movable.vis_flags + // Maybe should be cached but I'm too lazy and don't think this'll matter enough + var/list/vis_data = list() + // Turfs also inherit their contents as vis_contents + for (var/atom/vis_thing as anything in isturf(as_movable) ? (as_movable.vis_contents + as_movable.contents) : as_movable.vis_contents) + vis_data += list(get_appearance_data(vis_thing)) + data["vis_contents"] = vis_data + + // Handle all dynamically modified layers + if (target.layer > FLOOR_EMISSIVE_START_LAYER && target.layer < FLOOR_EMISSIVE_END_LAYER) + data["layer_text_override"] = "FLOOR_EMISSIVE_LAYER (+[target.layer - FLOOR_EMISSIVE_START_LAYER])" + else if (target.layer > GAS_PIPE_HIDDEN_LAYER && target.layer < GAS_PIPE_HIDDEN_LAYER + 0.006) + data["layer_text_override"] = "GAS_PIPE_HIDDEN_LAYER (+[target.layer - GAS_PIPE_HIDDEN_LAYER])" + else if (target.layer > GAS_PIPE_VISIBLE_LAYER && target.layer < GAS_PIPE_VISIBLE_LAYER + 0.006) + data["layer_text_override"] = "GAS_PIPE_VISIBLE_LAYER (+[target.layer - GAS_PIPE_VISIBLE_LAYER])" + else if (target.layer > PLUMBING_PIPE_VISIBILE_LAYER && target.layer < PLUMBING_PIPE_VISIBILE_LAYER + (FIFTH_DUCT_LAYER * 2 / 3333)) + data["layer_text_override"] = "PLUMBING_PIPE_VISIBILE_LAYER (+[target.layer - PLUMBING_PIPE_VISIBILE_LAYER])" + + return data + +/datum/appearance_debugger/ui_data(mob/user) + return list( + "updateWarning" = update_warning, + ) + +/datum/appearance_debugger/ui_static_data(mob/user) + return list( + "mainAppearance" = get_appearance_data(debug_target), + "planeToText" = GLOB.admin_readable_planes, + "layerToText" = GLOB.admin_readable_layers, + "flagsToText" = get_valid_bitflags("appearance_flags"), + "visToText" = get_valid_bitflags("vis_flags"), + "blendToText" = GLOB.blend_names, + "mapRefHover" = proxy_view_hover.assigned_map, + "mapRefSelected" = proxy_view_selected.assigned_map, + ) + +/datum/appearance_debugger/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + if(.) + return + switch(action) + if("swapMapViewHover") + var/appearance_id = text2num(params["id"]) + proxy_view_hover.appearance = appearance_copies[appearance_id] + + for (var/atom/movable/something as anything in proxy_view_hover.vis_contents) + proxy_view_hover.vis_contents -= something + for (var/ref_id in appearance_cache) + if (appearance_copies[appearance_id] != appearance_cache[ref_id]) + continue + if (fake_vis[ref_id]) + proxy_view_hover.vis_contents |= fake_vis[ref_id] + + // Needs screenloc to be set since we're setting the appearance and carrying over target's screenloc + proxy_view_hover.set_position(1, 1) + + if("swapMapViewSelected") + var/appearance_id = text2num(params["id"]) + proxy_view_selected.appearance = appearance_copies[appearance_id] + + for (var/atom/movable/something as anything in proxy_view_selected.vis_contents) + proxy_view_selected.vis_contents -= something + for (var/ref_id in appearance_cache) + if (appearance_copies[appearance_id] != appearance_cache[ref_id]) + continue + if (fake_vis[ref_id]) + proxy_view_selected.vis_contents |= fake_vis[ref_id] + + proxy_view_selected.set_position(1, 1) + + if("refreshAppearance") + update_warning = FALSE + appearance_copies = list() + appearance_cache = list() + for (var/ref_id in fake_vis) + var/list/all_fakes = fake_vis[ref_id] + QDEL_LIST(all_fakes) + fake_vis = list() + update_static_data_for_all_viewers() + + if("vvAppearance") + if (!check_rights(R_VAREDIT)) + return + var/appearance_id = text2num(params["id"]) + usr.client.debug_variables(appearance_copies[appearance_id]) + +/datum/appearance_debugger/ui_assets(mob/user) + return list(get_asset_datum(/datum/asset/simple/plane_background)) + +/datum/appearance_debugger/ui_state(mob/user) + return ADMIN_STATE(R_DEBUG) + +/datum/appearance_debugger/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "AppearanceDebug") + ui.open() + proxy_view_hover.display_to(user, ui.window) + proxy_view_selected.display_to(user, ui.window) + +/datum/appearance_debugger/ui_close(mob/user) + . = ..() + // Reset appearances when the UI is closed + proxy_view_hover.appearance = new /mutable_appearance() + proxy_view_selected.appearance = new /mutable_appearance() + proxy_view_hover.vis_contents.Cut() + proxy_view_selected.vis_contents.Cut() + if (isatom(debug_target)) + UnregisterSignal(debug_target, COMSIG_ATOM_UPDATE_APPEARANCE) + +/datum/appearance_debugger/proc/set_target(mutable_appearance/new_target) + if (isatom(debug_target)) + UnregisterSignal(debug_target, COMSIG_ATOM_UPDATE_APPEARANCE) + update_warning = FALSE + // Can be an atom! + debug_target = new_target + if (isatom(debug_target)) + RegisterSignal(debug_target, COMSIG_ATOM_UPDATE_APPEARANCE, PROC_REF(warn_update)) + appearance_copies = list() + appearance_cache = list() + for (var/ref_id in fake_vis) + var/list/all_fakes = fake_vis[ref_id] + QDEL_LIST(all_fakes) + fake_vis = list() + update_static_data_for_all_viewers() + +/datum/appearance_debugger/proc/warn_update() + SIGNAL_HANDLER + update_warning = TRUE diff --git a/code/modules/admin/verbs/path_debugger.dm b/code/modules/admin/verbs/path_debugger.dm index bd6b6620828..98bed7a0f34 100644 --- a/code/modules/admin/verbs/path_debugger.dm +++ b/code/modules/admin/verbs/path_debugger.dm @@ -103,22 +103,10 @@ GLOBAL_DATUM_INIT(pathfind_dude, /obj/pathfind_guy, new()) return /datum/action/innate/path_debug/proc/render_path(list/turf/draw_list) - if(!length(draw_list)) - return list() - - var/list/image/turf_images = list() - // Render everything but the first and last - for(var/i in 1 to (length(draw_list) - 1)) - var/turf/problem_child = draw_list[i] - var/turf/next = draw_list[i + 1] - turf_images += render_turf(problem_child, get_dir(problem_child, next)) - - return turf_images + return SSpathfinder.render_path_images(draw_list) /datum/action/innate/path_debug/proc/render_turf(turf/draw, direction) - var/image/arrow = image('icons/turf/debug.dmi', draw, "arrow", PATH_ARROW_DEBUG_LAYER, direction) - SET_PLANE_EXPLICIT(arrow, BALLOON_CHAT_PLANE, draw) - return arrow + return SSpathfinder.render_path_arrow(draw, direction) /datum/action/innate/path_debug/jps name = "JPS Test" diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm index 4277cae7d81..aefd988aa74 100644 --- a/code/modules/admin/verbs/pray.dm +++ b/code/modules/admin/verbs/pray.dm @@ -1,51 +1,50 @@ -/mob/verb/pray(msg as text) - set category = "IC" - set name = "Pray" +/mob/verb/pray(message as text) + set name = VERB_PRAY if(GLOB.say_disabled) //This is here to try to identify lag problems - to_chat(usr, span_danger("Speech is currently admin-disabled."), confidential = TRUE) + to_chat(src, span_danger("Speech is currently admin-disabled."), confidential = TRUE) return - msg = copytext_char(sanitize(msg), 1, MAX_MESSAGE_LEN) - if(!msg) + message = copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN) + if(!message) return - log_prayer("[src.key]/([src.name]): [msg]") - if(usr.client) - if(usr.client.prefs.muted & MUTE_PRAY) - to_chat(usr, span_danger("You cannot pray (muted)."), confidential = TRUE) + log_prayer("[src.key]/([src.name]): [message]") + if(src.client) + if(src.client.prefs.muted & MUTE_PRAY) + to_chat(src, span_danger("You cannot pray (muted)."), confidential = TRUE) return - if(src.client.handle_spam_prevention(msg,MUTE_PRAY)) + if(src.client.handle_spam_prevention(message, MUTE_PRAY)) return var/mutable_appearance/cross = mutable_appearance('icons/obj/storage/book.dmi', "bible") var/font_color = "purple" var/prayer_type = "PRAYER" var/deity - if(usr.job == JOB_CHAPLAIN) + if(src.job == JOB_CHAPLAIN) cross.icon_state = "kingyellow" font_color = "blue" prayer_type = "CHAPLAIN PRAYER" if(GLOB.deity) deity = GLOB.deity - else if(IS_CULTIST(usr)) + else if(IS_CULTIST(src)) cross.icon_state = "tome" font_color = "red" prayer_type = "CULTIST PRAYER" deity = "Nar'Sie" - else if(isliving(usr)) - var/mob/living/L = usr + else if(isliving(src)) + var/mob/living/L = src if(HAS_TRAIT(L, TRAIT_SPIRITUAL)) cross.icon_state = "holylight" font_color = "blue" prayer_type = "SPIRITUAL PRAYER" - var/msg_tmp = msg - GLOB.requests.pray(usr.client, msg, usr.job == JOB_CHAPLAIN) - msg = span_adminnotice("[icon2html(cross, GLOB.admins)][prayer_type][deity ? " (to [deity])" : ""]: [ADMIN_FULLMONTY(src)] [ADMIN_SC(src)]: [span_linkify(msg)]") + var/msg_tmp = message + GLOB.requests.pray(src.client, message, src.job == JOB_CHAPLAIN) + message = span_adminnotice("[icon2html(cross, GLOB.admins)][prayer_type][deity ? " (to [deity])" : ""]: [ADMIN_FULLMONTY(src)] [ADMIN_SC(src)]: [span_linkify(message)]") for(var/client/C in GLOB.admins) if(get_chat_toggles(C) & CHAT_PRAYER) - to_chat(C, msg, type = MESSAGE_TYPE_PRAYER, confidential = TRUE) - to_chat(usr, span_info("You pray to the gods: \"[msg_tmp]\""), confidential = TRUE) + to_chat(C, message, type = MESSAGE_TYPE_PRAYER, confidential = TRUE) + to_chat(src, span_info("You pray to the gods: \"[msg_tmp]\""), confidential = TRUE) BLACKBOX_LOG_ADMIN_VERB("Prayer") diff --git a/code/modules/admin/verbs/secrets.dm b/code/modules/admin/verbs/secrets.dm index c2a3f1f864d..84ccaf2935b 100644 --- a/code/modules/admin/verbs/secrets.dm +++ b/code/modules/admin/verbs/secrets.dm @@ -163,21 +163,6 @@ ADMIN_VERB(secrets, R_NONE, "Secrets", "Abuse harder than you ever have before w log_admin("[key_name(holder)] reset the station name.") message_admins(span_adminnotice("[key_name_admin(holder)] reset the station name.")) priority_announce("[command_name()] has renamed the station to \"[new_name]\".") - if("night_shift_set") - var/val = tgui_alert(holder, "What do you want to set night shift to? This will override the automatic system until set to automatic again.", "Night Shift", list("On", "Off", "Automatic")) - switch(val) - if("Automatic") - if(CONFIG_GET(flag/enable_night_shifts)) - SSnightshift.can_fire = TRUE - SSnightshift.fire() - else - SSnightshift.update_nightshift(active = FALSE, announce = TRUE, forced = TRUE) - if("On") - SSnightshift.can_fire = FALSE - SSnightshift.update_nightshift(active = TRUE, announce = TRUE, forced = TRUE) - if("Off") - SSnightshift.can_fire = FALSE - SSnightshift.update_nightshift(active = FALSE, announce = TRUE, forced = TRUE) if("moveferry") SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Send CentCom Ferry")) if(!SSshuttle.toggleShuttle("ferry","ferry_home","ferry_away")) @@ -703,6 +688,27 @@ ADMIN_VERB(secrets, R_NONE, "Secrets", "Abuse harder than you ever have before w return return + if("meteormode") + if(!is_funmin) + return + if(GLOB.meteor_mode) + QDEL_NULL(GLOB.meteor_mode) + message_admins("[key_name_admin(holder)] disabled meteor mode.") + return TRUE + + GLOB.meteor_mode = new() + var/start_when = tgui_input_number(usr, "Meteors will start in (this many seconds):", "Meteor Mode: Start", (5 MINUTES) / 10, (24 HOURS) / 10, 0) + var/ramp_speed = tgui_input_number(usr, "Meteors will worsen every (this many seconds):", "Meteor Mode: Intensity", (5 MINUTES) / 10, (24 HOURS) / 10, (30 SECONDS) / 10) + if(!is_funmin) // deadminnied? + QDEL_NULL(GLOB.meteor_mode) + return TRUE + GLOB.meteor_mode.meteordelay = world.time + (start_when * 10) + GLOB.meteor_mode.rampupdelta = ramp_speed / 60 + GLOB.meteor_mode.start_meteor() + message_admins("[key_name_admin(holder)] enabled meteor mode. \ + Meteors will start [start_when ? "in [DisplayTimeText(start_when * 10)]" : "immediately"], and will worsen every [DisplayTimeText(ramp_speed * 10)].") + return TRUE + if("fix_gravity") if(!is_funmin) return diff --git a/code/modules/admin/verbs/sprite_auditor.dm b/code/modules/admin/verbs/sprite_auditor.dm index 64022618c28..e1ffc660706 100644 --- a/code/modules/admin/verbs/sprite_auditor.dm +++ b/code/modules/admin/verbs/sprite_auditor.dm @@ -11,7 +11,7 @@ GLOBAL_DATUM_INIT(sprite_auditor, /datum/sprite_auditor, new) "name" = author.real_name, "ckey" = author.ckey, "appearance" = icon_appearance, - "timestamp" = gameTimestamp(), + "timestamp" = round_timestamp(), ))) SStgui.update_uis(src) diff --git a/code/modules/admin/view_variables/debug_variable_appearance.dm b/code/modules/admin/view_variables/debug_variable_appearance.dm index d92efcb7b2a..9f801066998 100644 --- a/code/modules/admin/view_variables/debug_variable_appearance.dm +++ b/code/modules/admin/view_variables/debug_variable_appearance.dm @@ -64,6 +64,10 @@ var/value = vars[var_name] return "
  • (READ ONLY) [var_name] = [_debug_variable_value(var_name, value, 0, src, sanitize = TRUE, display_flags = NONE)]
  • " +/mutable_appearance/vv_get_dropdown() + . = ..() + VV_DROPDOWN_OPTION(VV_HK_DEBUG_APPEARANCE, "Debug Appearance") + /mutable_appearance/appearance_mirror/vv_get_dropdown() SHOULD_CALL_PARENT(FALSE) @@ -74,6 +78,7 @@ VV_DROPDOWN_OPTION(VV_HK_TAG, "Tag Datum") VV_DROPDOWN_OPTION(VV_HK_DELETE, "Delete") VV_DROPDOWN_OPTION(VV_HK_EXPOSE, "Show VV To Player") + VV_DROPDOWN_OPTION(VV_HK_DEBUG_APPEARANCE, "Debug Appearance") /proc/get_vv_appearance(mutable_appearance/appearance) // actually appearance yadeeyada return new /mutable_appearance/appearance_mirror(appearance) diff --git a/code/modules/admin/view_variables/debug_variables.dm b/code/modules/admin/view_variables/debug_variables.dm index ded5890cba8..bdd45073f19 100644 --- a/code/modules/admin/view_variables/debug_variables.dm +++ b/code/modules/admin/view_variables/debug_variables.dm @@ -103,20 +103,14 @@ return "/list ([list_value.len])" // if it's a number, is it a bitflag? - var/list/valid_bitflags - if(!isnum(name)) - valid_bitflags = get_valid_bitflags(name) + var/list/matching_bitflags = get_matching_bitflags(name, value) - if(!length(valid_bitflags)) - return "[VV_HTML_ENCODE(value)]" + if(!isnull(matching_bitflags)) + if(length(matching_bitflags)) + return "[VV_HTML_ENCODE(matching_bitflags.Join(", "))]" + return "NONE" - var/list/flags = list() - for (var/bit_name in valid_bitflags) - if (value & valid_bitflags[bit_name]) - flags += bit_name - if(length(flags)) - return "[VV_HTML_ENCODE(flags.Join(", "))]" - return "NONE" + return "[VV_HTML_ENCODE(value)]" /datum/proc/debug_variable_value(name, level, datum/owner, sanitize, display_flags) if("[src]" != "[type]") // If we have a name var, let's use it. diff --git a/code/modules/admin/view_variables/reference_tracking.dm b/code/modules/admin/view_variables/reference_tracking.dm index 5f3afd380f7..cccb97f6c9b 100644 --- a/code/modules/admin/view_variables/reference_tracking.dm +++ b/code/modules/admin/view_variables/reference_tracking.dm @@ -19,6 +19,7 @@ GLOBAL_ALIST_EMPTY(reftracker_skip_typecache_b) /icon, /matrix, /regex, + /atom/movable/lighting_object, // only contains turf and MA refs /atom/movable/mirage_holder, /atom/movable/render_step/emissive_blocker, /datum/armor, @@ -31,7 +32,6 @@ GLOBAL_ALIST_EMPTY(reftracker_skip_typecache_b) /datum/greyscale_layer, /datum/icon_transformer, /datum/instrument_key, - /datum/lighting_object, // only contains turf and MA refs /datum/movespeed_modifier, /datum/painting, /datum/paper_input, diff --git a/code/modules/antagonists/_common/antag_spawner.dm b/code/modules/antagonists/_common/antag_spawner.dm index f708ec696e0..53febcc363f 100644 --- a/code/modules/antagonists/_common/antag_spawner.dm +++ b/code/modules/antagonists/_common/antag_spawner.dm @@ -139,7 +139,7 @@ return to_chat(user, span_notice("You activate [src] and wait for confirmation.")) - var/mob/chosen_one = SSpolling.poll_ghost_candidates("Do you want to play as a reinforcement [special_role_name]?", check_jobban = ROLE_OPERATIVE, role = ROLE_OPERATIVE, poll_time = 15 SECONDS, ignore_category = POLL_IGNORE_SYNDICATE, alert_pic = src, role_name_text = special_role_name, amount_to_pick = 1) + var/mob/chosen_one = SSpolling.poll_ghost_candidates("Do you want to play as a reinforcement [special_role_name]?", check_jobban = ROLE_OPERATIVE_MIDROUND, role = ROLE_OPERATIVE_MIDROUND, poll_time = 15 SECONDS, ignore_category = POLL_IGNORE_SYNDICATE, alert_pic = src, role_name_text = special_role_name, amount_to_pick = 1) if(chosen_one) if(QDELETED(src) || !check_usability(user)) return @@ -185,8 +185,8 @@ /obj/item/antag_spawner/nuke_ops/overwatch/Initialize(mapload) . = ..() - if(length(GLOB.nukeop_overwatch_start)) //Otherwise, it will default to the datum's spawn point anyways - spawn_location = pick(GLOB.nukeop_overwatch_start) + if(length(GLOB.nukeop_base_overwatch_start)) //Otherwise, it will default to the datum's spawn point anyways + spawn_location = pick(GLOB.nukeop_base_overwatch_start) //////CLOWN OP /obj/item/antag_spawner/nuke_ops/clown @@ -323,8 +323,6 @@ var/pod_style = /datum/pod_style/syndicate /// Do we use a random subtype of the outfit? var/use_subtypes = TRUE - /// The antag role we check if the ghosts have enabled to get the poll. - var/poll_role_check = ROLE_TRAITOR /// The mind's special role. var/role_to_play = ROLE_SYNDICATE_MONKEY /// What category to ignore the poll @@ -351,8 +349,7 @@ to_chat(user, span_notice("You activate [src] and wait for confirmation.")) var/mob/chosen_one = SSpolling.poll_ghost_candidates( - check_jobban = poll_role_check, - role = poll_role_check, + check_jobban = role_to_play, poll_time = 10 SECONDS, ignore_category = poll_ignore_category, alert_pic = src, @@ -409,7 +406,7 @@ outfit = /datum/outfit/contractor_partner use_subtypes = FALSE antag_datum = /datum/antagonist/traitor/contractor_support - poll_ignore_category = ROLE_TRAITOR + poll_ignore_category = POLL_IGNORE_CONTRACTOR_SUPPORT role_to_play = ROLE_CONTRACTOR_SUPPORT /obj/item/antag_spawner/loadout/contractor/do_special_things(mob/living/carbon/human/contractor_support, mob/user) @@ -426,9 +423,8 @@ outfit = /datum/outfit/syndicate_monkey antag_datum = /datum/antagonist/syndicate_monkey use_subtypes = FALSE - poll_role_check = ROLE_TRAITOR role_to_play = ROLE_SYNDICATE_MONKEY - poll_ignore_category = POLL_IGNORE_SYNDICATE + poll_ignore_category = POLL_IGNORE_SYNDICATE_MONKEY fail_text = "Unable to connect to the Animal Rights Consortium's Banana Ops. Please wait and try again later or use the beacon on your uplink to get your points refunded." /obj/item/antag_spawner/loadout/monkey_man/do_special_things(mob/living/carbon/human/monkey_man, mob/user) diff --git a/code/modules/antagonists/blob/overmind.dm b/code/modules/antagonists/blob/overmind.dm index d6286decf3f..d008c1c99cf 100644 --- a/code/modules/antagonists/blob/overmind.dm +++ b/code/modules/antagonists/blob/overmind.dm @@ -61,6 +61,9 @@ GLOBAL_LIST_EMPTY(blob_nodes) /// The list of strains the blob can reroll for. var/list/strain_choices + /// Adminbus potential - if this is set to FALSE, the blob won't end the round upon reaching critical mass. + var/end_round_on_victory = TRUE + /mob/eye/blob/Initialize(mapload, starting_points = OVERMIND_STARTING_POINTS) ADD_TRAIT(src, TRAIT_BLOB_ALLY, INNATE_TRAIT) validate_location() @@ -160,16 +163,8 @@ GLOBAL_LIST_EMPTY(blob_nodes) qdel(src) else if(!victory_in_progress && (blobs_legit.len >= blobwincount)) - victory_in_progress = TRUE - priority_announce("Biohazard has reached critical mass. Station loss is imminent.", "Biohazard Alert") - SSsecurity_level.set_level(SEC_LEVEL_DELTA) + begin_victory() - // Set status displays to biohazard alert - critical level - send_status_display_biohazard_alert() - - max_blob_points = INFINITY - blob_points = INFINITY - addtimer(CALLBACK(src, PROC_REF(victory)), 45 SECONDS) else if(!free_strain_rerolls && (last_reroll_time + BLOB_POWER_REROLL_FREE_TIME= controller.blobwincount)) + balloon_alert(controller, "max tiles reached!") + return FALSE + // Otherwise, it's probably fine. + return TRUE + +/obj/structure/blob/proc/expand(turf/T = null, mob/eye/blob/controller = null, expand_reaction = 1) if(!T) var/list/dirs = list(1,2,4,8) for(var/i = 1 to 4) @@ -172,6 +184,9 @@ return var/make_blob = TRUE //can we make a blob? + if(!can_make_blob(controller)) + make_blob = FALSE + if(isspaceturf(T) && !(locate(/obj/structure/lattice) in T) && prob(80)) make_blob = FALSE playsound(src.loc, 'sound/effects/splat.ogg', 50, TRUE) //Let's give some feedback that we DID try to spawn in space, since players are used to it diff --git a/code/modules/antagonists/blood_worm/actions/cocoon.dm b/code/modules/antagonists/blood_worm/actions/cocoon.dm index d84a6681912..f976a4fe559 100644 --- a/code/modules/antagonists/blood_worm/actions/cocoon.dm +++ b/code/modules/antagonists/blood_worm/actions/cocoon.dm @@ -407,3 +407,9 @@ /obj/structure/blood_worm_cocoon/adult/examine(mob/user) return ..() + span_warning("It can be broken to prevent the blood worm from reproducing, but it looks extremely tough.") + +/datum/action/cooldown/mob_cooldown/blood_worm/cocoon/hatchling/polymorph + new_worm_type = /mob/living/basic/blood_worm/juvenile/polymorph + +/datum/action/cooldown/mob_cooldown/blood_worm/cocoon/juvenile/polymorph + new_worm_type = /mob/living/basic/blood_worm/adult/polymorph diff --git a/code/modules/antagonists/blood_worm/blood_worm_host_handling.dm b/code/modules/antagonists/blood_worm/blood_worm_host_handling.dm index 2b87fd4c9f6..ebfeed40a64 100644 --- a/code/modules/antagonists/blood_worm/blood_worm_host_handling.dm +++ b/code/modules/antagonists/blood_worm/blood_worm_host_handling.dm @@ -22,6 +22,7 @@ RegisterSignal(host, COMSIG_LIVING_ADJUST_OXY_DAMAGE, PROC_REF(on_host_adjust_oxy_damage)) RegisterSignal(host, COMSIG_LIVING_PRE_UPDATE_BLOOD_STATUS, PROC_REF(on_host_pre_update_blood_status)) RegisterSignal(host, COMSIG_MOB_GET_STATUS_TAB_ITEMS, PROC_REF(on_host_get_status_tab_items)) + client?.set_stat_panel() RegisterSignal(host, COMSIG_MOB_EXAMINING, PROC_REF(on_host_examining)) START_PROCESSING(SSfastprocess, src) @@ -118,6 +119,7 @@ COMSIG_MOB_EXAMINING, COMSIG_MOB_HUD_CREATED, )) + client?.set_stat_panel() STOP_PROCESSING(SSfastprocess, src) diff --git a/code/modules/antagonists/blood_worm/blood_worm_mob.dm b/code/modules/antagonists/blood_worm/blood_worm_mob.dm index 6fe2a41391f..7ac05841786 100644 --- a/code/modules/antagonists/blood_worm/blood_worm_mob.dm +++ b/code/modules/antagonists/blood_worm/blood_worm_mob.dm @@ -398,3 +398,12 @@ transfuse_action = /datum/action/cooldown/mob_cooldown/blood_worm/inject/adult regen_rate = 0.5 // 360 seconds to recover from 0 to 180, or exactly 6 minutes. + +/mob/living/basic/blood_worm/hatchling/polymorph + cocoon_action = /datum/action/cooldown/mob_cooldown/blood_worm/cocoon/hatchling/polymorph + +/mob/living/basic/blood_worm/juvenile/polymorph + cocoon_action = /datum/action/cooldown/mob_cooldown/blood_worm/cocoon/juvenile/polymorph + +/mob/living/basic/blood_worm/adult/polymorph + cocoon_action = null diff --git a/code/modules/antagonists/changeling/cellular_emporium.dm b/code/modules/antagonists/changeling/cellular_emporium.dm index 1a661c86cae..08e3bfe726b 100644 --- a/code/modules/antagonists/changeling/cellular_emporium.dm +++ b/code/modules/antagonists/changeling/cellular_emporium.dm @@ -42,6 +42,7 @@ var/list/ability_data = list( "name" = initial(ability_path.name), "desc" = initial(ability_path.desc), + "icon" = initial(ability_path.button_icon_state), "helptext" = initial(ability_path.helptext), "path" = ability_path, "genetic_point_required" = dna_cost, diff --git a/code/modules/antagonists/changeling/powers/absorb.dm b/code/modules/antagonists/changeling/powers/absorb.dm index 23dad3450c3..ec28fc2866f 100644 --- a/code/modules/antagonists/changeling/powers/absorb.dm +++ b/code/modules/antagonists/changeling/powers/absorb.dm @@ -216,20 +216,16 @@ if(href_list["exit_hivemind"] && !QDELETED(src)) exit_hivemind() -/mob/eye/imaginary_friend/hivemind/verb/exit_hivemind() - set category = "IC" - set name = "Exit Hivemind" - set desc = "Leave the hivemind behind and enter the land of the dead." - +/mob/eye/imaginary_friend/hivemind/proc/exit_hivemind() var/response = tgui_alert(src, "Are you sure you want to exit the hivemind? \ You can't re-enter it, though you can still be revived.", "Confirm Exit", list("Exit", "Stay")) if(response != "Exit" || QDELETED(src)) return ghostize(TRUE) -/mob/eye/imaginary_friend/hivemind/ghostize(can_reenter_corpse, admin_ghost) +/mob/eye/imaginary_friend/hivemind/ghostize(can_reenter_corpse, forced) . = ..() - if(admin_ghost) + if(forced) return alert_hivemind("You sense the presence of [real_name] disappear from the hivemind.") diff --git a/code/modules/antagonists/changeling/powers/mutations.dm b/code/modules/antagonists/changeling/powers/mutations.dm index 20c4b7e220d..3dc6e81a6ef 100644 --- a/code/modules/antagonists/changeling/powers/mutations.dm +++ b/code/modules/antagonists/changeling/powers/mutations.dm @@ -478,7 +478,7 @@ return BULLET_ACT_HIT /obj/projectile/tentacle/Destroy() - qdel(chain) + QDEL_NULL(chain) source = null return ..() diff --git a/code/modules/antagonists/changeling/powers/tiny_prick.dm b/code/modules/antagonists/changeling/powers/tiny_prick.dm index 76f5bf34cfc..14408db87e3 100644 --- a/code/modules/antagonists/changeling/powers/tiny_prick.dm +++ b/code/modules/antagonists/changeling/powers/tiny_prick.dm @@ -1,5 +1,5 @@ /datum/action/changeling/sting//parent path, not meant for users afaik - name = "Tiny Prick" //cellularemporium uses `nameToIconState` to button icon state must match this, on top of matching the hud below. + name = "Tiny Prick" desc = "Stabby stabby" category = "stings" button_icon_state = "sting_null" //This must be equal to the icon state for `/atom/movable/screen/ling/sting` diff --git a/code/modules/antagonists/cult/cult_other.dm b/code/modules/antagonists/cult/cult_other.dm index 0e286d75e81..4f4ddd7aee0 100644 --- a/code/modules/antagonists/cult/cult_other.dm +++ b/code/modules/antagonists/cult/cult_other.dm @@ -9,7 +9,7 @@ /datum/outfit/cultist/post_equip(mob/living/carbon/human/equipped, visuals_only) equipped.set_eye_color(BLOODCULT_EYE) - equipped.update_body() + equipped.update_eyes() ///Returns whether the given mob is convertable to the blood cult /proc/is_convertable_to_cult(mob/living/target, datum/team/cult/specific_cult) diff --git a/code/modules/antagonists/cult/cult_structure_forge.dm b/code/modules/antagonists/cult/cult_structure_forge.dm index 3fe9a884369..d3532d2c636 100644 --- a/code/modules/antagonists/cult/cult_structure_forge.dm +++ b/code/modules/antagonists/cult/cult_structure_forge.dm @@ -1,6 +1,5 @@ /// Some defines for items the daemon forge can create. #define NARSIE_ARMOR "Nar'Sien Hardened Armor" -#define FLAGELLANT_ARMOR "Flagellant's Robe" #define ELDRITCH_SWORD "Eldritch Longsword" #define CURSED_BLADE "Cursed Ritual Blade" @@ -8,7 +7,7 @@ /obj/structure/destructible/cult/item_dispenser/forge name = "daemon forge" desc = "A forge used in crafting the unholy weapons used by the armies of Nar'Sie." - cult_examine_tip = "Can be used to create Nar'Sien hardened armor, flagellant's robes, and eldritch longswords." + cult_examine_tip = "Can be used to create Nar'Sien hardened armor and eldritch longswords." icon_state = "forge" light_range = 2 light_color = LIGHT_COLOR_LAVA @@ -56,6 +55,5 @@ debris = list() #undef NARSIE_ARMOR -#undef FLAGELLANT_ARMOR #undef ELDRITCH_SWORD #undef CURSED_BLADE diff --git a/code/modules/antagonists/heretic/heretic_antag.dm b/code/modules/antagonists/heretic/heretic_antag.dm index d3f91fe8c47..c6b6cd184e3 100644 --- a/code/modules/antagonists/heretic/heretic_antag.dm +++ b/code/modules/antagonists/heretic/heretic_antag.dm @@ -345,7 +345,9 @@ qdel(path) if(give_objectives) - forge_primary_objectives(heretic_shops[HERETIC_KNOWLEDGE_TREE]) + var/datum/objective/pick_path/pick_a_path = new() + pick_a_path.owner = owner + objectives += pick_a_path for(var/starting_knowledge in GLOB.heretic_start_knowledge) gain_knowledge(starting_knowledge, HERETIC_KNOWLEDGE_START, update = FALSE) @@ -374,6 +376,7 @@ var/mob/living/our_mob = mob_override || owner.current handle_clown_mutation(our_mob, "Ancient knowledge described to you has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.") our_mob.add_faction(FACTION_HERETIC) + our_mob.apply_status_effect(/datum/status_effect/grouped/heretic_dreams, type) if(!issilicon(our_mob)) GLOB.reality_smash_track.add_tracked_mind(owner) @@ -397,6 +400,7 @@ var/mob/living/our_mob = mob_override || owner.current handle_clown_mutation(our_mob, removing = FALSE) our_mob.remove_faction(FACTION_HERETIC) + our_mob.remove_status_effect(/datum/status_effect/grouped/heretic_dreams, type) if(owner in GLOB.reality_smash_track.tracked_heretics) GLOB.reality_smash_track.remove_tracked_mind(owner) @@ -411,10 +415,12 @@ COMSIG_LIVING_POST_FULLY_HEAL, COMSIG_LIVING_CULT_SACRIFICED, COMSIG_ATOM_EXAMINE, + COMSIG_ATOM_UPDATE_OVERLAYS, SIGNAL_ADDTRAIT(TRAIT_HERETIC_AURA_HIDDEN), - SIGNAL_REMOVETRAIT(TRAIT_HERETIC_AURA_HIDDEN) + SIGNAL_REMOVETRAIT(TRAIT_HERETIC_AURA_HIDDEN), ) ) + our_mob.update_appearance(UPDATE_OVERLAYS) /// Removes the ability to blade break, removes cloak of shadows and removes the cap on how many blades you can craft /datum/antagonist/heretic/proc/disable_blade_breaking() @@ -709,8 +715,13 @@ /** * Create our objectives for our heretic. */ -/datum/antagonist/heretic/proc/forge_primary_objectives(heretic_research_tree) - var/datum/objective/heretic_research/research_objective = new(heretic_research_tree = heretic_research_tree) +/datum/antagonist/heretic/proc/forge_primary_objectives() + for(var/datum/objective/pick_path/filler in objectives) + filler.owner = null + objectives -= filler + qdel(filler) + + var/datum/objective/heretic_research/research_objective = new(heretic_research_tree = heretic_shops) research_objective.owner = owner objectives += research_objective @@ -1099,6 +1110,10 @@ return HERETIC_HAS_LIVING_HEART +/datum/objective/pick_path + name = "pick a path" + explanation_text = "Pick a path to pursue." + /// Heretic's minor sacrifice objective. "Minor sacrifices" includes anyone. /datum/objective/minor_sacrifice name = "minor sacrifice" @@ -1133,29 +1148,21 @@ /// Heretic's research objective. "Research" is heretic knowledge nodes (You start with some). /datum/objective/heretic_research name = "research" - /// The length of a main path. Calculated once in New(). - var/static/main_path_length = 0 + target_amount = 1 // You spawn with 1 point -/datum/objective/heretic_research/New(text, heretic_research_tree) +/datum/objective/heretic_research/New(text, list/heretic_research_tree = list()) . = ..() - if(!main_path_length) - // Let's find the length of a main path. We'll use rust because it's the coolest. - // (All the main paths are (should be) the same length, so it doesn't matter.) - var/rust_paths_found = 0 - for(var/datum/heretic_knowledge/knowledge as anything in subtypesof(/datum/heretic_knowledge)) - var/list/knowledge_data = heretic_research_tree[knowledge] - if(knowledge_data && knowledge_data[HKT_ROUTE] == PATH_RUST) - rust_paths_found++ - - main_path_length = rust_paths_found - - // Factor in the length of the main path first. - target_amount = main_path_length - // Add in the base research we spawn with, otherwise it'd be too easy. + // Factor in the length of the main path + target_amount += length(heretic_research_tree[HERETIC_KNOWLEDGE_TREE]) || 10 + // Factor in base research we spawn with (otherwise it'd be too easy) target_amount += length(GLOB.heretic_start_knowledge) - // And add in some buffer, to require some sidepathing, especially since heretics get some free side paths. + // Factor in free knowledge, no challenge there + target_amount += ceil(length(heretic_research_tree[HERETIC_KNOWLEDGE_DRAFT]) / 3) || 4 + + // The actual challenge factor is introduced here, adding a random amount of additional knowledge needed target_amount += rand(2, 4) + update_explanation_text() /datum/objective/heretic_research/update_explanation_text() diff --git a/code/modules/antagonists/heretic/heretic_knowledge.dm b/code/modules/antagonists/heretic/heretic_knowledge.dm index d1a1ee28beb..0c5efc1a959 100644 --- a/code/modules/antagonists/heretic/heretic_knowledge.dm +++ b/code/modules/antagonists/heretic/heretic_knowledge.dm @@ -292,7 +292,9 @@ our_heretic.heretic_shops[HERETIC_KNOWLEDGE_DRAFT], ) SEND_SIGNAL(src, COMSIG_HERETIC_SHOP_SETUP) - + if(our_heretic.give_objectives) + our_heretic.forge_primary_objectives() + our_heretic.owner.announce_objectives() /datum/heretic_knowledge/limited_amount/starting/on_gain(mob/user, datum/antagonist/heretic/our_heretic) RegisterSignals(user, list(COMSIG_HERETIC_MANSUS_GRASP_ATTACK, COMSIG_LIONHUNTER_ON_HIT), PROC_REF(on_mansus_grasp)) @@ -553,7 +555,7 @@ to_chat(user, span_boldnotice("[name] completed!")) to_chat(user, span_hypnophrase(span_big("[pick_list(HERETIC_INFLUENCE_FILE, "drain_message")]"))) desc += " (Completed!)" - log_heretic_knowledge("[key_name(user)] completed a [name] at [gameTimestamp()].") + log_heretic_knowledge("[key_name(user)] completed a [name] at [round_timestamp()].") user.add_mob_memory(/datum/memory/heretic_knowledge_ritual) SEND_SIGNAL(our_heretic, COMSIG_HERETIC_PASSIVE_UPGRADE_FINAL) return TRUE @@ -584,7 +586,7 @@ var/list/cost = our_heretic.researched_knowledge[knowledge][HKT_COST] total_points += cost - log_heretic_knowledge("[key_name(user)] gained knowledge of their final ritual at [gameTimestamp()]. \ + log_heretic_knowledge("[key_name(user)] gained knowledge of their final ritual at [round_timestamp()]. \ They have [length(our_heretic.researched_knowledge)] knowledge nodes researched, totalling [total_points] points \ and have sacrificed [our_heretic.total_sacrifices] people ([our_heretic.high_value_sacrifices] of which were high value)") @@ -634,7 +636,7 @@ human_user.physiology.burn_mod *= 0.5 SSblackbox.record_feedback("tally", "heretic_ascended", 1, heretic_datum.heretic_path.route) - log_heretic_knowledge("[key_name(user)] completed their final ritual at [gameTimestamp()].") + log_heretic_knowledge("[key_name(user)] completed their final ritual at [round_timestamp()].") notify_ghosts( "[user.real_name] has completed an ascension ritual!", source = user, diff --git a/code/modules/antagonists/heretic/influences.dm b/code/modules/antagonists/heretic/influences.dm index 71d15cf4b03..793cf4b65c6 100644 --- a/code/modules/antagonists/heretic/influences.dm +++ b/code/modules/antagonists/heretic/influences.dm @@ -151,8 +151,7 @@ else human_user.gib(DROP_ALL_REMAINS) human_user.investigate_log("has died from using telekinesis on a heretic influence.", INVESTIGATE_DEATHS) - var/datum/effect_system/reagents_explosion/explosion = new(get_turf(human_user), 1, 1, 1) - explosion.start(src) + dyn_explosion(get_turf(human_user), 1, flash_range = 1, flame_range = 1) */ /obj/effect/visible_heretic_influence/examine(mob/living/user) diff --git a/code/modules/antagonists/heretic/items/corrupted_organs.dm b/code/modules/antagonists/heretic/items/corrupted_organs.dm index a6494591910..0c96652436c 100644 --- a/code/modules/antagonists/heretic/items/corrupted_organs.dm +++ b/code/modules/antagonists/heretic/items/corrupted_organs.dm @@ -251,8 +251,7 @@ breather.emote("cough"); var/chosen_gas = pick_weight(gas_types) var/datum/gas_mixture/mix_to_spawn = new() - mix_to_spawn.add_gas(pick(chosen_gas)) - mix_to_spawn.gases[chosen_gas][MOLES] = gas_amount + mix_to_spawn.adjust_gas(pick(chosen_gas), gas_amount) mix_to_spawn.temperature = breather.bodytemperature log_atmos("[owner] coughed some gas into the air due to their corrupted lungs.", mix_to_spawn) var/turf/open/our_turf = get_turf(breather) diff --git a/code/modules/antagonists/heretic/items/heretic_armor.dm b/code/modules/antagonists/heretic/items/heretic_armor.dm index a5b63179a96..1529284652b 100644 --- a/code/modules/antagonists/heretic/items/heretic_armor.dm +++ b/code/modules/antagonists/heretic/items/heretic_armor.dm @@ -1114,13 +1114,13 @@ // Void cloak. Turns invisible with the hood up, lets you hide stuff. /obj/item/clothing/head/hooded/cult_hoodie/void name = "void hood" - icon = 'icons/obj/clothing/head/helmet.dmi' - worn_icon = 'icons/mob/clothing/head/helmet.dmi' desc = "Black like tar, reflecting no light. Runic symbols line the outside. \ With each flash you lose comprehension of what you are seeing." + icon = 'icons/obj/clothing/head/helmet.dmi' + worn_icon = 'icons/mob/clothing/head/helmet.dmi' icon_state = "void_cloak" flags_inv = NONE - flags_cover = NONE + flags_cover = ALLOW_SURGERY_THROUGH armor_type = /datum/armor/cult_hoodie_void /datum/armor/cult_hoodie_void @@ -1221,6 +1221,7 @@ /obj/item/clothing/suit/hooded/cultrobes/void/proc/make_invisible() add_traits(list(TRAIT_NO_STRIP, TRAIT_EXAMINE_SKIP), REF(src)) RemoveElement(/datum/element/heretic_focus) + flags_cover |= ALLOW_SURGERY_THROUGH if(isliving(loc)) loc.remove_traits(list(TRAIT_RESISTLOWPRESSURE, TRAIT_RESISTCOLD), REF(src)) @@ -1232,6 +1233,7 @@ /obj/item/clothing/suit/hooded/cultrobes/void/proc/make_visible() remove_traits(list(TRAIT_NO_STRIP, TRAIT_EXAMINE_SKIP), REF(src)) AddElement(/datum/element/heretic_focus) + flags_cover &= ~ALLOW_SURGERY_THROUGH if(isliving(loc)) loc.add_traits(list(TRAIT_RESISTLOWPRESSURE, TRAIT_RESISTCOLD), REF(src)) diff --git a/code/modules/antagonists/heretic/items/heretic_grenade.dm b/code/modules/antagonists/heretic/items/heretic_grenade.dm index 3a5e0e2a129..4cae667299d 100644 --- a/code/modules/antagonists/heretic/items/heretic_grenade.dm +++ b/code/modules/antagonists/heretic/items/heretic_grenade.dm @@ -22,6 +22,9 @@ /obj/item/grenade/chem_grenade/rust_sower/Initialize(mapload) . = ..() + AddElement(/datum/element/tool_blocker, TOOL_SCREWDRIVER, TOOL_ACT_PRIMARY) + AddElement(/datum/element/tool_blocker, TOOL_WRENCH, TOOL_ACT_PRIMARY) + AddElement(/datum/element/tool_blocker, TOOL_MULTITOOL, TOOL_ACT_PRIMARY) RegisterSignal(src, COMSIG_ITEM_ON_GRIND, PROC_REF(on_try_grind)) var/obj/item/reagent_containers/cup/beaker/large/beaker_one = new(src) var/obj/item/reagent_containers/cup/beaker/large/beaker_two = new(src) @@ -39,15 +42,6 @@ playsound(src, 'sound/items/weapons/rust_sower_explode.ogg', 70, FALSE) qdel(src) -/obj/item/grenade/chem_grenade/rust_sower/screwdriver_act(mob/living/user, obj/item/tool) - return NONE - -/obj/item/grenade/chem_grenade/rust_sower/wrench_act(mob/living/user, obj/item/tool) - return NONE - -/obj/item/grenade/chem_grenade/rust_sower/multitool_act(mob/living/user, obj/item/tool) - return NONE - /// Returns -1 so that you cant extract the chems /obj/item/grenade/chem_grenade/rust_sower/proc/on_try_grind() SIGNAL_HANDLER diff --git a/code/modules/antagonists/heretic/items/keyring.dm b/code/modules/antagonists/heretic/items/keyring.dm index 61dbef21dc1..21bd99846e5 100644 --- a/code/modules/antagonists/heretic/items/keyring.dm +++ b/code/modules/antagonists/heretic/items/keyring.dm @@ -95,6 +95,7 @@ ///An ID card capable of shapeshifting to other IDs given by the Key Keepers Burden knowledge /obj/item/card/id/advanced/heretic + access = list(ACCESS_HERETIC) ///List of IDs this card consumed var/list/obj/item/card/id/fused_ids = list() ///The first portal in the portal pair, so we can clear it later diff --git a/code/modules/antagonists/heretic/knowledge/moon_lore.dm b/code/modules/antagonists/heretic/knowledge/moon_lore.dm index d8c093ac405..5c611079f8c 100644 --- a/code/modules/antagonists/heretic/knowledge/moon_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/moon_lore.dm @@ -119,8 +119,9 @@ research_tree_icon_frame = 9 /datum/heretic_knowledge/armor/moon - desc = "Allows you to transmute a table (or a suit), a mask and two sheets of glass to create a Resplendant Regalia, this robe will render the user fully immune to disabling effects and convert all forms of damage into brain damage, while also pacifying the user and render him unable to use ranged weapons (Moon blade will bypass pacifism). \ - Acts as a focus while hooded." + desc = "Allows you to transmute a table (or a suit), a mask and two sheets of glass to create a Resplendant Regalia. \ + This robe will render the user fully immune to disabling effects and convert all forms of damage into brain damage, while also pacifying the user and rendering them unable to use ranged weapons. \ + A Moonlight Amulet will be necessary to use blades while wearing it." gain_text = "Trails of light and mirth flowed from every arm of this magnificent attire. \ The troupe twirled in irridescent cascades, dazzling onlookers with the truth they sought. \ I observed, basking in the light, to find my self." diff --git a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm index a5a12f3650d..f5f9c473b8a 100644 --- a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm +++ b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm @@ -26,7 +26,7 @@ /// A weakref to the mind of our heretic. var/datum/mind/heretic_mind /// Lazylist of minds that we won't pick as targets. - var/list/datum/mind/target_blacklist + var/static/list/datum/mind/target_blacklist /// An assoc list of [ref] to [timers] - a list of all the timers of people in the shadow realm currently var/list/return_timers /// Evil organs we can put in people @@ -42,7 +42,6 @@ /datum/heretic_knowledge/hunt_and_sacrifice/Destroy(force) heretic_mind = null - LAZYCLEARLIST(target_blacklist) return ..() /datum/heretic_knowledge/hunt_and_sacrifice/on_research(mob/user, datum/antagonist/heretic/our_heretic) @@ -211,8 +210,8 @@ if(sacrifice.mind) LAZYADD(target_blacklist, sacrifice.mind) - heretic_datum.remove_sacrifice_target(sacrifice) - + for(var/datum/antagonist/heretic/all_heretic in GLOB.antagonists) + all_heretic.remove_sacrifice_target(sacrifice) var/feedback = "Your patrons accept your offer" var/sac_job_flag = sacrifice.mind?.assigned_role?.job_flags | sacrifice.last_mind?.assigned_role?.job_flags diff --git a/code/modules/antagonists/heretic/knowledge/side_knowledge/tier_one.dm b/code/modules/antagonists/heretic/knowledge/side_knowledge/tier_one.dm index e8a3f9b4d67..3706408b464 100644 --- a/code/modules/antagonists/heretic/knowledge/side_knowledge/tier_one.dm +++ b/code/modules/antagonists/heretic/knowledge/side_knowledge/tier_one.dm @@ -100,3 +100,136 @@ research_tree_icon_path = 'icons/obj/economy.dmi' research_tree_icon_state = "coin_heretic" drafting_tier = 1 + +/** + * This allows heretics to choose if they want to rush all the influences and take them stealthily, or + * Construct a codex and take what's left with more points. + * Another downside to having the book is strip searches, which means that it's not just a free nab, at least until you get exposed - and when you do, you'll probably need the faster drawing speed. + * Overall, it's a tradeoff between speed and stealth or power. + */ +/datum/heretic_knowledge/codex_cicatrix + name = "Codex Cicatrix" + desc = "Allows you to transmute a book, any pen, and your pick from any carcass (animal or human), leather, or hide to create a Codex Cicatrix. \ + The Codex Cicatrix can be used when draining influences to gain additional knowledge, but comes at greater risk of being noticed. \ + It can also be used to draw and remove transmutation runes easier, and as a spell focus in a pinch." + gain_text = "The occult leaves fragments of knowledge and power anywhere and everywhere. The Codex Cicatrix is one such example. \ + Within the leather-bound faces and age old pages, a path into the Mansus is revealed." + required_atoms = list( + list(/obj/item/toy/eldritch_book, /obj/item/book) = 1, + /obj/item/pen = 1, + list(/mob/living, /obj/item/stack/sheet/leather, /obj/item/stack/sheet/animalhide, /obj/item/food/deadmouse) = 1, + ) + result_atoms = list(/obj/item/codex_cicatrix) + cost = 1 + priority = MAX_KNOWLEDGE_PRIORITY - 4 + drafting_tier = 1 + is_shop_only = TRUE + research_tree_icon_path = 'icons/obj/antags/eldritch.dmi' + research_tree_icon_state = "book" + + var/static/list/non_mob_bindings = typecacheof(list( + /obj/item/stack/sheet/leather, + /obj/item/stack/sheet/animalhide, + /obj/item/food/deadmouse, + )) + +/datum/heretic_knowledge/codex_cicatrix/recipe_snowflake_check(mob/living/user, list/atoms, list/selected_atoms, turf/loc) + . = ..() + if(!.) + return FALSE + + for(var/thingy in atoms) + if(is_type_in_typecache(thingy, non_mob_bindings)) + selected_atoms += thingy + return TRUE + else if(isliving(thingy)) + var/mob/living/body = thingy + if(body.stat != DEAD) + continue + selected_atoms += body + return TRUE + return FALSE + +/datum/heretic_knowledge/codex_cicatrix/cleanup_atoms(list/selected_atoms) + var/mob/living/body = locate() in selected_atoms + if(!body) + return ..() + // A golem or an android doesn't have skin! + var/exterior_text = "skin" + // If carbon, it's the limb. If not, it's the body. + var/atom/movable/ripped_thing = body + + // We will check if it's a carbon's body. + // If it is, we will damage a random bodypart, and check that bodypart for its body type, to select between 'skin' or 'exterior'. + if(iscarbon(body)) + var/mob/living/carbon/carbody = body + var/obj/item/bodypart/bodypart = pick(carbody.get_bodyparts()) + ripped_thing = bodypart + + carbody.apply_damage(25, BRUTE, bodypart, sharpness = SHARP_EDGED) + if(!(bodypart.bodytype & BODYTYPE_ORGANIC)) + exterior_text = "exterior" + else + body.apply_damage(25, BRUTE, sharpness = SHARP_EDGED) + // If it is not a carbon mob, we will just check biotypes and damage it directly. + if(body.mob_biotypes & (MOB_MINERAL|MOB_ROBOTIC)) + exterior_text = "exterior" + + // Procure book for flavor text. This is why we call parent at the end. + var/obj/item/book/le_book = locate() in selected_atoms + if(!le_book) + stack_trace("Somehow, no book in codex cicatrix selected atoms! [english_list(selected_atoms)]") + playsound(body, 'sound/items/poster/poster_ripped.ogg', 100, TRUE) + body.do_jitter_animation() + body.visible_message(span_danger("An awful ripping sound is heard as [ripped_thing]'s [exterior_text] is ripped straight out, wrapping around [le_book || "the book"], turning into an eldritch shade of blue!")) + return ..() + +/** + * Warren King's Welcome + * Offers an alternative way besides stealing an ID or visiting the HoP to gain access to maintenance + * Additionally changes all nearby airlock's access's to ACCESS_HERETIC + */ +/datum/heretic_knowledge/bookworm + name = "Warren King's Welcome" + desc = "Allows you to transmute 10 cable pieces, a piece of paper, and a multitool to brand nearby ID cards and airlocks. \ + Branded ID cards will gain access to maintenance, external airlocks, as well to branded airlocks. \ + Branded airlocks will only be accessible by those with a branded ID card." + gain_text = "Gnawed into vicious-stained fingerbones, my grim invitation snaps my nauseous and clouded mind towards the heavy-set door. \ + Slowly, the light dances between a crawling darkness, blanketing the fetid promenade with infinite machinations. \ + But the King will soon take his pound of flesh. Even here, the taxman takes their cut. For there are a thousands mouths to feed." + required_atoms = list( + /obj/item/stack/cable_coil = 10, + /obj/item/paper = 1, + /obj/item/multitool = 1, + ) + cost = 1 + priority = MAX_KNOWLEDGE_PRIORITY - 3 + drafting_tier = 1 + research_tree_icon_path = 'icons/obj/card.dmi' + research_tree_icon_state = "eldritch" + +/datum/heretic_knowledge/bookworm/recipe_snowflake_check(mob/living/user, list/atoms, list/selected_atoms, turf/loc) + . = ..() + for(var/obj/item/card/id/used_id in atoms) + selected_atoms += used_id + var/obj/item/card/user_card = user.get_idcard(hand_first = TRUE) + if(user_card) + selected_atoms += user_card + +/datum/heretic_knowledge/bookworm/on_finished_recipe(mob/living/user, list/selected_atoms, turf/loc) + . = ..() + for(var/obj/item/card/id/improved_id in selected_atoms) + improved_id.add_access(list(ACCESS_MAINT_TUNNELS, ACCESS_EXTERNAL_AIRLOCKS, ACCESS_HERETIC), mode = FORCE_ADD_ALL) + selected_atoms -= improved_id + for(var/obj/machinery/door/airlock/door in view(7, loc)) + door.req_one_access = null + door.req_access = list(ACCESS_HERETIC) + door.wires?.cut(WIRE_AI) + new /obj/effect/temp_visual/eldritch_sparks(door.loc) + var/obj/effect/light_emitter/light = new(door.loc) + light.set_light(1.75, 1.5, COLOR_PUCE) + QDEL_IN(light, 1 SECONDS) + playsound(door, 'sound/effects/magic.ogg', 20, vary = TRUE, extrarange = SILENCED_SOUND_EXTRARANGE, ignore_walls = FALSE) + playsound(door, SFX_SPARKS, 33, vary = TRUE, extrarange = SILENCED_SOUND_EXTRARANGE, ignore_walls = FALSE) + + return TRUE diff --git a/code/modules/antagonists/heretic/knowledge/starting_lore.dm b/code/modules/antagonists/heretic/knowledge/starting_lore.dm index 6647ee086bc..4105a4d08c9 100644 --- a/code/modules/antagonists/heretic/knowledge/starting_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/starting_lore.dm @@ -200,84 +200,6 @@ GLOBAL_LIST_INIT(heretic_start_knowledge, initialize_starting_knowledge()) cost = 0 is_starting_knowledge = TRUE -/** - * Codex Cicatrixi is available at the start: - * This allows heretics to choose if they want to rush all the influences and take them stealthily, or - * Construct a codex and take what's left with more points. - * Another downside to having the book is strip searches, which means that it's not just a free nab, at least until you get exposed - and when you do, you'll probably need the faster drawing speed. - * Overall, it's a tradeoff between speed and stealth or power. - */ -/datum/heretic_knowledge/codex_cicatrix - name = "Codex Cicatrix" - desc = "Allows you to transmute a book, any pen, and your pick from any carcass (animal or human), leather, or hide to create a Codex Cicatrix. \ - The Codex Cicatrix can be used when draining influences to gain additional knowledge, but comes at greater risk of being noticed. \ - It can also be used to draw and remove transmutation runes easier, and as a spell focus in a pinch." - gain_text = "The occult leaves fragments of knowledge and power anywhere and everywhere. The Codex Cicatrix is one such example. \ - Within the leather-bound faces and age old pages, a path into the Mansus is revealed." - required_atoms = list( - list(/obj/item/toy/eldritch_book, /obj/item/book) = 1, - /obj/item/pen = 1, - list(/mob/living, /obj/item/stack/sheet/leather, /obj/item/stack/sheet/animalhide, /obj/item/food/deadmouse) = 1, - ) - result_atoms = list(/obj/item/codex_cicatrix) - cost = 1 - is_starting_knowledge = TRUE - priority = MAX_KNOWLEDGE_PRIORITY - 4 // Least priority out of the starting knowledges, as it's an optional boon. - var/static/list/non_mob_bindings = typecacheof(list(/obj/item/stack/sheet/leather, /obj/item/stack/sheet/animalhide, /obj/item/food/deadmouse)) - research_tree_icon_path = 'icons/obj/antags/eldritch.dmi' - research_tree_icon_state = "book" - -/datum/heretic_knowledge/codex_cicatrix/recipe_snowflake_check(mob/living/user, list/atoms, list/selected_atoms, turf/loc) - . = ..() - if(!.) - return FALSE - - for(var/thingy in atoms) - if(is_type_in_typecache(thingy, non_mob_bindings)) - selected_atoms += thingy - return TRUE - else if(isliving(thingy)) - var/mob/living/body = thingy - if(body.stat != DEAD) - continue - selected_atoms += body - return TRUE - return FALSE - -/datum/heretic_knowledge/codex_cicatrix/cleanup_atoms(list/selected_atoms) - var/mob/living/body = locate() in selected_atoms - if(!body) - return ..() - // A golem or an android doesn't have skin! - var/exterior_text = "skin" - // If carbon, it's the limb. If not, it's the body. - var/atom/movable/ripped_thing = body - - // We will check if it's a carbon's body. - // If it is, we will damage a random bodypart, and check that bodypart for its body type, to select between 'skin' or 'exterior'. - if(iscarbon(body)) - var/mob/living/carbon/carbody = body - var/obj/item/bodypart/bodypart = pick(carbody.get_bodyparts()) - ripped_thing = bodypart - - carbody.apply_damage(25, BRUTE, bodypart, sharpness = SHARP_EDGED) - if(!(bodypart.bodytype & BODYTYPE_ORGANIC)) - exterior_text = "exterior" - else - body.apply_damage(25, BRUTE, sharpness = SHARP_EDGED) - // If it is not a carbon mob, we will just check biotypes and damage it directly. - if(body.mob_biotypes & (MOB_MINERAL|MOB_ROBOTIC)) - exterior_text = "exterior" - - // Procure book for flavor text. This is why we call parent at the end. - var/obj/item/book/le_book = locate() in selected_atoms - if(!le_book) - stack_trace("Somehow, no book in codex cicatrix selected atoms! [english_list(selected_atoms)]") - playsound(body, 'sound/items/poster/poster_ripped.ogg', 100, TRUE) - body.do_jitter_animation() - body.visible_message(span_danger("An awful ripping sound is heard as [ripped_thing]'s [exterior_text] is ripped straight out, wrapping around [le_book || "the book"], turning into an eldritch shade of blue!")) - return ..() - /datum/heretic_knowledge/feast_of_owls name = "Feast of Owls" desc = "Allows you to undergo a ritual that gives you 5 knowledge points but locks you out of ascension. This can only be done once and cannot be reverted." @@ -322,42 +244,3 @@ GLOBAL_LIST_INIT(heretic_start_knowledge, initialize_starting_knowledge()) var/drain_message = pick_list(HERETIC_INFLUENCE_FILE, "drain_message") to_chat(user, span_hypnophrase(span_big("[drain_message]"))) return . - -/** - * Warren King's Welcome - * Ritual available at the start. So that heretics can easily gain access to maintenance airlocks without having to rely on a HoP or having to off some poor assistant. - * Gives access to solars since those doors are especially useful to get in or out of space. - */ -/datum/heretic_knowledge/bookworm - name = "Warren King's Welcome" - desc = "Allows you to transmute 5 cable pieces and a piece of paper to infuse any ID with maintenace and external airlock access." - gain_text = "Gnawed into vicious-stained fingerbones, my grim invitation snaps my nauseous and clouded mind towards the heavy-set door. \ - Slowly, the light dances between a crawling darkness, blanketing the fetid promenade with infinite machinations. \ - But the King will soon take his pound of flesh. Even here, the taxman takes their cut. For there are a thousands mouths to feed." - required_atoms = list( - /obj/item/stack/cable_coil = 5, - /obj/item/paper = 1, - ) - cost = 1 - is_starting_knowledge = TRUE - priority = MAX_KNOWLEDGE_PRIORITY - 3 - research_tree_icon_path = 'icons/obj/card.dmi' - research_tree_icon_state = "eldritch" - -/datum/heretic_knowledge/bookworm/recipe_snowflake_check(mob/living/user, list/atoms, list/selected_atoms, turf/loc) - . = ..() - for(var/obj/item/card/id/used_id in atoms) - if((ACCESS_MAINT_TUNNELS in used_id.access) && (ACCESS_EXTERNAL_AIRLOCKS in used_id.access)) // If we can't give any access we aren't elligible - continue - selected_atoms += used_id - return TRUE - - user.balloon_alert(user, "ritual failed, no ID lacking access!") - return FALSE - -/datum/heretic_knowledge/bookworm/on_finished_recipe(mob/living/user, list/selected_atoms, turf/loc) - . = ..() - var/obj/item/card/id/improved_id = locate() in selected_atoms - improved_id.add_access(list(ACCESS_MAINT_TUNNELS, ACCESS_EXTERNAL_AIRLOCKS), mode = FORCE_ADD_ALL) - selected_atoms -= improved_id - return TRUE diff --git a/code/modules/antagonists/heretic/magic/eldritch_shapeshift.dm b/code/modules/antagonists/heretic/magic/eldritch_shapeshift.dm index 514236771e2..af2fd7e0ef1 100644 --- a/code/modules/antagonists/heretic/magic/eldritch_shapeshift.dm +++ b/code/modules/antagonists/heretic/magic/eldritch_shapeshift.dm @@ -17,5 +17,5 @@ /mob/living/basic/pet/cat, /mob/living/basic/pet/dog/corgi, /mob/living/basic/pet/fox, - /mob/living/simple_animal/bot/secbot, + /mob/living/basic/bot/secbot, ) diff --git a/code/modules/antagonists/heretic/moon_lunatic.dm b/code/modules/antagonists/heretic/moon_lunatic.dm index d33ad281a83..87609dbf967 100644 --- a/code/modules/antagonists/heretic/moon_lunatic.dm +++ b/code/modules/antagonists/heretic/moon_lunatic.dm @@ -17,6 +17,7 @@ var/datum/objective/lunatic/lunatic_obj /datum/antagonist/lunatic/on_gain() + owner.current.log_message("has become a Lunatic!", LOG_ATTACK, color="red") // Masters gain an objective before so we dont want duplicates for(var/objective in objectives) if(!istype(objective, /datum/objective/lunatic)) @@ -27,6 +28,10 @@ lunatic_obj = loony return ..() +/datum/antagonist/lunatic/on_removal() + owner?.current?.log_message("lost their Lunatic status!", LOG_ATTACK, color="red") + return ..() + /// Runs when the moon heretic creates us, used to give the lunatic a master /datum/antagonist/lunatic/proc/set_master(datum/mind/heretic_master, mob/living/carbon/human/heretic_body) src.ascended_heretic = heretic_master diff --git a/code/modules/antagonists/heretic/status_effects/dreams.dm b/code/modules/antagonists/heretic/status_effects/dreams.dm new file mode 100644 index 00000000000..1b1db45f702 --- /dev/null +++ b/code/modules/antagonists/heretic/status_effects/dreams.dm @@ -0,0 +1,118 @@ +/datum/status_effect/grouped/heretic_dreams + id = "heretic_dreams" + duration = STATUS_EFFECT_PERMANENT + tick_interval = STATUS_EFFECT_NO_TICK + alert_type = null + /// Cooldown between allowed dreams + COOLDOWN_DECLARE(dreaming_cooldown) + +/datum/status_effect/grouped/heretic_dreams/on_apply() + . = ..() + RegisterSignal(owner, COMSIG_PRE_DREAMING, PROC_REF(add_heretic_dream)) + RegisterSignal(owner, COMSIG_START_DREAMING, PROC_REF(start_heretic_dream)) + +/datum/status_effect/grouped/heretic_dreams/on_remove() + . = ..() + UnregisterSignal(owner, COMSIG_PRE_DREAMING) + UnregisterSignal(owner, COMSIG_START_DREAMING) + +/datum/status_effect/grouped/heretic_dreams/proc/add_heretic_dream(mob/living/dreamer, list/dream_pool) + SIGNAL_HANDLER + + if(!COOLDOWN_FINISHED(src, dreaming_cooldown)) + return + + var/atom/dream_center = get_dream_center(dreamer) + if(isnull(dream_center)) + return + + dream_pool[new /datum/dream/heretic(dream_center)] = 200 + +/datum/status_effect/grouped/heretic_dreams/proc/start_heretic_dream(mob/living/dreamer, datum/dream/current_dream) + SIGNAL_HANDLER + + if(!istype(current_dream, /datum/dream/heretic)) + return + COOLDOWN_START(src, dreaming_cooldown, /datum/mood_event/mansus_dream_fatigue::timeout) + dreamer.add_mood_event("mansus_dream_fatigue", /datum/mood_event/mansus_dream_fatigue) + +/datum/status_effect/grouped/heretic_dreams/proc/get_dream_center(mob/living/dreamer) + // Select a random influence as the center of the dream + if(length(GLOB.reality_smash_track.smashes)) + return pick(GLOB.reality_smash_track.smashes) + + // If there are no influences, either don't trigger the dream (if we are a heretic) or pick a completely random locale (if we aren't) + if(IS_HERETIC(dreamer)) + return null + + return get_safe_random_station_turf_equal_weight() + +/// Heretics can see dreams about random machinery from the perspective of a random unused influence +/datum/dream/heretic + sleep_until_finished = TRUE + /// The location of the influence (or lack thereof in the case of a fake dream) we will be dreaming about + var/atom/dream_center + /// The distance to the objects visible from the influence during the dream + var/dream_view_range = 5 + var/list/what_you_can_see = list( + /obj/item, + /obj/structure, + /obj/machinery, + ) + var/static/list/what_you_cant_see = typecacheof(list( + // Underfloor stuff and default wallmounts + /obj/item/radio/intercom, + /obj/structure/cable, + /obj/structure/disposalpipe/segment, + /obj/machinery/atmospherics/pipe/smart/manifold4w, + /obj/machinery/atmospherics/components/unary/vent_scrubber, + /obj/machinery/atmospherics/components/unary/vent_pump, + /obj/machinery/duct, + /obj/machinery/navbeacon, + /obj/machinery/power/terminal, + /obj/machinery/power/apc, + /obj/machinery/light_switch, + /obj/machinery/light, + /obj/machinery/camera, + /obj/machinery/door/firedoor, + /obj/machinery/firealarm, + /obj/machinery/airalarm, + /obj/structure/window/fulltile, + /obj/structure/window/reinforced/fulltile, + )) + /// Cached list of allowed typecaches for each type in what_you_can_see + var/static/list/allowed_typecaches_by_root_type = null + +/datum/dream/heretic/New(atom/dream_center) + src.dream_center = dream_center + +/datum/dream/heretic/GenerateDream(mob/living/carbon/dreamer) + . = list() + . += "you wander through the forest of Mansus" + . += "there is a " + pick("pond", "well", "lake", "puddle", "stream", "spring", "brook", "marsh") + + if(isnull(allowed_typecaches_by_root_type)) + allowed_typecaches_by_root_type = list() + for(var/type in what_you_can_see) + allowed_typecaches_by_root_type[type] = typecacheof(type) - what_you_cant_see + + var/list/all_objects = oview(dream_view_range, dream_center) + var/something_found = FALSE + for(var/object_type in allowed_typecaches_by_root_type) + var/list/filtered_objects = typecache_filter_list(all_objects, allowed_typecaches_by_root_type[object_type]) + if(filtered_objects.len) + if (!something_found) + . += "its waters reflect" + something_found = TRUE + var/obj/found_object = pick(filtered_objects) + . += initial(found_object.name) + if(!something_found) + . += pick("it's pitch black", "ihe reflections are vague", "you stroll aimlessly") + else + . += "the images fade in the ripples" + . += "you feel exhausted" + +/datum/mood_event/mansus_dream_fatigue + description = "I must recover before I can dream of Mansus again." + mood_change = -2 + timeout = 5 MINUTES diff --git a/code/modules/antagonists/malf_ai/malf_ai_modules.dm b/code/modules/antagonists/malf_ai/malf_ai_modules.dm index 82dd7b3c95c..1ce6f88c8f4 100644 --- a/code/modules/antagonists/malf_ai/malf_ai_modules.dm +++ b/code/modules/antagonists/malf_ai/malf_ai_modules.dm @@ -653,7 +653,6 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf)) name = "Robotic Factory (Removes Shunting)" description = "Build a machine anywhere, using expensive nanomachines, that will slowly create loyal cyborgs for you." // SKYRAT EDIT cost = 100 - minimum_apcs = 10 // So you can't speedrun this power_type = /datum/action/innate/ai/place_transformer unlock_text = span_notice("You make contact with Space Amazon and request a robotics factory for delivery.") unlock_sound = 'sound/machines/ping.ogg' @@ -759,7 +758,7 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf)) power_type = /datum/action/innate/ai/break_fire_alarms unlock_text = span_notice("You replace the thermal sensing capabilities of all fire alarms with a manual override, \ allowing you to turn them off at will.") - unlock_sound = 'sound/machines/fire_alarm/FireAlarm1.ogg' + unlock_sound = 'sound/machines/fire_alarm/fire_alarm1.ogg' /datum/action/innate/ai/break_fire_alarms name = "Override Thermal Sensors" diff --git a/code/modules/antagonists/nukeop/datums/operative.dm b/code/modules/antagonists/nukeop/datums/operative.dm index dccd7450f97..ae3d3c9d777 100644 --- a/code/modules/antagonists/nukeop/datums/operative.dm +++ b/code/modules/antagonists/nukeop/datums/operative.dm @@ -15,6 +15,8 @@ var/datum/team/nuclear/nuke_team /// Should the user be moved to default spawnpoint after being granted this datum. var/send_to_spawnpoint = TRUE + /// Should the nukie get a little bonus tc depending on how many players there are + var/give_bonus_tc = TRUE var/job_type = /datum/job/nuclear_operative /// The DEFAULT outfit we will give to players granted this datum @@ -49,11 +51,11 @@ equip_op() if(send_to_spawnpoint) move_to_spawnpoint() - // grant extra TC for the people who start in the nukie base ie. not the lone op - var/extra_tc = CEILING(GLOB.joined_player_list.len/5, 5) + if(give_bonus_tc) + var/extra_tc = CEILING(GLOB.joined_player_list.len / 5, 5) var/datum/component/uplink/uplink = owner.find_syndicate_uplink() - if (uplink) - uplink.uplink_handler.add_telecrystals(extra_tc) + uplink?.uplink_handler.add_telecrystals(extra_tc) + var/datum/component/uplink/uplink = owner.find_syndicate_uplink() if(uplink) var/datum/team/nuclear/nuke_team = get_team() @@ -81,7 +83,7 @@ objectives |= nuke_team.objectives /datum/antagonist/nukeop/leader/get_spawnpoint() - return pick(GLOB.nukeop_leader_start) + return pick(GLOB.nukeop_base_leader_start) /datum/antagonist/nukeop/create_team(datum/team/nuclear/new_team) if(!new_team) @@ -146,7 +148,7 @@ return TRUE /datum/antagonist/nukeop/proc/admin_send_to_base(mob/admin) - owner.current.forceMove(pick(GLOB.nukeop_start)) + owner.current.forceMove(pick(GLOB.nukeop_base_start)) /datum/antagonist/nukeop/proc/admin_tell_code(mob/admin) var/code @@ -192,7 +194,7 @@ if(nuke_team) team_number = nuke_team.members.Find(owner) - return GLOB.nukeop_start[((team_number - 1) % GLOB.nukeop_start.len) + 1] + return GLOB.nukeop_base_start[((team_number - 1) % GLOB.nukeop_base_start.len) + 1] /datum/antagonist/nukeop/proc/spawn_infiltrator() var/datum/map_template/shuttle/infiltrator/ship = SSmapping.shuttle_templates[infiltrator_id] @@ -221,6 +223,6 @@ mobile_port.setTimer(mobile_port.ignitionTime) /datum/antagonist/nukeop/on_respawn(mob/new_character) - new_character.forceMove(pick(GLOB.nukeop_start)) + new_character.forceMove(pick(GLOB.nukeop_base_start)) equip_op() return TRUE diff --git a/code/modules/antagonists/nukeop/datums/operative_leader.dm b/code/modules/antagonists/nukeop/datums/operative_leader.dm index 7815c8c8631..3f3aaaf3185 100644 --- a/code/modules/antagonists/nukeop/datums/operative_leader.dm +++ b/code/modules/antagonists/nukeop/datums/operative_leader.dm @@ -1,6 +1,8 @@ /datum/antagonist/nukeop/leader name = "Nuclear Operative Leader" nukeop_outfit = /datum/outfit/syndicate/leader + /// Whether to spawn the infiltrator + var/spawn_ship = TRUE /// Randomly chosen honorific, for distinction var/title /// The nuclear challenge remote we will spawn this player with. @@ -63,7 +65,8 @@ return capitalize(newname) /datum/antagonist/nukeop/leader/create_team(datum/team/nuclear/new_team) - spawn_infiltrator() + if(spawn_ship) + spawn_infiltrator() if(new_team) return ..() // Leaders always make new teams diff --git a/code/modules/antagonists/nukeop/datums/operative_lone.dm b/code/modules/antagonists/nukeop/datums/operative_lone.dm index b074016890a..ba6d001ff80 100644 --- a/code/modules/antagonists/nukeop/datums/operative_lone.dm +++ b/code/modules/antagonists/nukeop/datums/operative_lone.dm @@ -1,6 +1,7 @@ /datum/antagonist/nukeop/lone name = "Lone Operative" send_to_spawnpoint = FALSE //Handled by event + give_bonus_tc = FALSE nukeop_outfit = /datum/outfit/syndicate/full/loneop preview_outfit = /datum/outfit/nuclear_operative preview_outfit_behind = null diff --git a/code/modules/antagonists/nukeop/datums/operative_reinforcement.dm b/code/modules/antagonists/nukeop/datums/operative_reinforcement.dm index eb386342c09..9cbad2572f8 100644 --- a/code/modules/antagonists/nukeop/datums/operative_reinforcement.dm +++ b/code/modules/antagonists/nukeop/datums/operative_reinforcement.dm @@ -2,6 +2,7 @@ name = "Nuclear Operative Reinforcement" show_in_antagpanel = FALSE send_to_spawnpoint = FALSE + give_bonus_tc = FALSE nukeop_outfit = /datum/outfit/syndicate/reinforcement /datum/antagonist/nukeop/reinforcement/cyborg diff --git a/code/modules/antagonists/nukeop/datums/operative_support.dm b/code/modules/antagonists/nukeop/datums/operative_support.dm index 1b1ea923903..b10bb4a369c 100644 --- a/code/modules/antagonists/nukeop/datums/operative_support.dm +++ b/code/modules/antagonists/nukeop/datums/operative_support.dm @@ -32,7 +32,7 @@ owner.current.grant_language(/datum/language/codespeak) /datum/antagonist/nukeop/support/get_spawnpoint() - return pick(GLOB.nukeop_overwatch_start) + return pick(GLOB.nukeop_base_overwatch_start) /datum/antagonist/nukeop/support/forge_objectives() var/datum/objective/overwatch/objective = new diff --git a/code/modules/antagonists/nukeop/datums/operative_team.dm b/code/modules/antagonists/nukeop/datums/operative_team.dm index 4eab9341d48..98ffe695e47 100644 --- a/code/modules/antagonists/nukeop/datums/operative_team.dm +++ b/code/modules/antagonists/nukeop/datums/operative_team.dm @@ -18,7 +18,7 @@ objectives += maingoal // when a nuke team is created, the infiltrator has not loaded in yet - it takes some time. so no nuke, we have to wait - addtimer(CALLBACK(src, PROC_REF(assign_nuke_delayed)), 4 SECONDS) + addtimer(CALLBACK(src, PROC_REF(assign_nuke_delayed)), 5 SECONDS) /datum/team/nuclear/roundend_report() var/list/parts = list() @@ -192,7 +192,7 @@ infil_or_nukebase = SPAWN_AT_BASE if(infil_or_nukebase == SPAWN_AT_BASE) - spawn_loc = pick(GLOB.nukeop_start) + spawn_loc = pick(GLOB.nukeop_base_start) var/mob/living/carbon/human/nukie = new(spawn_loc) chosen_one.client.prefs.safe_transfer_prefs_to(nukie, is_antag = TRUE) @@ -200,6 +200,7 @@ var/datum/antagonist/nukeop/antag_datum = new() antag_datum.send_to_spawnpoint = FALSE + antag_datum.give_bonus_tc = FALSE antag_datum.nukeop_outfit = /datum/outfit/syndicate/reinforcement nukie.mind.add_antag_datum(antag_datum, src) @@ -313,20 +314,25 @@ ..() SEND_SIGNAL(src, COMSIG_NUKE_TEAM_ADDITION, new_member.current) -/datum/team/nuclear/proc/assign_nuke_delayed() - assign_nuke() - if(tracked_nuke && memorized_code) - for(var/datum/mind/synd_mind in members) - var/datum/antagonist/nukeop/synd_datum = synd_mind.has_antag_datum(/datum/antagonist/nukeop) - synd_datum?.memorize_code() +/datum/team/nuclear/proc/assign_nuke_delayed(attempts = 0) + if(!assign_nuke()) + if(attempts > 5) + stack_trace("Failed to assign nuke to team after multiple attempts. \ + This likely means the nuke was not found. Please investigate.") + else + addtimer(CALLBACK(src, PROC_REF(assign_nuke_delayed), attempts + 1), 5 SECONDS) + return + + for(var/datum/mind/synd_mind as anything in members) + var/datum/antagonist/nukeop/synd_datum = synd_mind.has_antag_datum(/datum/antagonist/nukeop) + synd_datum?.memorize_code() /datum/team/nuclear/proc/assign_nuke() - memorized_code = random_nukecode() var/obj/machinery/nuclearbomb/syndicate/nuke = locate() in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/nuclearbomb/syndicate) if(!nuke) - stack_trace("Syndicate nuke not found during nuke team creation.") - memorized_code = null - return + return FALSE + + memorized_code = random_nukecode() tracked_nuke = nuke if(nuke.r_code == NUKE_CODE_UNSET) nuke.r_code = memorized_code @@ -334,6 +340,7 @@ memorized_code = nuke.r_code for(var/obj/machinery/nuclearbomb/beer/beernuke as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/nuclearbomb/beer)) beernuke.r_code = memorized_code + return TRUE #undef SPAWN_AT_BASE #undef SPAWN_AT_INFILTRATOR @@ -341,14 +348,14 @@ /datum/team/nuclear/loneop /datum/team/nuclear/loneop/assign_nuke() - memorized_code = random_nukecode() var/obj/machinery/nuclearbomb/selfdestruct/nuke = locate() in SSmachines.get_machines_by_type(/obj/machinery/nuclearbomb/selfdestruct) - if(nuke) - tracked_nuke = nuke - if(nuke.r_code == NUKE_CODE_UNSET) - nuke.r_code = memorized_code - else //Already set by admins/something else? - memorized_code = nuke.r_code - else - stack_trace("Station self-destruct not found during lone op team creation.") - memorized_code = null + if(!nuke) + return FALSE + + memorized_code = random_nukecode() + tracked_nuke = nuke + if(nuke.r_code == NUKE_CODE_UNSET) + nuke.r_code = memorized_code + else //Already set by admins/something else? + memorized_code = nuke.r_code + return TRUE diff --git a/code/modules/antagonists/nukeop/outfits.dm b/code/modules/antagonists/nukeop/outfits.dm index ec2b63e7413..74402a2cd06 100644 --- a/code/modules/antagonists/nukeop/outfits.dm +++ b/code/modules/antagonists/nukeop/outfits.dm @@ -144,11 +144,10 @@ /datum/outfit/syndicate/reinforcement/cybersun name = "Syndicate Operative - Cybersun Reinforcement" - uniform = /obj/item/clothing/under/syndicate/combat - suit = /obj/item/clothing/suit/jacket/oversized - gloves = /obj/item/clothing/gloves/fingerless - glasses = /obj/item/clothing/glasses/sunglasses - mask = /obj/item/cigarette/cigar + uniform = /obj/item/clothing/under/syndicate/cybersun + gloves = /obj/item/clothing/gloves/combat + shoes = /obj/item/clothing/shoes/laceup + mask = /obj/item/clothing/mask/gas/syndicate/cybersun faction = "Cybersun Industries" /datum/outfit/syndicate/reinforcement/donk diff --git a/code/modules/antagonists/pirate/pirate_shuttle_equipment.dm b/code/modules/antagonists/pirate/pirate_shuttle_equipment.dm index 858f3906b43..fe7da57e654 100644 --- a/code/modules/antagonists/pirate/pirate_shuttle_equipment.dm +++ b/code/modules/antagonists/pirate/pirate_shuttle_equipment.dm @@ -173,7 +173,7 @@ /obj/machinery/piratepad name = "cargo hold pad" icon = 'icons/obj/machines/telepad.dmi' - icon_state = "lpad-idle-off" + icon_state = "lpad-off" base_icon_state = "lpad" /// Determines what icon is being shown VAR_PRIVATE/is_sending = FALSE @@ -213,11 +213,11 @@ /obj/machinery/piratepad/update_icon_state() . = ..() if(panel_open) - icon_state = "[base_icon_state]-idle-open" + icon_state = "[base_icon_state]-open" else if(is_sending) - icon_state = "[base_icon_state]-idle" + icon_state = "[base_icon_state]" else - icon_state = "[base_icon_state]-idle-off" + icon_state = "[base_icon_state]-off" /obj/machinery/computer/piratepad_control name = "cargo hold control terminal" diff --git a/code/modules/antagonists/space_dragon/carp_rift.dm b/code/modules/antagonists/space_dragon/carp_rift.dm index 99eeb362627..126ccfab0f1 100644 --- a/code/modules/antagonists/space_dragon/carp_rift.dm +++ b/code/modules/antagonists/space_dragon/carp_rift.dm @@ -342,7 +342,7 @@ /obj/structure/carp_rift/hitby(atom/movable/hit_by, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) if(HAS_TRAIT(hit_by, TRAIT_TELEKINESIS_CONTROLLED)) - var/mob/thrower = throwingdatum.thrower.resolve() + var/mob/thrower = throwingdatum.thrower?.resolve() if(thrower && ismob(thrower)) to_chat(thrower, span_warning("The gravitational field of [src] interferes with the telekenetic control of [hit_by], nullifying the hit!")) return diff --git a/code/modules/antagonists/space_ninja/equipment/ninja_explosive.dm b/code/modules/antagonists/space_ninja/equipment/ninja_explosive.dm index 6e61ad68761..25317f623b7 100644 --- a/code/modules/antagonists/space_ninja/equipment/ninja_explosive.dm +++ b/code/modules/antagonists/space_ninja/equipment/ninja_explosive.dm @@ -51,7 +51,7 @@ if(!IS_SPACE_NINJA(user)) say("Access denied.") return FALSE - if(!check_loc(user)) + if(!check_loc(bomb_target, user)) return FALSE if(!..()) return FALSE @@ -59,7 +59,7 @@ return TRUE /obj/item/grenade/c4/ninja/detonate(mob/living/lanced_by) - if(!check_loc(detonator.resolve())) // if its moved, deactivate the c4 + if(!check_loc(target, detonator.resolve())) // if its moved, deactivate the c4 var/obj/item/grenade/c4/ninja/new_c4 = new /obj/item/grenade/c4/ninja(target.loc) new_c4.detonation_area = detonation_area new_c4.say("Invalid location!") @@ -87,11 +87,11 @@ * Arguments * * mob/user - The planter of the c4 */ -/obj/item/grenade/c4/ninja/proc/check_loc(mob/user) +/obj/item/grenade/c4/ninja/proc/check_loc(atom/bomb_target, mob/user) if(isnull(detonation_area)) balloon_alert(user, "no location set!") return FALSE - if((get_area(target) != detonation_area) && (get_area(src) != detonation_area)) + if(get_area(bomb_target) != detonation_area) if (!active) balloon_alert(user, "wrong location!") return FALSE diff --git a/code/modules/antagonists/spy/spy.dm b/code/modules/antagonists/spy/spy.dm index 3685800dcf1..224f083029c 100644 --- a/code/modules/antagonists/spy/spy.dm +++ b/code/modules/antagonists/spy/spy.dm @@ -196,6 +196,7 @@ var/mob/living/carbon/human/dummy/consistent/dummy = new() dummy.set_haircolor(COLOR_SILVER, update = FALSE) dummy.set_hairstyle("CIA", update = FALSE) + dummy.update_hair() var/datum/universal_icon/dummy_icon = render_preview_outfit(preview_outfit, dummy) qdel(dummy) return finish_preview_icon(dummy_icon) diff --git a/code/modules/antagonists/spy/spy_bounty.dm b/code/modules/antagonists/spy/spy_bounty.dm index a1020c3c93e..5344f86be2e 100644 --- a/code/modules/antagonists/spy/spy_bounty.dm +++ b/code/modules/antagonists/spy/spy_bounty.dm @@ -716,23 +716,23 @@ /datum/spy_bounty/some_bot/beepsky difficulty = SPY_DIFFICULTY_MEDIUM // gotta get him to stand still - bot_type = /mob/living/simple_animal/bot/secbot/beepsky/officer + bot_type = /mob/living/basic/bot/secbot/beepsky/officer help = "Abduct Officer Beepsky - commonly found patrolling the station. \ Watch out, they may not take kindly to being scanned." /datum/spy_bounty/some_bot/ofitser difficulty = SPY_DIFFICULTY_EASY - bot_type = /mob/living/simple_animal/bot/secbot/beepsky/ofitser + bot_type = /mob/living/basic/bot/secbot/beepsky/ofitser help = "Abduct Prison Ofitser - commonly found guarding the Gulag." /datum/spy_bounty/some_bot/armsky difficulty = SPY_DIFFICULTY_HARD - bot_type = /mob/living/simple_animal/bot/secbot/beepsky/armsky + bot_type = /mob/living/basic/bot/secbot/beepsky/armsky help = "Abduct Sergeant-At-Armsky - commonly found guarding the station's Armory." /datum/spy_bounty/some_bot/pingsky difficulty = SPY_DIFFICULTY_HARD - bot_type = /mob/living/simple_animal/bot/secbot/pingsky + bot_type = /mob/living/basic/bot/secbot/pingsky help = "Abduct Officer Pingsky - commonly found protecting the station's AI." /datum/spy_bounty/some_bot/scrubs diff --git a/code/modules/antagonists/voidwalker/voidwalker_mob.dm b/code/modules/antagonists/voidwalker/voidwalker_mob.dm index 447389876ea..1300c7b6d37 100644 --- a/code/modules/antagonists/voidwalker/voidwalker_mob.dm +++ b/code/modules/antagonists/voidwalker/voidwalker_mob.dm @@ -40,6 +40,11 @@ hud_possible = list(ANTAG_HUD) sight = SEE_TURFS | SEE_MOBS + //purplish tint night vision because the voidwalker is purple + lighting_cutoff_red = 30 + lighting_cutoff_green = 15 + lighting_cutoff_blue = 30 + /// Color of our regen outline var/regenerate_colour = COLOR_GRAY @@ -139,7 +144,7 @@ /mob/living/basic/voidwalker/early_melee_attack(atom/target, list/modifiers, ignore_cooldown) . = ..() - if(!. || !can_do_abductions) + if(. || !can_do_abductions) return if(ishuman(target)) @@ -151,12 +156,12 @@ hewmon.apply_status_effect(/datum/status_effect/void_chomped) if(!should_attack) - return FALSE + return BASIC_MOB_CONTINUE_ATTACK_CHAIN if(hewmon.stat == HARD_CRIT && !hewmon.has_trauma_type(/datum/brain_trauma/voided)) hewmon.balloon_alert(src, "is in crit!") hewmon.Stun(5 SECONDS) // blocks some crit movement mechanics from a bunch of sources - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN // left click if(LAZYACCESS(modifiers, LEFT_CLICK)) @@ -167,9 +172,9 @@ melee_damage_type = rclick_damage_type if(!istype(target, /turf/closed/wall)) - return + return BASIC_MOB_CONTINUE_ATTACK_CHAIN INVOKE_ASYNC(src, PROC_REF(try_convert_wall), target) - return TRUE + return BASIC_MOB_CONTINUE_ATTACK_CHAIN /// Called by the regenerator component so we only regen in space /mob/living/basic/voidwalker/proc/can_regen() diff --git a/code/modules/antagonists/wizard/equipment/soulstone.dm b/code/modules/antagonists/wizard/equipment/soulstone.dm index 7d30ceba8c6..f557b04b4f4 100644 --- a/code/modules/antagonists/wizard/equipment/soulstone.dm +++ b/code/modules/antagonists/wizard/equipment/soulstone.dm @@ -208,6 +208,11 @@ log_combat(user, M, "captured [M.name]'s soul", src) capture_soul(M, user) +/obj/item/soulstone/suicide_act(mob/living/user) + . = ..() + user.visible_message(span_suicide("[user] is capturing [user.p_their()] own soul with [src]! It looks like [user.p_theyre()] trying to commit suicide!")) + return capture_soul(user, null, TRUE) ? MANUAL_SUICIDE : BRUTELOSS + ///////////////////Options for using captured souls/////////////////////////////////////// /obj/item/soulstone/attack_self(mob/living/user) diff --git a/code/modules/antagonists/wizard/equipment/spellbook_entries/defensive.dm b/code/modules/antagonists/wizard/equipment/spellbook_entries/defensive.dm index 9a55eecd953..382e8963feb 100644 --- a/code/modules/antagonists/wizard/equipment/spellbook_entries/defensive.dm +++ b/code/modules/antagonists/wizard/equipment/spellbook_entries/defensive.dm @@ -55,7 +55,7 @@ it will become easier for others to find your item of power." spell_type = /datum/action/cooldown/spell/lichdom category = SPELLBOOK_CATEGORY_DEFENSIVE - no_coexistence_typecache = list(/datum/action/cooldown/spell/splattercasting, /datum/spellbook_entry/perks/wormborn) + no_coexistence_typecache = list(/datum/action/cooldown/spell/splattercasting, /datum/spellbook_entry/perks/wormborn, /datum/spellbook_entry/ghostliness) /datum/spellbook_entry/chuunibyou name = "Chuuni Invocations" @@ -117,13 +117,36 @@ /datum/spellbook_entry/item/wands name = "Wand Assortment" desc = "A collection of wands that allow for a wide variety of utility. \ - Wands have a limited number of charges, so be conservative with their use. Comes in a handy belt." + Wands have a limited number of charges, so be conservative with their use. \ + Comes in a handy belt, or a fancy bandolier if you are already wearing one." item_path = /obj/item/storage/belt/wands/full category = SPELLBOOK_CATEGORY_DEFENSIVE /datum/spellbook_entry/item/wands/try_equip_item(mob/living/carbon/human/user, obj/item/to_equip) - var/was_equipped = user.equip_to_slot_if_possible(to_equip, ITEM_SLOT_BELT, disable_warning = TRUE) - to_chat(user, span_notice("\A [to_equip.name] has been summoned [was_equipped ? "on your waist" : "at your feet"].")) + if (!istype(user.belt, /obj/item/storage/belt/wands)) + var/was_equipped = user.equip_to_slot_if_possible(to_equip, ITEM_SLOT_BELT, disable_warning = TRUE) + to_chat(user, span_notice("\A [to_equip.name] has been summoned [was_equipped ? "on your waist" : "at your feet"].")) + return + + // If you already have a wand belt you get a cool bandolier instead for your copious amount of wands + var/obj/item/storage/belt/wand_bandolier/bandolier = new(user.drop_location()) + + for (var/obj/item/wand_presumably in to_equip.atom_storage.real_location) + bandolier.atom_storage.attempt_insert(wand_presumably, user, messages = FALSE) + + qdel(to_equip) + + var/was_equipped = user.equip_to_slot_if_possible(bandolier, ITEM_SLOT_SUITSTORE, disable_warning = TRUE) + to_chat(user, span_notice("\A [bandolier.name] has been summoned [was_equipped ? "across your chest" : "at your feet"].")) + +/datum/spellbook_entry/item/wands/discount + name = "Wand Assortment (Bargain Bin)" + desc = "A random collection of wands sourced from apprentice wandmaking studies. \ + You're never quite sure what you're going to get. \ + Comes in a handy belt, or a fancy bandolier if you are already wearing one." + cost = 1 + item_path = /obj/item/storage/belt/wands/full/discount + category = SPELLBOOK_CATEGORY_DEFENSIVE /datum/spellbook_entry/item/armor name = "Mastercrafted Armor Set" diff --git a/code/modules/antagonists/wizard/equipment/spellbook_entries/mobility.dm b/code/modules/antagonists/wizard/equipment/spellbook_entries/mobility.dm index bc09b092f6c..eb0c841c105 100644 --- a/code/modules/antagonists/wizard/equipment/spellbook_entries/mobility.dm +++ b/code/modules/antagonists/wizard/equipment/spellbook_entries/mobility.dm @@ -59,4 +59,13 @@ cost = 2 // Puts it at 3 cost if you go for safety instant summons, but teleporting anywhere on screen is pretty good. category = SPELLBOOK_CATEGORY_MOBILITY +/datum/spellbook_entry/ghostliness + name = "Forsake Body" + desc = "A necromantic spell which permanently severs your soul from your body, and partially anchors it to the material plane. \ + In this state, you can enter a state of incorporeality, allowing you to pass through solid matter. This, however, includes \ + most such matter on or inside of you." + spell_type = /datum/action/cooldown/spell/ghostliness + category = SPELLBOOK_CATEGORY_MOBILITY + no_coexistence_typecache = list(/datum/spellbook_entry/lichdom, /datum/spellbook_entry/splattercasting) + #undef SPELLBOOK_CATEGORY_MOBILITY diff --git a/code/modules/antagonists/wizard/equipment/spellbook_entries/offensive.dm b/code/modules/antagonists/wizard/equipment/spellbook_entries/offensive.dm index 48653ea7ced..8cd1c5074e7 100644 --- a/code/modules/antagonists/wizard/equipment/spellbook_entries/offensive.dm +++ b/code/modules/antagonists/wizard/equipment/spellbook_entries/offensive.dm @@ -99,7 +99,7 @@ draining from you over time. You can replenish it from your victims, specifically their necks." spell_type = /datum/action/cooldown/spell/splattercasting category = SPELLBOOK_CATEGORY_OFFENSIVE - no_coexistence_typecache = list(/datum/action/cooldown/spell/lichdom) + no_coexistence_typecache = list(/datum/action/cooldown/spell/lichdom, /datum/spellbook_entry/ghostliness) /datum/spellbook_entry/sanguine_strike name = "Exsanguinating Strike" diff --git a/code/modules/antagonists/wizard/equipment/spellbook_entries/perks.dm b/code/modules/antagonists/wizard/equipment/spellbook_entries/perks.dm index 2d87616c0b1..4d4063f6efd 100644 --- a/code/modules/antagonists/wizard/equipment/spellbook_entries/perks.dm +++ b/code/modules/antagonists/wizard/equipment/spellbook_entries/perks.dm @@ -104,9 +104,10 @@ /datum/spellbook_entry/perks/heart_eater name = "Heart Eater" - desc = "Gives you ability to obtain a person's life force by eating their heart. \ + desc = "Gives you the ability to obtain a sentient being's life force by eating their heart. \ + Additionally, you can tear a vulnerable being's heart out with your bare hands. \ By eating someone's heart you can increase your damage resistance or gain random mutation. \ - Heart also give strong healing buff." + Hearts also provide strong healing." hud_icon = "hearteater" /datum/spellbook_entry/perks/heart_eater/buy_spell(mob/living/carbon/human/user, obj/item/spellbook/book, log_buy) diff --git a/code/modules/antagonists/wizard/equipment/wiz_robe.dm b/code/modules/antagonists/wizard/equipment/wiz_robe.dm index cae9a388ae0..26e6d85690a 100644 --- a/code/modules/antagonists/wizard/equipment/wiz_robe.dm +++ b/code/modules/antagonists/wizard/equipment/wiz_robe.dm @@ -119,7 +119,7 @@ inhand_icon_state = "wizrobe" body_parts_covered = CHEST|GROIN|ARMS|LEGS armor_type = /datum/armor/suit_wizrobe - allowed = list(/obj/item/teleportation_scroll, /obj/item/highfrequencyblade/wizard) + allowed = list(/obj/item/highfrequencyblade/wizard, /obj/item/storage/belt/wand_bandolier, /obj/item/teleportation_scroll) flags_inv = HIDEJUMPSUIT strip_delay = 5 SECONDS equip_delay_other = 5 SECONDS diff --git a/code/modules/antagonists/wizard/equipment/wizard_hammer.dm b/code/modules/antagonists/wizard/equipment/wizard_hammer.dm index 110fcfd214f..c5877735f31 100644 --- a/code/modules/antagonists/wizard/equipment/wizard_hammer.dm +++ b/code/modules/antagonists/wizard/equipment/wizard_hammer.dm @@ -113,16 +113,15 @@ var/atom/throw_target = get_edge_target_turf(target, get_dir(src, get_step_away(target, src))) target.throw_at(throw_target, 200, 4) -/obj/item/mjollnir/attack(mob/living/target_mob, mob/user) - ..() - if(QDELETED(target_mob)) +/obj/item/mjollnir/afterattack(atom/target, mob/user) + if(QDELETED(target)) return - if(HAS_TRAIT(user, TRAIT_PACIFISM)) - return - if(HAS_TRAIT(src, TRAIT_WIELDED)) - yeet_shock(target_mob) + if(HAS_TRAIT(src, TRAIT_WIELDED) && isliving(target)) + yeet_shock(target) /obj/item/mjollnir/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) . = ..() + if(.) + return if(!QDELETED(hit_atom) && isliving(hit_atom)) yeet_shock(hit_atom) diff --git a/code/modules/art/statues.dm b/code/modules/art/statues.dm index 2bb49122747..e86b53d68ea 100644 --- a/code/modules/art/statues.dm +++ b/code/modules/art/statues.dm @@ -332,14 +332,17 @@ . = ..() AddElement(/datum/element/eyestab) AddElement(/datum/element/wall_engraver) - //deals 200 damage to statues, meaning you can actually kill one in ~250 hits - AddElement(/datum/element/bane, target_type = /mob/living/basic/statue, damage_multiplier = 40) + AddComponent(/datum/component/bane, damage_multiplier = 40, should_bane_callback = CALLBACK(src, PROC_REF(bane_check)), label_text = "statues") /obj/item/chisel/Destroy() prepared_block = null tracked_user = null return ..() +/// Bane component callback +/obj/item/chisel/proc/bane_check(mob/living/target) + return istype(target, /mob/living/basic/statue) + /* Hit the block to start Point with the chisel at the target to choose what to sculpt or hit block to choose from preset statue types. diff --git a/code/modules/asset_cache/assets/tgui.dm b/code/modules/asset_cache/assets/tgui.dm index 4b31d93e037..89556bc4487 100644 --- a/code/modules/asset_cache/assets/tgui.dm +++ b/code/modules/asset_cache/assets/tgui.dm @@ -33,3 +33,9 @@ ) #endif + +/datum/asset/simple/chat_dark + keep_local_name = FALSE + assets = list( + "tgui-chat-dark.bundle.css" = file("tgui/public/tgui-chat-dark.bundle.css"), + ) diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index b9f59c3208d..2324824426a 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -172,6 +172,40 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) SEND_SIGNAL(src, COMSIG_GASMIX_MERGED) return TRUE +// Set the gas specie within the gas mix to a set amount, if there is none it will be created at the target temp +/datum/gas_mixture/proc/set_gas(gas_specie, amount) + ASSERT_GAS(gas_specie, src) + gases[gas_specie][MOLES] = amount + garbage_collect() + +/datum/gas_mixture/proc/set_temperature(target_temp) + temperature = target_temp + +/// Add a specific amount of moles to specified gas or add a new gas to the mix +/// amount is added so make it negative to remove +/datum/gas_mixture/proc/adjust_gas(gas, amount) + ASSERT_GAS(gas, src) + gases[gas][MOLES] += QUANTIZE(amount) + garbage_collect() + +/// Add a specific amount of moles to all the gasses present or add a new gas to the mix +///gases_moles is an associative list of gas species to their amount to be added +/datum/gas_mixture/proc/adjust_multiple_gases(list/gases_moles) + for(var/gas_specie in gases_moles) + ASSERT_GAS(gas_specie, src) + gases[gas_specie][MOLES] += gases_moles[gas_specie] + garbage_collect() + + +/// Modify the gas list as to convert moles of gas species A to gas species B +/// reactant and product are the gas species to convert and conversion_amount is the amount to be converted +/datum/gas_mixture/proc/convert_gas(datum/gas/reactant, datum/gas/product, conversion_amount) + var/list/cached_gases = gases + assert_gases(reactant, product) + cached_gases[reactant][MOLES] -= QUANTIZE(conversion_amount) + cached_gases[product][MOLES] += QUANTIZE(conversion_amount) + garbage_collect() + ///Proportionally removes amount of gas from the gas_mixture. ///Returns: gas_mixture with the gases removed /datum/gas_mixture/proc/remove(amount) @@ -764,3 +798,4 @@ GLOBAL_LIST_INIT(gaslist_cache, init_gaslist_cache()) atmos_contents += temperature_str return atmos_contents.Join(";") + diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm index d215c1c6803..4f5c643d05c 100644 --- a/code/modules/atmospherics/gasmixtures/reactions.dm +++ b/code/modules/atmospherics/gasmixtures/reactions.dm @@ -220,7 +220,7 @@ plasma_burn_rate = min(plasma_burn_rate, plasma[MOLES], oxygen[MOLES] * INVERSE(oxygen_burn_ratio)) //Ensures matter is conserved properly plasma[MOLES] = QUANTIZE(plasma[MOLES] - plasma_burn_rate) oxygen[MOLES] = QUANTIZE(oxygen[MOLES] - (plasma_burn_rate * oxygen_burn_ratio)) - if (super_saturation) + if(super_saturation) ASSERT_GAS(/datum/gas/tritium, air) cached_gases[/datum/gas/tritium][MOLES] += plasma_burn_rate else @@ -229,6 +229,7 @@ cached_gases[/datum/gas/carbon_dioxide][MOLES] += plasma_burn_rate * 0.75 cached_gases[/datum/gas/water_vapor][MOLES] += plasma_burn_rate * 0.25 + SET_REACTION_RESULTS((plasma_burn_rate) * (1 + oxygen_burn_ratio)) var/energy_released = FIRE_PLASMA_ENERGY_RELEASED * plasma_burn_rate var/new_heat_capacity = air.heat_capacity() @@ -583,6 +584,8 @@ nitrous_oxide[MOLES] -= 0.4 * bz_formed plasma[MOLES] -= 0.8 * bz_formed * (1-nitrous_oxide_decomposed_factor) + + SET_REACTION_RESULTS(bz_formed) var/energy_released = bz_formed * (BZ_FORMATION_ENERGY + nitrous_oxide_decomposed_factor * (N2O_DECOMPOSITION_ENERGY - BZ_FORMATION_ENERGY)) var/new_heat_capacity = air.heat_capacity() @@ -681,6 +684,7 @@ bz[MOLES] -= heat_efficiency * 0.05 //bz gets consumed to balance the nitrium production and not make it too common and/or easy cached_gases[/datum/gas/nitrium][MOLES] += heat_efficiency + SET_REACTION_RESULTS(heat_efficiency) var/energy_used = heat_efficiency * NITRIUM_FORMATION_ENERGY var/new_heat_capacity = air.heat_capacity() @@ -829,6 +833,7 @@ tritium[MOLES] -= 5 * nob_formed * reduction_factor nitrogen[MOLES] -= 10 * nob_formed cached_gases[/datum/gas/hypernoblium][MOLES] += nob_formed // I'm not going to nitpick, but N20H10 feels like it should be an explosive more than anything. + SET_REACTION_RESULTS(nob_formed) var/energy_released = nob_formed * NOBLIUM_FORMATION_ENERGY / max(bz[MOLES], 1) var/new_heat_capacity = air.heat_capacity() @@ -1254,6 +1259,7 @@ continue gas[MOLES] -= reaction_rate * gas[MOLES] / total_not_antinoblium_moles antinoblium[MOLES] += reaction_rate + SET_REACTION_RESULTS(reaction_rate) var/new_heat_capacity = air.heat_capacity() if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/temperature_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/temperature_pump.dm index 496a992e50b..60e355110b7 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/temperature_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/temperature_pump.dm @@ -14,6 +14,7 @@ /obj/machinery/atmospherics/components/binary/temperature_pump/Initialize(mapload) . = ..() + AddComponent(/datum/component/usb_port, typecacheof(list(/obj/item/circuit_component/atmos_temperature_pump), only_root_path = TRUE)) register_context() /obj/machinery/atmospherics/components/binary/temperature_pump/add_context(atom/source, list/context, obj/item/held_item, mob/user) diff --git a/code/modules/atmospherics/machinery/components/components_base.dm b/code/modules/atmospherics/machinery/components/components_base.dm index 23babb68c96..71eb4e1fb8d 100644 --- a/code/modules/atmospherics/machinery/components/components_base.dm +++ b/code/modules/atmospherics/machinery/components/components_base.dm @@ -268,8 +268,7 @@ internal_pressure = internal_pressure > airs[i].return_pressure() ? internal_pressure : airs[i].return_pressure() if(!filled_pipe) - default_deconstruction_crowbar(tool) - return ITEM_INTERACT_SUCCESS + return default_deconstruction_crowbar(user, tool) to_chat(user, span_notice("You begin to unfasten \the [src]...")) diff --git a/code/modules/atmospherics/machinery/components/electrolyzer/electrolyzer_reactions.dm b/code/modules/atmospherics/machinery/components/electrolyzer/electrolyzer_reactions.dm index 21fd7eb018a..6ff94177190 100644 --- a/code/modules/atmospherics/machinery/components/electrolyzer/electrolyzer_reactions.dm +++ b/code/modules/atmospherics/machinery/components/electrolyzer/electrolyzer_reactions.dm @@ -64,11 +64,11 @@ GLOBAL_LIST_INIT(electrolyzer_reactions, electrolyzer_reactions_list()) /datum/electrolyzer_reaction/h2o_conversion/react(datum/gas_mixture/air_mixture, working_power, list/electrolyzer_args = list()) var/old_heat_capacity = air_mixture.heat_capacity() - air_mixture.assert_gases(/datum/gas/water_vapor, /datum/gas/oxygen, /datum/gas/hydrogen) + var/proportion = min(air_mixture.gases[/datum/gas/water_vapor][MOLES] * INVERSE(2), (2.5 * (working_power ** 2))) - air_mixture.gases[/datum/gas/water_vapor][MOLES] -= proportion * 2 - air_mixture.gases[/datum/gas/oxygen][MOLES] += proportion - air_mixture.gases[/datum/gas/hydrogen][MOLES] += proportion * 2 + air_mixture.adjust_gas(/datum/gas/water_vapor, -proportion * 2) + air_mixture.adjust_gas(/datum/gas/oxygen, proportion) + air_mixture.adjust_gas(/datum/gas/hydrogen, proportion * 2) var/new_heat_capacity = air_mixture.heat_capacity() if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) air_mixture.temperature = max(air_mixture.temperature * old_heat_capacity / new_heat_capacity, TCMB) @@ -100,8 +100,10 @@ GLOBAL_LIST_INIT(electrolyzer_reactions, electrolyzer_reactions_list()) var/list/hypernoblium = cached_gases[/datum/gas/hypernoblium] var/list/antinoblium = cached_gases[/datum/gas/antinoblium] var/electrolysed = hypernoblium[MOLES] * clamp(supermatter_power - POWER_PENALTY_THRESHOLD, 0, CRITICAL_POWER_PENALTY_THRESHOLD - POWER_PENALTY_THRESHOLD) / (CRITICAL_POWER_PENALTY_THRESHOLD - POWER_PENALTY_THRESHOLD) - hypernoblium[MOLES] -= electrolysed - antinoblium[MOLES] += electrolysed + + air_mixture.adjust_gas(/datum/gas/hypernoblium, -electrolysed) + air_mixture.adjust_gas(/datum/gas/antinoblium, electrolysed) + var/new_heat_capacity = old_heat_capacity + electrolysed * (antinoblium[GAS_META][META_GAS_SPECIFIC_HEAT] - hypernoblium[GAS_META][META_GAS_SPECIFIC_HEAT]) if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) air_mixture.temperature = max(air_mixture.temperature * old_heat_capacity / new_heat_capacity, TCMB) @@ -126,9 +128,11 @@ GLOBAL_LIST_INIT(electrolyzer_reactions, electrolyzer_reactions_list()) var/old_heat_capacity = air_mixture.heat_capacity() air_mixture.assert_gases(/datum/gas/bz, /datum/gas/oxygen, /datum/gas/halon) var/reaction_efficency = min(air_mixture.gases[/datum/gas/bz][MOLES] * (1 - NUM_E ** (-0.5 * air_mixture.temperature * working_power / FIRE_MINIMUM_TEMPERATURE_TO_EXIST)), air_mixture.gases[/datum/gas/bz][MOLES]) - air_mixture.gases[/datum/gas/bz][MOLES] -= reaction_efficency - air_mixture.gases[/datum/gas/oxygen][MOLES] += reaction_efficency * 0.2 - air_mixture.gases[/datum/gas/halon][MOLES] += reaction_efficency * 2 + + air_mixture.adjust_gas(/datum/gas/bz, -reaction_efficency) + air_mixture.adjust_gas(/datum/gas/oxygen, reaction_efficency * 0.2) + air_mixture.adjust_gas(/datum/gas/halon, reaction_efficency * 2) + var/energy_used = reaction_efficency * HALON_FORMATION_ENERGY var/new_heat_capacity = air_mixture.heat_capacity() if(new_heat_capacity > MINIMUM_HEAT_CAPACITY) diff --git a/code/modules/atmospherics/machinery/components/fusion/hfr_main_processes.dm b/code/modules/atmospherics/machinery/components/fusion/hfr_main_processes.dm index 06fcda77b44..0dbf0cfaa54 100644 --- a/code/modules/atmospherics/machinery/components/fusion/hfr_main_processes.dm +++ b/code/modules/atmospherics/machinery/components/fusion/hfr_main_processes.dm @@ -250,37 +250,37 @@ var/scaled_production = production_amount * selected_fuel.gas_production_multiplier for(var/gas_id in fuel.requirements) - internal_fusion.gases[gas_id][MOLES] -= min(fuel_list[gas_id], fuel_consumption) + internal_fusion.adjust_gas(gas_id, -min(fuel_list[gas_id], fuel_consumption)) for(var/gas_id in fuel.primary_products) - internal_fusion.gases[gas_id][MOLES] += fuel_consumption * 0.5 + internal_fusion.adjust_gas(gas_id, fuel_consumption * 0.5) // Each recipe provides a tier list of six output gases. // Which gases are produced depend on what the fusion level is. var/list/tier = fuel.secondary_products switch(power_level) if(1) - moderator_internal.gases[tier[1]][MOLES] += scaled_production * 0.95 - moderator_internal.gases[tier[2]][MOLES] += scaled_production * 0.75 + moderator_internal.adjust_gas(tier[1], scaled_production * 0.95) + moderator_internal.adjust_gas(tier[2], scaled_production * 0.75) if(2) - moderator_internal.gases[tier[1]][MOLES] += scaled_production * 1.65 - moderator_internal.gases[tier[2]][MOLES] += scaled_production + moderator_internal.adjust_gas(tier[1], scaled_production * 1.65) + moderator_internal.adjust_gas(tier[2], scaled_production) if(moderator_list[/datum/gas/plasma] > 50) - moderator_internal.gases[tier[3]][MOLES] += scaled_production * 1.15 + moderator_internal.adjust_gas(tier[3], scaled_production * 1.15) if(3) - moderator_internal.gases[tier[2]][MOLES] += scaled_production * 0.5 - moderator_internal.gases[tier[3]][MOLES] += scaled_production * 0.45 + moderator_internal.adjust_gas(tier[2], scaled_production * 0.5) + moderator_internal.adjust_gas(tier[3], scaled_production * 0.45) if(4) - moderator_internal.gases[tier[3]][MOLES] += scaled_production * 1.65 - moderator_internal.gases[tier[4]][MOLES] += scaled_production * 1.25 + moderator_internal.adjust_gas(tier[3], scaled_production * 1.65) + moderator_internal.adjust_gas(tier[4], scaled_production * 1.25) if(moderator_list[/datum/gas/plasma] > 50) - moderator_internal.gases[tier[5]][MOLES] += scaled_production * 1.15 + moderator_internal.adjust_gas(tier[5], scaled_production * 1.15) if(5) - moderator_internal.gases[tier[4]][MOLES] += scaled_production * 0.65 - moderator_internal.gases[tier[5]][MOLES] += scaled_production - moderator_internal.gases[tier[6]][MOLES] += scaled_production * 0.75 + moderator_internal.adjust_gas(tier[4], scaled_production * 0.65) + moderator_internal.adjust_gas(tier[5], scaled_production) + moderator_internal.adjust_gas(tier[6], scaled_production * 0.75) if(6) - moderator_internal.gases[tier[5]][MOLES] += scaled_production * 0.35 - moderator_internal.gases[tier[6]][MOLES] += scaled_production + moderator_internal.adjust_gas(tier[5], scaled_production * 0.35) + moderator_internal.adjust_gas(tier[6], scaled_production) /** * Perform common fusion actions: @@ -293,94 +293,81 @@ switch(power_level) if(1) if(moderator_list[/datum/gas/plasma] > 100) - internal_output.assert_gases(/datum/gas/nitrous_oxide) - internal_output.gases[/datum/gas/nitrous_oxide] += scaled_production * 0.5 - moderator_internal.gases[/datum/gas/plasma][MOLES] -= min(moderator_internal.gases[/datum/gas/plasma][MOLES], scaled_production * 0.85) + internal_output.adjust_gas(/datum/gas/nitrous_oxide, scaled_production * 0.5) + moderator_internal.adjust_gas(/datum/gas/plasma, min(moderator_internal.gases[/datum/gas/plasma][MOLES], scaled_production * 0.85)) if(moderator_list[/datum/gas/bz] > 150) - internal_output.assert_gases(/datum/gas/halon) - internal_output.gases[/datum/gas/halon][MOLES] += scaled_production * 0.55 - moderator_internal.gases[/datum/gas/bz][MOLES] -= min(moderator_internal.gases[/datum/gas/bz][MOLES], scaled_production * 0.95) + internal_output.adjust_gas(/datum/gas/halon, scaled_production * 0.55) + moderator_internal.adjust_gas(/datum/gas/bz, min(moderator_internal.gases[/datum/gas/bz][MOLES], scaled_production * 0.95)) if(2) if(moderator_list[/datum/gas/plasma] > 50) - internal_output.assert_gases(/datum/gas/bz) - internal_output.gases[/datum/gas/bz][MOLES] += scaled_production * 1.8 - moderator_internal.gases[/datum/gas/plasma][MOLES] -= min(moderator_internal.gases[/datum/gas/plasma][MOLES], scaled_production * 1.75) + internal_output.adjust_gas(/datum/gas/bz, scaled_production * 1.8) + moderator_internal.adjust_gas(/datum/gas/plasma, min(moderator_internal.gases[/datum/gas/plasma][MOLES], scaled_production * 1.75)) if(moderator_list[/datum/gas/proto_nitrate] > 20) radiation *= 1.55 heat_output *= 1.025 - internal_output.assert_gases(/datum/gas/nitrium) - internal_output.gases[/datum/gas/nitrium][MOLES] += scaled_production * 1.05 - moderator_internal.gases[/datum/gas/proto_nitrate][MOLES] -= min(moderator_internal.gases[/datum/gas/proto_nitrate][MOLES], scaled_production * 1.35) + internal_output.adjust_gas(/datum/gas/nitrium, scaled_production * 1.05) + moderator_internal.adjust_gas(/datum/gas/proto_nitrate, min(moderator_internal.gases[/datum/gas/proto_nitrate][MOLES], scaled_production * 1.35)) if(3, 4) if(moderator_list[/datum/gas/plasma] > 10) - internal_output.assert_gases(/datum/gas/freon, /datum/gas/nitrium) - internal_output.gases[/datum/gas/freon][MOLES] += scaled_production * 0.15 - internal_output.gases[/datum/gas/nitrium][MOLES] += scaled_production * 1.05 - moderator_internal.gases[/datum/gas/plasma][MOLES] -= min(moderator_internal.gases[/datum/gas/plasma][MOLES], scaled_production * 0.45) + var/list/new_gases = list(/datum/gas/freon = scaled_production * 0.15, /datum/gas/nitrium = scaled_production * 1.05) + internal_output.adjust_multiple_gases(new_gases) + moderator_internal.adjust_gas(/datum/gas/plasma, min(moderator_internal.gases[/datum/gas/plasma][MOLES], scaled_production * 0.45)) if(moderator_list[/datum/gas/freon] > 50) heat_output *= 0.9 radiation *= 0.8 if(moderator_list[/datum/gas/proto_nitrate]> 15) - internal_output.assert_gases(/datum/gas/nitrium, /datum/gas/halon) - internal_output.gases[/datum/gas/nitrium][MOLES] += scaled_production * 1.25 - internal_output.gases[/datum/gas/halon][MOLES] += scaled_production * 1.15 - moderator_internal.gases[/datum/gas/proto_nitrate][MOLES] -= min(moderator_internal.gases[/datum/gas/proto_nitrate][MOLES], scaled_production * 1.55) + var/list/new_gases = list(/datum/gas/nitrium = scaled_production * 1.25, /datum/gas/halon = scaled_production * 1.15) + internal_output.adjust_multiple_gases(new_gases) + moderator_internal.adjust_gas(/datum/gas/proto_nitrate, min(moderator_internal.gases[/datum/gas/proto_nitrate][MOLES], scaled_production * 1.55)) radiation *= 1.95 heat_output *= 1.25 if(moderator_list[/datum/gas/bz] > 100) - internal_output.assert_gases(/datum/gas/healium, /datum/gas/proto_nitrate) - internal_output.gases[/datum/gas/proto_nitrate][MOLES] += scaled_production * 1.5 - internal_output.gases[/datum/gas/healium][MOLES] += scaled_production * 1.5 + var/list/new_gases = list(/datum/gas/healium = scaled_production * 1.5, /datum/gas/proto_nitrate = scaled_production * 1.5) + internal_output.adjust_multiple_gases(new_gases) visible_hallucination_pulse(src, HALLUCINATION_HFR(heat_output), 100 SECONDS * power_level * seconds_per_tick) if(5) if(moderator_list[/datum/gas/plasma] > 15) - internal_output.assert_gases(/datum/gas/freon) - internal_output.gases[/datum/gas/freon][MOLES] += scaled_production *0.25 - moderator_internal.gases[/datum/gas/plasma][MOLES] -= min(moderator_internal.gases[/datum/gas/plasma][MOLES], scaled_production * 1.45) + internal_output.adjust_gas(/datum/gas/freon, scaled_production *0.25) + moderator_internal.adjust_gas(/datum/gas/plasma,min(moderator_internal.gases[/datum/gas/plasma][MOLES], scaled_production * 1.45)) if(moderator_list[/datum/gas/freon] > 500) heat_output *= 0.5 radiation *= 0.2 if(moderator_list[/datum/gas/proto_nitrate] > 50) - internal_output.assert_gases(/datum/gas/nitrium, /datum/gas/pluoxium) - internal_output.gases[/datum/gas/nitrium][MOLES] += scaled_production * 1.95 - internal_output.gases[/datum/gas/pluoxium][MOLES] += scaled_production - moderator_internal.gases[/datum/gas/proto_nitrate][MOLES] -= min(moderator_internal.gases[/datum/gas/proto_nitrate][MOLES], scaled_production * 1.35) + var/list/new_gases = list(/datum/gas/nitrium = scaled_production * 1.95, /datum/gas/pluoxium = scaled_production) + internal_output.adjust_multiple_gases(new_gases) + moderator_internal.adjust_gas(/datum/gas/proto_nitrate, min(moderator_internal.gases[/datum/gas/proto_nitrate][MOLES], scaled_production * 1.35)) radiation *= 1.95 heat_output *= 1.25 if(moderator_list[/datum/gas/bz] > 100) - internal_output.assert_gases(/datum/gas/healium, /datum/gas/freon) - internal_output.gases[/datum/gas/healium][MOLES] += scaled_production + var/list/new_gases = list(/datum/gas/healium = scaled_production, /datum/gas/freon = scaled_production * 1.15) + internal_output.adjust_multiple_gases(new_gases) visible_hallucination_pulse(src, HALLUCINATION_HFR(heat_output), 100 SECONDS * power_level * seconds_per_tick) - internal_output.gases[/datum/gas/freon][MOLES] += scaled_production * 1.15 if(moderator_list[/datum/gas/healium] > 100) if(critical_threshold_proximity > 400) critical_threshold_proximity = max(critical_threshold_proximity - (moderator_list[/datum/gas/healium] / 100 * seconds_per_tick ), 0) - moderator_internal.gases[/datum/gas/healium][MOLES] -= min(moderator_internal.gases[/datum/gas/healium][MOLES], scaled_production * 20) + moderator_internal.adjust_gas(/datum/gas/healium, -min(moderator_internal.gases[/datum/gas/healium][MOLES], scaled_production * 20)) if(moderator_internal.temperature < 1e7 || (moderator_list[/datum/gas/plasma] > 100 && moderator_list[/datum/gas/bz] > 50)) - internal_output.assert_gases(/datum/gas/antinoblium) - internal_output.gases[/datum/gas/antinoblium][MOLES] += dirty_production_rate * 0.9 / 0.065 * seconds_per_tick + internal_output.adjust_gas(/datum/gas/antinoblium, dirty_production_rate * 0.9 / 0.065 * seconds_per_tick) if(6) internal_output.assert_gases(/datum/gas/antinoblium) if(moderator_list[/datum/gas/plasma] > 30) - internal_output.assert_gases(/datum/gas/bz) - internal_output.gases[/datum/gas/bz][MOLES] += scaled_production * 1.15 - moderator_internal.gases[/datum/gas/plasma][MOLES] -= min(moderator_internal.gases[/datum/gas/plasma][MOLES], scaled_production * 1.45) + internal_output.adjust_gas(/datum/gas/bz, scaled_production * 1.15) + moderator_internal.adjust_gas(/datum/gas/plasma, -min(moderator_internal.gases[/datum/gas/plasma][MOLES], scaled_production * 1.45)) if(moderator_list[/datum/gas/proto_nitrate]) - internal_output.assert_gases(/datum/gas/zauker, /datum/gas/nitrium) - internal_output.gases[/datum/gas/zauker][MOLES] += scaled_production * 5.35 - internal_output.gases[/datum/gas/nitrium][MOLES] += scaled_production * 2.15 - moderator_internal.gases[/datum/gas/proto_nitrate][MOLES] -= min(moderator_internal.gases[/datum/gas/proto_nitrate][MOLES], scaled_production * 3.35) + var/list/new_gases = list(/datum/gas/zauker = scaled_production * 5.35, /datum/gas/nitrium = scaled_production * 2.15) + internal_output.adjust_multiple_gases(new_gases) + moderator_internal.adjust_gas(/datum/gas/proto_nitrate, -min(moderator_internal.gases[/datum/gas/proto_nitrate][MOLES], scaled_production * 3.35)) radiation *= 2 heat_output *= 2.25 if(moderator_list[/datum/gas/bz]) visible_hallucination_pulse(src, HALLUCINATION_HFR(heat_output), 100 SECONDS * power_level * seconds_per_tick) - internal_output.gases[/datum/gas/antinoblium][MOLES] += clamp(dirty_production_rate / 0.045, 0, 10) * seconds_per_tick + internal_output.adjust_gas(/datum/gas/antinoblium, clamp(dirty_production_rate / 0.045, 0, 10) * seconds_per_tick) if(moderator_list[/datum/gas/healium] > 100) if(critical_threshold_proximity > 400) critical_threshold_proximity = max(critical_threshold_proximity - (moderator_list[/datum/gas/healium] / 100 * seconds_per_tick ), 0) - moderator_internal.gases[/datum/gas/healium][MOLES] -= min(moderator_internal.gases[/datum/gas/healium][MOLES], scaled_production * 20) - internal_fusion.gases[/datum/gas/antinoblium][MOLES] += dirty_production_rate * 0.01 / 0.095 * seconds_per_tick + moderator_internal.adjust_gas(/datum/gas/healium, -min(moderator_internal.gases[/datum/gas/healium][MOLES], scaled_production * 20)) + internal_fusion.adjust_gas(/datum/gas/antinoblium, dirty_production_rate * 0.01 / 0.095 * seconds_per_tick) //Modifies the internal_fusion temperature with the amount of heat output var/temperature_modifier = selected_fuel.temperature_change_multiplier @@ -413,7 +400,7 @@ var/max_iron_removable = IRON_OXYGEN_HEAL_PER_SECOND var/iron_removed = min(max_iron_removable * seconds_per_tick, iron_content) iron_content -= iron_removed - moderator_internal.gases[/datum/gas/oxygen][MOLES] -= iron_removed * OXYGEN_MOLES_CONSUMED_PER_IRON_HEAL + moderator_internal.adjust_gas(/datum/gas/oxygen, -iron_removed * OXYGEN_MOLES_CONSUMED_PER_IRON_HEAL) check_gravity_pulse(seconds_per_tick) diff --git a/code/modules/atmospherics/machinery/components/gas_recipe_machines/crystallizer.dm b/code/modules/atmospherics/machinery/components/gas_recipe_machines/crystallizer.dm index b48dbd53c0c..5f24e939746 100644 --- a/code/modules/atmospherics/machinery/components/gas_recipe_machines/crystallizer.dm +++ b/code/modules/atmospherics/machinery/components/gas_recipe_machines/crystallizer.dm @@ -55,12 +55,15 @@ if(TOOL_SCREWDRIVER) context[SCREENTIP_CONTEXT_LMB] = "[panel_open ? "Close" : "Open"] panel" if(TOOL_WRENCH) - context[SCREENTIP_CONTEXT_RMB] = "Rotate" + context[SCREENTIP_CONTEXT_LMB] = "Rotate" return CONTEXTUAL_SCREENTIP_SET /obj/machinery/atmospherics/components/binary/crystallizer/screwdriver_act(mob/living/user, obj/item/tool) return on ? NONE : default_deconstruction_screwdriver(user, tool) +/obj/machinery/atmospherics/components/binary/crystallizer/wrench_act(mob/living/user, obj/item/tool) + return default_change_direction_wrench(user, tool) + /obj/machinery/atmospherics/components/binary/crystallizer/crowbar_act(mob/living/user, obj/item/tool) return crowbar_deconstruction_act(user, tool, internal.return_pressure()) diff --git a/code/modules/atmospherics/machinery/components/tank.dm b/code/modules/atmospherics/machinery/components/tank.dm index 1bfb9c1d5b2..8d9381df273 100644 --- a/code/modules/atmospherics/machinery/components/tank.dm +++ b/code/modules/atmospherics/machinery/components/tank.dm @@ -143,8 +143,8 @@ var/pressure_limit = max_pressure * safety_margin var/moles_to_add = (pressure_limit * air_contents.volume) / (R_IDEAL_GAS_EQUATION * air_contents.temperature) - air_contents.assert_gas(gastype) - air_contents.gases[gastype][MOLES] += moles_to_add + + air_contents.adjust_gas(gastype, moles_to_add) air_contents.archive() /obj/machinery/atmospherics/components/tank/process_atmos() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm b/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm index fc3622b892f..225a357ebca 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm @@ -33,6 +33,9 @@ var/datum/gas_mixture/external = location.return_air() var/datum/gas_mixture/internal = airs[1] + if(!internal.volume || !external.volume) + return + if(internal.equalize(external)) air_update_turf(FALSE, FALSE) update_parents() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm index 7fb5364170b..87d25f25a32 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm @@ -43,6 +43,8 @@ /obj/machinery/atmospherics/components/unary/thermomachine/Initialize(mapload) . = ..() update_appearance(UPDATE_ICON) + if(interactive) + AddComponent(/datum/component/usb_port, typecacheof(list(/obj/item/circuit_component/thermomachine), only_root_path = TRUE)) register_context() /obj/machinery/atmospherics/components/unary/thermomachine/add_context(atom/source, list/context, obj/item/held_item, mob/user) diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm index 0ca5fbff785..3a76be7b184 100644 --- a/code/modules/atmospherics/machinery/portable/canister.dm +++ b/code/modules/atmospherics/machinery/portable/canister.dm @@ -308,9 +308,8 @@ pressure_limit = 1e14 /obj/machinery/portable_atmospherics/canister/fusion_test/create_gas() - air_contents.add_gases(/datum/gas/hydrogen, /datum/gas/tritium) - air_contents.gases[/datum/gas/hydrogen][MOLES] = 300 - air_contents.gases[/datum/gas/tritium][MOLES] = 300 + air_contents.adjust_gas(/datum/gas/hydrogen, 300) + air_contents.adjust_gas(/datum/gas/tritium, 300) air_contents.temperature = 10000 SSair.start_processing_machine(src) @@ -323,9 +322,8 @@ greyscale_colors = "#9fba6c#3d4680" /obj/machinery/portable_atmospherics/canister/anesthetic_mix/create_gas() - air_contents.add_gases(/datum/gas/oxygen, /datum/gas/nitrous_oxide) - air_contents.gases[/datum/gas/oxygen][MOLES] = (O2_ANESTHETIC * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) - air_contents.gases[/datum/gas/nitrous_oxide][MOLES] = (N2O_ANESTHETIC * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) + air_contents.adjust_gas(/datum/gas/oxygen, (O2_ANESTHETIC * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)) + air_contents.adjust_gas(/datum/gas/nitrous_oxide, (N2O_ANESTHETIC * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)) SSair.start_processing_machine(src) /** @@ -335,14 +333,12 @@ /obj/machinery/portable_atmospherics/canister/proc/create_gas() if(!gas_type) return - air_contents.add_gas(gas_type) - air_contents.gases[gas_type][MOLES] = (maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) + air_contents.adjust_gas(gas_type, (maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)) SSair.start_processing_machine(src) /obj/machinery/portable_atmospherics/canister/air/create_gas() - air_contents.add_gases(/datum/gas/oxygen, /datum/gas/nitrogen) - air_contents.gases[/datum/gas/oxygen][MOLES] = (O2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) - air_contents.gases[/datum/gas/nitrogen][MOLES] = (N2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature) + air_contents.adjust_gas(/datum/gas/oxygen, (O2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)) + air_contents.adjust_gas(/datum/gas/nitrogen, (N2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)) SSair.start_processing_machine(src) /obj/machinery/portable_atmospherics/canister/update_icon_state() diff --git a/code/modules/atmospherics/machinery/portable/pipe_scrubber.dm b/code/modules/atmospherics/machinery/portable/pipe_scrubber.dm index 60f3ac82bb8..6ab73e5b2e1 100644 --- a/code/modules/atmospherics/machinery/portable/pipe_scrubber.dm +++ b/code/modules/atmospherics/machinery/portable/pipe_scrubber.dm @@ -93,6 +93,7 @@ filtered.temperature = filtering.temperature for(var/gas in filtering.gases & scrubbing) filtered.add_gas(gas) + filtered.gases[gas][MOLES] = filtering.gases[gas][MOLES] // Shuffle the "bad" gasses to the filtered mixture. filtering.gases[gas][MOLES] = 0 filtering.garbage_collect() // Now that the gasses are set to 0, clean up the mixture. diff --git a/code/modules/atmospherics/machinery/portable/scrubber.dm b/code/modules/atmospherics/machinery/portable/scrubber.dm index b1b094c9db0..4fd3392c32b 100644 --- a/code/modules/atmospherics/machinery/portable/scrubber.dm +++ b/code/modules/atmospherics/machinery/portable/scrubber.dm @@ -84,7 +84,7 @@ //contains all of the gas we're sucking out of the tile, gets put into our parent pipenet var/datum/gas_mixture/filtered_out = new - var/list/filtered_gases = filtered_out.gases + filtered_out.temperature = environment.temperature //maximum percentage of the turfs gas we can filter @@ -102,8 +102,8 @@ filtered_out.add_gas(gas) var/transferred_moles = max(QUANTIZE(env_gases[gas][MOLES] * removal_ratio * (env_gases[gas][MOLES] / total_moles_to_remove)), min(MOLAR_ACCURACY*1000, env_gases[gas][MOLES])) - filtered_gases[gas][MOLES] = transferred_moles - env_gases[gas][MOLES] -= transferred_moles + filtered_out.adjust_gas(gas, transferred_moles) + environment.adjust_gas(gas, -transferred_moles) environment.garbage_collect() diff --git a/code/modules/autowiki/pages/vending.dm b/code/modules/autowiki/pages/vending.dm index e110afa760e..eb10e0549e4 100644 --- a/code/modules/autowiki/pages/vending.dm +++ b/code/modules/autowiki/pages/vending.dm @@ -11,7 +11,7 @@ var/obj/parent = new for (var/obj/machinery/vending/vending_type as anything in sort_list(subtypesof(/obj/machinery/vending), GLOBAL_PROC_REF(cmp_typepaths_asc))) - var/obj/machinery/vending/parent_machine = type2parent(vending_type) + var/obj/machinery/vending/parent_machine = vending_type::parent_type if(initial(parent_machine.name) == initial(vending_type.name)) continue //Same name, likely just a slightly touched up subtype for specific maps. var/obj/machinery/vending/vending_machine = new vending_type(parent) diff --git a/code/modules/awaymissions/mission_code/heretic/naval_cannon.dm b/code/modules/awaymissions/mission_code/heretic/naval_cannon.dm new file mode 100644 index 00000000000..7b7d81602ac --- /dev/null +++ b/code/modules/awaymissions/mission_code/heretic/naval_cannon.dm @@ -0,0 +1,36 @@ +/obj/machinery/deployable_turret/naval_cannon + name = "Bofors Naval Cannon" + desc = "A naval cannon of some variety, it probably won't feel good to be on the other end of this thing." + icon = 'icons/obj/weapons/naval_cannon.dmi' + icon_state = "turret_bofors" + max_integrity = 5000 //its a naval cannon, but its not unbreakable + projectile_type = /obj/projectile/bullet/mm40 + anchored = TRUE //nobody should be bringing this back to station, this is a set piece. + number_of_shots = 1 + firesound = 'sound/items/weapons/gun/general/cannon.ogg' + overheatsound = 'sound/items/tools/ratchet_slow.ogg' + can_be_undeployed = FALSE + always_anchored = TRUE + +/obj/item/ammo_casing/mm40 + name = "40mm shell" + desc = "A 40mm shell." + caliber = CALIBER_40MM_SHELL + projectile_type = /obj/projectile/bullet/mm40 + icon_state = "40mm-shell" + newtonian_force = 10 + slowdown = 2 //tank shells weigh a lot + +/obj/projectile/bullet/mm40 + name ="40mm shell" + icon_state = "40mm" + speed = 2 + range = 400 + damage = 600 + paralyze = 5 SECONDS + armour_penetration = 50 + +/obj/projectile/bullet/mm40/on_hit(atom/target, blocked = 0, pierce_hit) + ..() + explosion(target, devastation_range = -1, heavy_impact_range = 2, light_impact_range = 3, flame_range = 4, flash_range = 6, adminlog = FALSE) + return BULLET_ACT_HIT diff --git a/code/modules/awaymissions/mission_code/murderdome.dm b/code/modules/awaymissions/mission_code/murderdome.dm index 0253ad69f93..87bb666fedb 100644 --- a/code/modules/awaymissions/mission_code/murderdome.dm +++ b/code/modules/awaymissions/mission_code/murderdome.dm @@ -12,11 +12,10 @@ obj_flags = CONDUCTS_ELECTRICITY resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF -/obj/structure/grille/indestructible/screwdriver_act(mob/living/user, obj/item/tool) - return NONE - -/obj/structure/grille/indestructible/wirecutter_act(mob/living/user, obj/item/tool) - return NONE +/obj/structure/grille/indestructible/Initialize(mapload) + . = ..() + AddElement(/datum/element/tool_blocker, TOOL_SCREWDRIVER, TOOL_ACT_PRIMARY) + AddElement(/datum/element/tool_blocker, TOOL_WIRECUTTER, TOOL_ACT_PRIMARY) /obj/effect/spawner/structure/window/reinforced/indestructible spawn_list = list(/obj/structure/grille/indestructible, /obj/structure/window/reinforced/fulltile/indestructible) diff --git a/code/modules/bitrunning/components/avatar_connection.dm b/code/modules/bitrunning/components/avatar_connection.dm index 8fa4cd90011..35c1e4e74aa 100644 --- a/code/modules/bitrunning/components/avatar_connection.dm +++ b/code/modules/bitrunning/components/avatar_connection.dm @@ -188,7 +188,11 @@ if(damage > 30 && prob(30)) INVOKE_ASYNC(old_body, TYPE_PROC_REF(/mob/living, emote), "scream") - old_body.apply_damage(damage, damage_type, def_zone, blocked, wound_bonus = CANT_WOUND) + var/zone = def_zone + if(isbodypart(def_zone)) // If the defined zone is a bodypart, then it is the bodypart of the domain avatar. We don't want that bodypart, we want the real body's bodypart, so we go back to zone. + zone = astype(def_zone, /obj/item/bodypart).body_zone + + old_body.apply_damage(damage, damage_type, zone, blocked, wound_bonus = CANT_WOUND) if(old_body.stat > SOFT_CRIT) // KO! full_avatar_disconnect(cause_damage = TRUE) diff --git a/code/modules/bitrunning/components/bitrunning_points.dm b/code/modules/bitrunning/components/bitrunning_points.dm deleted file mode 100644 index 039f3a9d338..00000000000 --- a/code/modules/bitrunning/components/bitrunning_points.dm +++ /dev/null @@ -1,36 +0,0 @@ -/// Attaches to a turf so it spawns a crate when a certain amount of points are added to it. -/datum/component/bitrunning_points - /// The amount required to spawn a crate - var/points_goal = 10 - /// A special condition limits this from spawning a crate - var/points_received = 0 - - -/datum/component/bitrunning_points/Initialize(datum/lazy_template/virtual_domain/domain) - if(!isturf(parent)) - return COMPONENT_INCOMPATIBLE - - RegisterSignal(domain, COMSIG_BITRUNNER_GOAL_POINT, PROC_REF(on_add_points)) - - -/// Listens for points to be added which will eventually spawn a crate. -/datum/component/bitrunning_points/proc/on_add_points(datum/source, points_to_add) - SIGNAL_HANDLER - - points_received += points_to_add - - if(points_received < points_goal) - return - - reveal() - - -/// Spawns the crate with some effects -/datum/component/bitrunning_points/proc/reveal() - playsound(src, 'sound/effects/magic/blink.ogg', 50, TRUE) - - var/turf/tile = parent - var/obj/structure/closet/crate/secure/bitrunning/encrypted/crate = new() - crate.forceMove(tile) // Triggers any on-move effects on that turf - do_sparks(5, FALSE, tile, spark_type = /datum/effect_system/basic/spark_spread/quantum) - qdel(src) diff --git a/code/modules/bitrunning/objects/disks.dm b/code/modules/bitrunning/objects/disks.dm index fbbca9ab8e8..d206f6e96a9 100644 --- a/code/modules/bitrunning/objects/disks.dm +++ b/code/modules/bitrunning/objects/disks.dm @@ -186,7 +186,7 @@ /obj/item/borg/upgrade/modkit/range, /obj/item/borg/upgrade/modkit/damage, /obj/item/borg/upgrade/modkit/cooldown, - /obj/item/borg/upgrade/modkit/aoe/mobs, + /obj/item/borg/upgrade/modkit/cooldown/aoe/mobs, /obj/item/borg/upgrade/modkit/human_passthrough, ) diff --git a/code/modules/bitrunning/objects/hololadder.dm b/code/modules/bitrunning/objects/hololadder.dm index 3df41a403e7..1335ef8b848 100644 --- a/code/modules/bitrunning/objects/hololadder.dm +++ b/code/modules/bitrunning/objects/hololadder.dm @@ -64,6 +64,14 @@ if(isnull(user.mind)) return + var/obj/machinery/quantum_server/our_server = server_ref.resolve() + if(!our_server.domain_complete) + for(var/datum/weakref/ghostrole_weakref as anything in our_server.spawned_threat_refs) + var/mob/living/ghostrole = ghostrole_weakref.resolve() + if(ghostrole?.stat == CONSCIOUS && ghostrole.client && ghostrole.mind.has_antag_datum(/datum/antagonist/bitrunning_glitch)) + to_chat(user, span_danger("A being in the simulation is preventing your retreat. You must either complete your mission or remove the obstacle before safe exit will be possible.")) + return + if(!HAS_TRAIT(user, TRAIT_TEMPORARY_BODY)) balloon_alert(user, "no connection detected") return diff --git a/code/modules/bitrunning/server/_parent.dm b/code/modules/bitrunning/server/_parent.dm index 89525514e47..a0e60892326 100644 --- a/code/modules/bitrunning/server/_parent.dm +++ b/code/modules/bitrunning/server/_parent.dm @@ -16,6 +16,8 @@ var/datum/lazy_template/virtual_domain/generated_domain /// If the current domain was a random selection var/domain_randomized = FALSE + /// Whether the domain is finished, so the bitrunners can leave despite glitches + var/domain_complete = FALSE /// Prevents multiple user actions. Handled by loading domains and cooldowns var/is_ready = TRUE /// Chance multipled by threat to spawn a glitch diff --git a/code/modules/bitrunning/server/loot.dm b/code/modules/bitrunning/server/loot.dm index 9fdbcebbca4..2d9db6c5a7d 100644 --- a/code/modules/bitrunning/server/loot.dm +++ b/code/modules/bitrunning/server/loot.dm @@ -80,6 +80,8 @@ generated_domain.disk_reward_spawned = TRUE chosen_forge.start_to_spawn(reward_cache) + + domain_complete = TRUE return TRUE diff --git a/code/modules/bitrunning/server/map_handling.dm b/code/modules/bitrunning/server/map_handling.dm index 96a10d60bbf..9076f30a73a 100644 --- a/code/modules/bitrunning/server/map_handling.dm +++ b/code/modules/bitrunning/server/map_handling.dm @@ -53,12 +53,12 @@ scrub_vdom() is_ready = TRUE return FALSE - - + + //We will want to record how the domain was selected. Either entirely randomly, with the name redacted, or with full information. //Without this, it is difficult to determine what domains are selected more often intentionallly, vs unintentionally. var/selection_type - + if(was_random_selection) selection_type = "random selection" else @@ -168,8 +168,7 @@ continue if(istype(thing, /obj/effect/landmark/bitrunning/loot_signal)) - var/turf/signaler_turf = get_turf(thing) - signaler_turf.AddComponent(/datum/component/bitrunning_points, generated_domain) + generated_domain.main_crate_loc = thing.loc qdel(thing) continue @@ -200,6 +199,7 @@ /// Stops the current virtual domain and disconnects all users /obj/machinery/quantum_server/proc/reset(fast = FALSE) is_ready = FALSE + domain_complete = FALSE sever_connections() diff --git a/code/modules/bitrunning/server/threats.dm b/code/modules/bitrunning/server/threats.dm index 34583aa358d..c9c33c49f44 100644 --- a/code/modules/bitrunning/server/threats.dm +++ b/code/modules/bitrunning/server/threats.dm @@ -142,6 +142,22 @@ aas.broadcast("QUANTUM SERVER ALERT: Fabrication protocols have crashed unexpectedly. Please evacuate the area.", list(RADIO_CHANNEL_SUPPLY)) timeout = 10 SECONDS + var/bitrunners_alive = 0 + var/island_brawl_exception = istype(generated_domain, /datum/lazy_template/virtual_domain/island_brawl) + for(var/datum/weakref/bitrunner_ref in avatar_connection_refs) + var/mob/living/bitrunner = astype(bitrunner_ref.resolve(), /datum/component/avatar_connection)?.parent + if(!bitrunner) + continue + if((bitrunner.stat > CONSCIOUS) || !bitrunner.client) + continue + if(island_brawl_exception) + timeout *= max(5 - generated_domain.main_crate_points, 1) + continue + bitrunners_alive++ + timeout *= 5 + if(bitrunners_alive) + to_chat(antag, span_warning("[bitrunners_alive] criminals still remain here, pilfering your domain. It will be more difficult to leave until they are handled.")) + if(!do_after(antag, timeout) || QDELETED(chosen_forge) || QDELETED(antag) || QDELETED(src) || !is_ready || !is_operational) chosen_forge.setup_particles() return diff --git a/code/modules/bitrunning/virtual_domain/virtual_domain.dm b/code/modules/bitrunning/virtual_domain/virtual_domain.dm index 8fc3173df95..139e46d5508 100644 --- a/code/modules/bitrunning/virtual_domain/virtual_domain.dm +++ b/code/modules/bitrunning/virtual_domain/virtual_domain.dm @@ -52,6 +52,12 @@ var/secondary_loot_generated /// Has this domain been beaten with high enough score to spawn a tech disk? var/disk_reward_spawned = FALSE + /// The amount of points towards the spawning of the main crate, on maps using points. + var/main_crate_points = 0 + /// The amount of points required to spawn the main crate, on maps using points. + var/main_crate_point_goal = 10 + /// The location the crate will spawn when enough points are accumulated, on maps using points. + var/main_crate_loc /** * Modularity @@ -99,7 +105,19 @@ /// Sends a point to any loot signals on the map /datum/lazy_template/virtual_domain/proc/add_points(points_to_add = 1) - SEND_SIGNAL(src, COMSIG_BITRUNNER_GOAL_POINT, points_to_add) + main_crate_points += points_to_add + if(main_crate_points >= main_crate_point_goal) + reveal() + +/datum/lazy_template/virtual_domain/proc/reveal() + if(!main_crate_loc) + return + var/turf/spawn_loc = get_turf(main_crate_loc) + playsound(spawn_loc, 'sound/effects/magic/blink.ogg', 50, TRUE) + var/obj/structure/closet/crate/secure/bitrunning/encrypted/crate = new() + crate.forceMove(spawn_loc) // Triggers any on-move effects on that turf + do_sparks(5, FALSE, spawn_loc, spark_type = /datum/effect_system/basic/spark_spread/quantum) + main_crate_loc = null /// Loads the ghost candidates. /datum/lazy_template/virtual_domain/proc/load_advanced_npcs(list/mob/lucky_ghosts) diff --git a/code/modules/capture_the_flag/ctf_game.dm b/code/modules/capture_the_flag/ctf_game.dm index b10513eca27..2b164277aba 100644 --- a/code/modules/capture_the_flag/ctf_game.dm +++ b/code/modules/capture_the_flag/ctf_game.dm @@ -461,11 +461,10 @@ /obj/structure/table/reinforced/ctf resistance_flags = INDESTRUCTIBLE -/obj/structure/table/reinforced/ctf/wrench_act_secondary(mob/living/user, obj/item/tool) - return NONE - -/obj/structure/table/reinforced/ctf/screwdriver_act_secondary(mob/living/user, obj/item/tool) - return NONE +/obj/structure/table/reinforced/ctf/Initialize(mapload) + . = ..() + AddElement(/datum/element/tool_blocker, TOOL_SCREWDRIVER, TOOL_ACT_SECONDARY) + AddElement(/datum/element/tool_blocker, TOOL_WRENCH, TOOL_ACT_SECONDARY) #define CTF_LOADING_UNLOADED 0 #define CTF_LOADING_LOADING 1 diff --git a/code/modules/cargo/bounties/security.dm b/code/modules/cargo/bounties/security.dm index f94c1973cbb..aad196c3b5e 100644 --- a/code/modules/cargo/bounties/security.dm +++ b/code/modules/cargo/bounties/security.dm @@ -68,6 +68,7 @@ start_tracking(id_card) /datum/bounty/patrol/proc/start_tracking(obj/item/card/id/id_card) + contribution |= id_card.registered_account tracker = AddComponent(/datum/component/connect_containers, id_card, list(COMSIG_MOVABLE_MOVED = PROC_REF(on_card_moved))) RegisterSignal(id_card, COMSIG_MOVABLE_MOVED, PROC_REF(on_card_moved)) diff --git a/code/modules/cargo/expressconsole.dm b/code/modules/cargo/expressconsole.dm index 9dc6152b037..01bc5c23a97 100644 --- a/code/modules/cargo/expressconsole.dm +++ b/code/modules/cargo/expressconsole.dm @@ -14,7 +14,6 @@ interface_type = "CargoExpress" var/message - var/list/meme_pack_data /// The linked supplypod beacon var/obj/item/supplypod_beacon/beacon /// Where we droppin boys @@ -31,16 +30,11 @@ /obj/machinery/computer/cargo/express/Initialize(mapload) . = ..() - packin_up() landingzone = GLOB.areas_by_type[landingzone] if (isnull(landingzone)) WARNING("[src] couldnt find a Quartermaster/Storage (aka cargobay) area on the station, and as such it has set the supplypod landingzone to the area it resides in.") landingzone = get_area(src) -/obj/machinery/computer/cargo/express/on_construction(mob/user) - . = ..() - packin_up() - /obj/machinery/computer/cargo/express/Destroy() if(beacon) beacon.unlink_console() @@ -87,23 +81,8 @@ var/obj/item/circuitboard/computer/cargo/board = circuit board.obj_flags |= EMAGGED board.contraband = TRUE - packin_up() return TRUE -/obj/machinery/computer/cargo/express/proc/packin_up(forced = FALSE) // oh shit, I'm sorry - meme_pack_data = list() // sorry for what? - if(!forced && !SSshuttle.initialized) // our quartermaster taught us not to be ashamed of our supply packs - SSshuttle.express_consoles += src // specially since they're such a good price and all - return // yeah, I see that, your quartermaster gave you good advice - // it gets cheaper when I return it - for(var/pack_id in SSshuttle.supply_packs) // mmhm - var/datum/supply_pack/pack = SSshuttle.supply_packs[pack_id] // sometimes, I return it so much, I rip the manifest - if(!meme_pack_data[pack.group]) // see, my quartermaster taught me a few things too - meme_pack_data[pack.group] = list( // like, how not to rip the manifest - "name" = pack.group, // by using someone else's crate - "packs" = get_packs_data(pack.group, express = TRUE), // will you show me? - ) // i'd be right happy to - /obj/machinery/computer/cargo/express/ui_data(mob/user) var/canBeacon = beacon && (isturf(beacon.loc) || ismob(beacon.loc))//is the beacon in a valid location? var/list/data = list() @@ -124,7 +103,6 @@ data["hasBeacon"] = beacon != null//is there a linked beacon? data["beaconName"] = beacon ? beacon.name : "No Beacon Found" data["printMsg"] = COOLDOWN_FINISHED(src, beacon_print_cooldown) ? "Print Beacon for [BEACON_COST] [MONEY_NAME]" : "Print Beacon for [BEACON_COST] [MONEY_NAME] ([COOLDOWN_TIMELEFT(src, beacon_print_cooldown)])" //buttontext for printing beacons - data["supplies"] = list() message = "Sales are near-instantaneous - please choose carefully." if(SSshuttle.supply_blocked) message = blockade_warning @@ -135,10 +113,6 @@ if(obj_flags & EMAGGED) message = "(&!#@ERROR: R0UTING_#PRO7O&OL MALF(*CT#ON. $UG%ESTE@ ACT#0N: !^/PULS3-%E)ET CIR*)ITB%ARD." data["message"] = message - if(!meme_pack_data) - packin_up() - stack_trace("There was no pack data for [src]") - data["supplies"] = meme_pack_data return data /obj/machinery/computer/cargo/express/get_discount() diff --git a/code/modules/cargo/goodies.dm b/code/modules/cargo/goodies.dm index 4891a552c04..0ebfd10e15e 100644 --- a/code/modules/cargo/goodies.dm +++ b/code/modules/cargo/goodies.dm @@ -203,6 +203,12 @@ cost = PAYCHECK_CREW * 3 contains = list(/obj/item/storage/toolbox/mechanical) +/datum/supply_pack/goody/autolatheboard + name = "Autolathe Circuit Board" + desc = "A single autolathe circuit board for your construction needs." + cost = PAYCHECK_CREW * 2 + contains = list(/obj/item/circuitboard/machine/autolathe) + /datum/supply_pack/goody/valentine name = "Valentine Card" desc = "Make an impression on that special someone! Comes with one valentine card and a free candy heart!" @@ -435,12 +441,17 @@ cost = PAYCHECK_CREW * 5 contains = list(/obj/item/key/golfcart) - /datum/supply_pack/goody/handheld_crew_monitor name = "Handheld Crew Monitor" - desc = "A crate containing a handheld crew monitor" + desc = "A crate containing a handheld crew monitor." cost = /obj/item/sensor_device::custom_premium_price * 1.25 // 1.25X base vending machine value contains = list( /obj/item/sensor_device, ) crate_name = "handheld crew monitor crate" + +/datum/supply_pack/goody/camera + name = "Broadcast Camera" + desc = "A single broadcast camera which broadcasts to the station's entertainment monitors, for all your theatrical needs." + cost = PAYCHECK_COMMAND * 8 + contains = list(/obj/item/broadcast_camera/cargo) diff --git a/code/modules/cargo/markets/market_items/clothing.dm b/code/modules/cargo/markets/market_items/clothing.dm index bfa34867068..52b6a18cdc4 100644 --- a/code/modules/cargo/markets/market_items/clothing.dm +++ b/code/modules/cargo/markets/market_items/clothing.dm @@ -112,3 +112,14 @@ price_max = CARGO_CRATE_VALUE * 4.5 stock_max = 3 availability_prob = 60 + +/datum/market_item/clothing/totally_normal_pet_collar + name = "Strange Pet Collar" + desc = "We found these in the back of a militarized shuttle destined for New Osaka. Who the hell transports pet collars \ + in an armored vessel? Whatever, if Cybersun Industries didn't want you to have them, that must mean they're REAL special! \ + Which is why we're charging you extra for them." + item = /obj/item/clothing/neck/petcollar/wearable/cyber + price_min = CARGO_CRATE_VALUE * 5 + price_max = CARGO_CRATE_VALUE * 10 + stock_max = 5 + availability_prob = 20 diff --git a/code/modules/cargo/markets/market_items/weapons.dm b/code/modules/cargo/markets/market_items/weapons.dm index c9326807cc5..ce2c16735fe 100644 --- a/code/modules/cargo/markets/market_items/weapons.dm +++ b/code/modules/cargo/markets/market_items/weapons.dm @@ -153,3 +153,13 @@ price_max = CARGO_CRATE_VALUE * 5 stock_max = 2 availability_prob = 80 + +/datum/market_item/weapon/earthcracker + name = "E-1 Earthcracker" + desc = "Surplus mining equipment from one of the many, nameless asteroid mining companies bought out by Nanotrasen in this sector.\ + While they were decent enough at mining asteroids, these things really shine at leaving large cracks on station-class hulls when deployed these days." + item = /obj/item/earthcracker/small + price_min = CARGO_CRATE_VALUE + price_max = CARGO_CRATE_VALUE * 3 + stock_max = 1 + availability_prob = 30 diff --git a/code/modules/cargo/materials_market.dm b/code/modules/cargo/materials_market.dm index 390ac1d0ee9..207a47ae0c6 100644 --- a/code/modules/cargo/materials_market.dm +++ b/code/modules/cargo/materials_market.dm @@ -130,6 +130,7 @@ var/sheet_to_buy var/requested_amount var/minimum_value_threshold = 0 + var/maximum_value_threshold = 0 var/elastic_mult = 1 for(var/datum/material/traded_mat as anything in SSstock_market.materials_prices) //convert trend into text @@ -168,6 +169,8 @@ else minimum_value_threshold = round(initial(traded_mat.value_per_unit) * SHEET_MATERIAL_AMOUNT * 0.5) + maximum_value_threshold = round(initial(traded_mat.value_per_unit) * SHEET_MATERIAL_AMOUNT * 3) + //Pulling elastic modifier into data. for(var/datum/export/material/market/export_est in GLOB.exports_list) if(export_est.material_id == traded_mat) @@ -177,7 +180,8 @@ "name" = initial(traded_mat.name), "price" = SSstock_market.materials_prices[traded_mat], "rarity" = initial(traded_mat.value_per_unit), - "threshold" = minimum_value_threshold, + "min_threshold" = minimum_value_threshold, + "max_threshold" = maximum_value_threshold, "quantity" = SSstock_market.materials_quantity[traded_mat], "trend" = trend_string, "color" = color_string, diff --git a/code/modules/cargo/order.dm b/code/modules/cargo/order.dm index 78cf184b0d4..e456dccbafb 100644 --- a/code/modules/cargo/order.dm +++ b/code/modules/cargo/order.dm @@ -110,7 +110,7 @@ var/requisition_text = "

    [station_name()] Supply Requisition

    " requisition_text += "
    " requisition_text += "Order #[id]
    " - requisition_text+= "Time of Order: [station_time_timestamp()]
    " + requisition_text += "Time of Order: [UNDERLINED_HTML_TEXT("[server_timestamp(ic_time = TRUE)]", "Shift Time: [round_timestamp()]")]
    " requisition_text += "Item: [pack.name]
    " requisition_text += "Access Restrictions: [SSid_access.get_access_desc(pack.access)]
    " requisition_text += "Requested by: [orderer]
    " @@ -119,7 +119,7 @@ requisition_text += "Rank: [orderer_rank]
    " requisition_text += "Comment: [reason]
    " - requisition_paper.add_raw_text(requisition_text) + requisition_paper.add_raw_text(requisition_text, advanced_html = TRUE) requisition_paper.update_appearance() return requisition_paper diff --git a/code/modules/cargo/orderconsole.dm b/code/modules/cargo/orderconsole.dm index c940e1c5da5..345bca00d24 100644 --- a/code/modules/cargo/orderconsole.dm +++ b/code/modules/cargo/orderconsole.dm @@ -173,9 +173,8 @@ /** * returns a list of supply packs for a certain group * * group - the group of packs to return - * * express - if this is an express console */ -/obj/machinery/computer/cargo/proc/get_packs_data(group, express = FALSE) +/obj/machinery/computer/cargo/proc/get_packs_data(group) var/list/packs = list() for(var/pack_id in SSshuttle.supply_packs) var/datum/supply_pack/pack = SSshuttle.supply_packs[pack_id] @@ -185,11 +184,9 @@ if(pack.order_flags & ORDER_INVISIBLE) continue - // Express console packs check - if(express && (pack.order_flags & (ORDER_EMAG_ONLY | ORDER_SPECIAL))) + if((pack.order_flags & ORDER_EMAG_ONLY) && !(obj_flags & EMAGGED)) continue - - if(!express && (((pack.order_flags & ORDER_EMAG_ONLY) && !(obj_flags & EMAGGED)) || ((pack.order_flags & ORDER_SPECIAL) && !(pack.order_flags & ORDER_SPECIAL_ENABLED)) || (pack.order_flags & ORDER_POD_ONLY))) + if((pack.order_flags & ORDER_SPECIAL) && !(pack.order_flags & ORDER_SPECIAL_ENABLED)) continue // BUBBER EDIT START - Interdyne-only items check @@ -200,6 +197,9 @@ if((pack.order_flags & ORDER_CONTRABAND) && !contraband) continue + if(!is_express && (pack.order_flags & ORDER_POD_ONLY)) + continue + var/obj/item/first_item = length(pack.contains) > 0 ? pack.contains[1] : null packs += list(list( "name" = pack.name, @@ -409,10 +409,10 @@ //create the paper from the SSshuttle.shopping_list if(length(SSshuttle.shopping_list)) var/obj/item/paper/requisition/requisition_paper = new(get_turf(src)) - requisition_paper.name = "requisition form - [station_time_timestamp()]" + requisition_paper.name = "requisition form - [server_timestamp(ic_time = TRUE)] (PT: [round_timestamp()])" var/requisition_text = "

    [station_name()] Supply Requisition

    " requisition_text += "
    " - requisition_text += "Time of Order: [station_time_timestamp()]

    " + requisition_text += "Time of Order: [UNDERLINED_HTML_TEXT("[server_timestamp(ic_time = TRUE)]", "Shift Time: [round_timestamp()]")]

    " for(var/datum/supply_order/order as anything in SSshuttle.shopping_list) requisition_text += "[order.pack.name]
    " requisition_text += "- Order ID: [order.id]
    " @@ -427,7 +427,7 @@ if(reason) requisition_text += "- Reason Given: [reason]
    " requisition_text += "

    " - requisition_paper.add_raw_text(requisition_text) + requisition_paper.add_raw_text(requisition_text, advanced_html = TRUE) requisition_paper.color = "#9ef5ff" requisition_paper.update_appearance() diff --git a/code/modules/cargo/packs/science.dm b/code/modules/cargo/packs/science.dm index 870645ab7d7..c556a7878ef 100644 --- a/code/modules/cargo/packs/science.dm +++ b/code/modules/cargo/packs/science.dm @@ -121,3 +121,15 @@ contains = list(/obj/item/mod/core/standard = 3) crate_name = "\improper MOD core crate" crate_type = /obj/structure/closet/crate/nakamura + +/datum/supply_pack/science/gizmo + name = "Gizmo research crate" + desc = "Three weird science gizmo thinga-majiggers? We don't know what they do." + cost = CARGO_CRATE_VALUE * 5 + access = ACCESS_SCIENCE + access_view = ACCESS_SCIENCE + contains = list( + /obj/machinery/gizmo = 1, + /obj/effect/spawner/random/gizmo = 2, + ) + crate_name = "\improper Gizmo research crate" diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index 989ff3efa1e..a49169b9084 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -256,5 +256,7 @@ /// The DPI scale of the client. 1 is equivalent to 100% window scaling, 2 will be 200% window scaling var/window_scaling + var/datum/tgui_window/stat_panel + /// OOC colour of the clients messages. var/ooc_colour = null diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 978bff094bc..26651b74fce 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -571,8 +571,6 @@ GLOBAL_LIST_INIT(unrecommended_builds, list( to_chat(src, span_info("You have unread updates in the changelog.")) if(CONFIG_GET(flag/aggressive_changelog)) changelog() - else - winset(src, "infobuttons.changelog", "font-style=bold") if(ckey in GLOB.clientmessages) for(var/message in GLOB.clientmessages[ckey]) @@ -592,19 +590,16 @@ GLOBAL_LIST_INIT(unrecommended_builds, list( if(!tooltips) tooltips = new /datum/tooltip(src) - if (!interviewee) - initialize_menus() - loot_panel = new(src) view_size = new(src) - set_fullscreen(logging_in = TRUE) view_size.resetFormat() view_size.setZoomMode() view_size.apply() Master.UpdateTickRate() SEND_GLOBAL_SIGNAL(COMSIG_GLOB_CLIENT_CONNECT, src) fully_created = TRUE + set_fullscreen() ////////////// //DISCONNECT// @@ -1159,29 +1154,6 @@ GLOBAL_LIST_INIT(unrecommended_builds, list( return to_chat(src, span_userdanger("Statpanel failed to load, click here to reload the panel ")) -/** - * Initializes dropdown menus on client - */ -/client/proc/initialize_menus() - var/list/topmenus = GLOB.menulist[/datum/verbs/menu] - for (var/thing in topmenus) - var/datum/verbs/menu/topmenu = thing - var/topmenuname = "[topmenu]" - if (topmenuname == "[topmenu.type]") - var/list/tree = splittext(topmenuname, "/") - topmenuname = tree[tree.len] - winset(src, "[topmenu.type]", "parent=menu;name=[url_encode(topmenuname)]") - var/list/entries = topmenu.Generate_list(src) - for (var/child in entries) - winset(src, "[child]", "[entries[child]]") - if (!ispath(child, /datum/verbs/menu)) - var/procpath/verbpath = child - if (verbpath.name[1] != "@") - new child(src) - - // Place Help back at the end. - winset(src, "help-menu", "index=1000") - /client/proc/open_filter_editor(atom/in_atom) if(holder) holder.filterrific = new /datum/filter_editor(in_atom) @@ -1195,13 +1167,13 @@ GLOBAL_LIST_INIT(unrecommended_builds, list( /client/proc/set_right_click_menu_mode(shift_only) if(shift_only) - winset(src, "mapwindow.map", "right-click=true") - winset(src, "ShiftUp", "is-disabled=false") - winset(src, "Shift", "is-disabled=false") + winset(src, SKIN_MAPWINDOW_MAP, "right-click=true") + winset(src, SKIN_DEFAULT_SHIFTUP, "is-disabled=false") + winset(src, SKIN_DEFAULT_SHIFT, "is-disabled=false") else - winset(src, "mapwindow.map", "right-click=false") - winset(src, "default.Shift", "is-disabled=true") - winset(src, "default.ShiftUp", "is-disabled=true") + winset(src, SKIN_MAPWINDOW_MAP, "right-click=false") + winset(src, SKIN_DEFAULT_SHIFT, "is-disabled=true") + winset(src, SKIN_DEFAULT_SHIFTUP, "is-disabled=true") /client/proc/update_ambience_pref(value) if(value) @@ -1270,15 +1242,8 @@ GLOBAL_LIST_INIT(unrecommended_builds, list( prefs.write_preference(GLOB.preference_entries[/datum/preference/toggle/fullscreen_mode], !is_on) set_fullscreen() -/client/proc/set_fullscreen(logging_in = FALSE) - var/fullscreen = prefs?.read_preference(/datum/preference/toggle/fullscreen_mode) - //no need to set every login to not fullscreen, they already aren't. - //we also dont need to call attempt_auto_fit_viewport, Login does that for us. - if(logging_in) - if(fullscreen) - winset(src, "mainwindow", "menu=;is-fullscreen=[fullscreen ? "true" : "false"]") - return - winset(src, "mainwindow", "menu=;is-fullscreen=[fullscreen ? "true" : "false"]") +/client/proc/set_fullscreen() + winset(src, SKIN_MAINWINDOW, "is-fullscreen=[prefs?.read_preference(/datum/preference/toggle/fullscreen_mode) ? "true" : "false"]") attempt_auto_fit_viewport() /// Clears the client's screen, aside from ones that opt out diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 69587cda807..fec578eed1d 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -576,7 +576,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) return TRUE /datum/preferences/proc/GetQuirkBalance() - var/bal = CONFIG_GET(number/default_quirk_points) + var/bal = SSquirks.default_quirk_points for(var/V in all_quirks) var/datum/quirk/T = SSquirks.quirks[V] bal -= initial(T.value) @@ -606,7 +606,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(LAZYLEN(quirks_removed)) LAZYADD(feedback, "The following quirks are incompatible with your species:") LAZYADD(feedback, quirks_removed) - if(!CONFIG_GET(flag/disable_quirk_points) && GetQuirkBalance() < 0) + if(SSquirks.points_enabled && GetQuirkBalance() < 0) LAZYADD(feedback, "Your quirks have been reset.") all_quirks = list() if(LAZYLEN(feedback)) diff --git a/code/modules/client/preferences/body_type.dm b/code/modules/client/preferences/body_type.dm index 18f4d1c2094..33c8f736fd8 100644 --- a/code/modules/client/preferences/body_type.dm +++ b/code/modules/client/preferences/body_type.dm @@ -10,11 +10,6 @@ /datum/preference/choiced/body_type/init_possible_values() return list(USE_GENDER, MALE, FEMALE) -/datum/preference/choiced/body_type/is_valid(value, datum/preferences/preferences) - . = ..() - if(. && value == USE_GENDER) - return gender_has_physique(preferences.read_preference(/datum/preference/choiced/gender)) - /datum/preference/choiced/body_type/create_informed_default_value(datum/preferences/preferences) return gender_has_physique(preferences.read_preference(/datum/preference/choiced/gender)) ? USE_GENDER : FEMALE diff --git a/code/modules/client/preferences/gender.dm b/code/modules/client/preferences/gender.dm index c5bfd19d317..bf1107843c2 100644 --- a/code/modules/client/preferences/gender.dm +++ b/code/modules/client/preferences/gender.dm @@ -18,12 +18,3 @@ // The only reason I'm limiting this to male or female // is that hairstyle randomization handles enbies poorly return pick(MALE, FEMALE) - -/datum/preference/choiced/gender/post_write(value, datum/preferences/preferences) - ..() - if (gender_has_physique(value)) - return - - var/current_physique = preferences.read_preference(/datum/preference/choiced/body_type) - if(current_physique != MALE && current_physique != FEMALE) - preferences.update_preference(GLOB.preference_entries[/datum/preference/choiced/body_type], FEMALE) diff --git a/code/modules/client/preferences/middleware/quirks.dm b/code/modules/client/preferences/middleware/quirks.dm index 5476c56effe..834a462cfbe 100644 --- a/code/modules/client/preferences/middleware/quirks.dm +++ b/code/modules/client/preferences/middleware/quirks.dm @@ -19,7 +19,7 @@ if(!LAZYLEN(incompatible_quirks)) return var/list/message = list("The following quirks are incompatible with your selected species and will be removed: [incompatible_quirks.Join(", ")].") - if(CONFIG_GET(flag/disable_quirk_points)) + if(!SSquirks.points_enabled) message += "Would you like to continue?" else message += "If you do not have enough points to cover the removed quirks, your quirks will be reset. Would you like to continue?" @@ -48,7 +48,7 @@ var/list/data = list() data["selected_quirks"] = get_selected_quirks() - data["default_quirk_balance"] = CONFIG_GET(number/default_quirk_points) + data["default_quirk_balance"] = SSquirks.default_quirk_points data["species_disallowed_quirks"] = get_species_compatibility() return data @@ -68,7 +68,7 @@ var/list/quirks = SSquirks.get_quirks() - var/max_positive_quirks = CONFIG_GET(number/max_positive_quirks) + var/max_positive_quirks = SSquirks.max_positive_quirks var/positive_quirks_disabled = max_positive_quirks == 0 for (var/quirk_name in quirks) var/datum/quirk/quirk = quirks[quirk_name] @@ -91,7 +91,7 @@ "max_positive_quirks" = max_positive_quirks, "quirk_info" = quirk_info, "quirk_blacklist" = GLOB.quirk_string_blacklist, - "points_enabled" = !CONFIG_GET(flag/disable_quirk_points), + "points_enabled" = SSquirks.points_enabled, ) /datum/preference_middleware/quirks/on_new_character(mob/user) diff --git a/code/modules/client/preferences/names.dm b/code/modules/client/preferences/names.dm index f7c77f10fd2..e253bd5b660 100644 --- a/code/modules/client/preferences/names.dm +++ b/code/modules/client/preferences/names.dm @@ -174,7 +174,7 @@ return FALSE // If one of the roles is ticked in the antag prefs menu, this option will show. - var/static/list/ops_roles = list(ROLE_OPERATIVE, ROLE_LONE_OPERATIVE, ROLE_OPERATIVE_MIDROUND, ROLE_CLOWN_OPERATIVE) + var/static/list/ops_roles = list(ROLE_OPERATIVE, ROLE_LONE_OPERATIVE, ROLE_OPERATIVE_MIDROUND, ROLE_CLOWN_OPERATIVE, ROLE_CLOWN_OPERATIVE_MIDROUND) if(length(ops_roles & preferences.be_special)) return TRUE diff --git a/code/modules/client/preferences/operative_species.dm b/code/modules/client/preferences/operative_species.dm index 5bee923c415..e67ffff7568 100644 --- a/code/modules/client/preferences/operative_species.dm +++ b/code/modules/client/preferences/operative_species.dm @@ -14,7 +14,7 @@ return FALSE // If one of the roles is ticked in the antag prefs menu, this option will show. - var/static/list/ops_roles = list(ROLE_OPERATIVE, ROLE_LONE_OPERATIVE, ROLE_OPERATIVE_MIDROUND, ROLE_CLOWN_OPERATIVE) + var/static/list/ops_roles = list(ROLE_OPERATIVE, ROLE_LONE_OPERATIVE, ROLE_OPERATIVE_MIDROUND, ROLE_CLOWN_OPERATIVE, ROLE_CLOWN_OPERATIVE_MIDROUND) if(length(ops_roles & preferences.be_special)) return TRUE diff --git a/code/modules/client/preferences/statpanel.dm b/code/modules/client/preferences/statpanel.dm index 4c9e3c51b26..3924e0743fe 100644 --- a/code/modules/client/preferences/statpanel.dm +++ b/code/modules/client/preferences/statpanel.dm @@ -9,3 +9,8 @@ return FALSE return is_admin(preferences.parent) + +/datum/preference/toggle/statpanel + savefile_key = "statpanel_open" + savefile_identifier = PREFERENCE_PLAYER + default_value = TRUE diff --git a/code/modules/client/preferences/status_bar.dm b/code/modules/client/preferences/status_bar.dm index 1f1724ff49e..853280cd7fc 100644 --- a/code/modules/client/preferences/status_bar.dm +++ b/code/modules/client/preferences/status_bar.dm @@ -7,4 +7,4 @@ /datum/preference/toggle/status_bar/apply_to_client(client/client, value) if(isnull(client) || istype(client, /datum/client_interface)) //no winset on mock clients. return - winset(client, "mapwindow.status_bar", "is-visible=[value]") + winset(client, SKIN_MAPWINDOW_STATUS_BAR, "is-visible=[value]") diff --git a/code/modules/client/preferences/time.dm b/code/modules/client/preferences/time.dm new file mode 100644 index 00000000000..698618571ec --- /dev/null +++ b/code/modules/client/preferences/time.dm @@ -0,0 +1,5 @@ +/datum/preference/toggle/twelve_hour + category = PREFERENCE_CATEGORY_GAME_PREFERENCES + savefile_key = "twelve_hour" + savefile_identifier = PREFERENCE_PLAYER + default_value = FALSE diff --git a/code/modules/client/preferences_menu.dm b/code/modules/client/preferences_menu.dm index 887816a0a0a..30c658d4541 100644 --- a/code/modules/client/preferences_menu.dm +++ b/code/modules/client/preferences_menu.dm @@ -1,26 +1,22 @@ -/datum/verbs/menu/Preferences/verb/open_character_preferences() +/client/verb/open_character_preferences() set category = "OOC" set name = "Open Character Preferences" set desc = "Open Character Preferences" - var/datum/preferences/preferences = usr?.client?.prefs - if (!preferences) + if(!prefs) return + prefs.current_window = PREFERENCE_TAB_CHARACTER_PREFERENCES + prefs.update_static_data(usr) + prefs.ui_interact(usr) - preferences.current_window = PREFERENCE_TAB_CHARACTER_PREFERENCES - preferences.update_static_data(usr) - preferences.ui_interact(usr) - -/datum/verbs/menu/Preferences/verb/open_game_preferences() +/client/verb/open_game_preferences() set category = "OOC" set name = "Open Game Preferences" set desc = "Open Game Preferences" - var/datum/preferences/preferences = usr?.client?.prefs - if (!preferences) + if(!prefs) return - - preferences.current_window = PREFERENCE_TAB_GAME_PREFERENCES - preferences.update_static_data(usr) - preferences.ui_interact(usr) + prefs.current_window = PREFERENCE_TAB_GAME_PREFERENCES + prefs.update_static_data(usr) + prefs.ui_interact(usr) diff --git a/code/modules/client/verbs/ooc.dm b/code/modules/client/verbs/ooc.dm index cd2e598c7cc..e250d29268c 100644 --- a/code/modules/client/verbs/ooc.dm +++ b/code/modules/client/verbs/ooc.dm @@ -3,8 +3,7 @@ GLOBAL_VAR_INIT(normal_ooc_colour, "#002eb8") ///talking in OOC uses this /client/verb/ooc(msg as text) - set name = "OOC" //Gave this shit a shorter name so you only have to time out "ooc" rather than "ooc message" to use it --NeoFite - set category = "OOC" + set name = VERB_OOC if(GLOB.say_disabled) //This is here to try to identify lag problems to_chat(usr, span_danger("Speech is currently admin-disabled.")) @@ -138,7 +137,6 @@ GLOBAL_VAR_INIT(normal_ooc_colour, "#002eb8") else GLOB.dooc_allowed = !GLOB.dooc_allowed - /client/proc/set_ooc() set name = "Set Player OOC Color" set desc = "Modifies player OOC Color" @@ -357,16 +355,16 @@ ADMIN_VERB(reset_ooc_color, R_FUN, "Reset Player OOC Color", "Returns player OOC var/aspect_ratio = view_size[1] / view_size[2] // Calculate desired pixel width using window size and aspect ratio - var/list/sizes = params2list(winget(src, "mainwindow.split;mapwindow", "size")) + var/list/sizes = params2list(winget(src, "[SKIN_MAINWINDOW_SPLIT];[SKIN_MAPWINDOW]", "size")) // Client closed the window? Some other error? This is unexpected behaviour, let's // CRASH with some info. - if(!sizes["mapwindow.size"]) + if(!sizes["[SKIN_MAPWINDOW].size"]) CRASH("sizes does not contain mapwindow.size key. This means a winget failed to return what we wanted. --- sizes var: [sizes] --- sizes length: [length(sizes)]") - var/list/map_size = splittext(sizes["mapwindow.size"], "x") + var/list/map_size = splittext(sizes["[SKIN_MAPWINDOW].size"], "x") - var/split_size = splittext(sizes["mainwindow.split.size"], "x") + var/split_size = splittext(sizes["[SKIN_MAINWINDOW_SPLIT].size"], "x") var/split_width = text2num(split_size[1]) // Window is minimized, we can't get proper data so return to avoid division by 0 @@ -400,12 +398,12 @@ ADMIN_VERB(reset_ooc_color, R_FUN, "Reset Player OOC Color", "Returns player OOC // Calculate and apply a best estimate // +4 pixels are for the width of the splitter's handle var/pct = 100 * (desired_width + 4) / split_width - winset(src, "mainwindow.split", "splitter=[pct]") + winset(src, SKIN_MAINWINDOW_SPLIT, "splitter=[pct]") // Apply an ever-lowering offset until we finish or fail var/delta for(var/safety in 1 to 10) - var/after_size = winget(src, "mapwindow", "size") + var/after_size = winget(src, SKIN_MAPWINDOW, "size") map_size = splittext(after_size, "x") var/got_width = text2num(map_size[1]) @@ -420,7 +418,7 @@ ADMIN_VERB(reset_ooc_color, R_FUN, "Reset Player OOC Color", "Returns player OOC delta = -delta/2 pct += delta - winset(src, "mainwindow.split", "splitter=[pct]") + winset(src, SKIN_MAINWINDOW_SPLIT, "splitter=[pct]") /// Attempt to automatically fit the viewport, assuming the user wants it /client/proc/attempt_auto_fit_viewport() diff --git a/code/modules/client/verbs/ping.dm b/code/modules/client/verbs/ping.dm deleted file mode 100644 index 03603cea895..00000000000 --- a/code/modules/client/verbs/ping.dm +++ /dev/null @@ -1,22 +0,0 @@ -/client/verb/update_ping(time as num) - set instant = TRUE - set name = ".update_ping" - var/ping = pingfromtime(time) - lastping = ping - if (!avgping) - avgping = ping - else - avgping = MC_AVERAGE_SLOW(avgping, ping) - -/client/proc/pingfromtime(time) - return ((world.time+world.tick_lag*TICK_USAGE_REAL/100)-time)*100 - -/client/verb/display_ping(time as num) - set instant = TRUE - set name = ".display_ping" - to_chat(src, span_notice("Round trip ping took [round(pingfromtime(time),1)]ms")) - -/client/verb/ping() - set name = "Ping" - set category = "OOC" - winset(src, null, "command=.display_ping+[world.time+world.tick_lag*TICK_USAGE_REAL/100]") diff --git a/code/modules/client/verbs/stat_panel.dm b/code/modules/client/verbs/stat_panel.dm new file mode 100644 index 00000000000..b350c4ee887 --- /dev/null +++ b/code/modules/client/verbs/stat_panel.dm @@ -0,0 +1,21 @@ +/client/verb/toggle_stat_panel() + set name = "Toggle Stat Panel" + set hidden = TRUE + + //Flip it + prefs.write_preference(GLOB.preference_entries[/datum/preference/toggle/statpanel], !prefs.read_preference(/datum/preference/toggle/statpanel)) + set_stat_panel() + +///Sets the stat panel's visibility to the player, depending on whether they need it/have it enabled or not. +/client/proc/set_stat_panel() + if(prefs.read_preference(/datum/preference/toggle/statpanel) || needs_stat_panel()) + winset(src, SKIN_INFOWINDOW_CHILD, "left=statwindow") + else + winset(src, SKIN_INFOWINDOW_CHILD, "left=null") + +///Returns TRUE if the player has something that necessitates the stat panel. +/client/proc/needs_stat_panel() + if(holder || interviewee) + return TRUE + . = mob.get_status_tab_items() + return length(.) >= 2 diff --git a/code/modules/client/verbs/typing.dm b/code/modules/client/verbs/typing.dm index 035a35d2e55..52cd57a828c 100644 --- a/code/modules/client/verbs/typing.dm +++ b/code/modules/client/verbs/typing.dm @@ -9,7 +9,7 @@ /client/proc/handle_commandbar_typing(href_list) if (!typing_indicators) //check pref return - if (length(href_list["verb"]) < 1 || !(LOWER_TEXT(href_list["verb"]) in IC_VERBS) || text2num(href_list["argument_length"]) < 1) + if (length(href_list["verb"]) < 1 || !(LOWER_TEXT(href_list["verb"]) in IC_VERBS) || text2num(href_list["argument_length"]) < 2) if (commandbar_typing) commandbar_typing = FALSE stop_typing() diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 91df732e454..fe5c87fe898 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -572,7 +572,7 @@ BLIND // can't see anything if(!iscarbon(user)) return TRUE var/mob/living/carbon/carbon_user = user - if(up) + if(visor_flags_inv) carbon_user.refresh_obscured() if(visor_vars_to_toggle & VISOR_TINT) carbon_user.update_tint() diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm index bbff852053d..365ba867f56 100644 --- a/code/modules/clothing/glasses/_glasses.dm +++ b/code/modules/clothing/glasses/_glasses.dm @@ -491,7 +491,7 @@ inhand_icon_state = "welding-g" actions_types = list(/datum/action/item_action/toggle) flash_protect = FLASH_PROTECTION_WELDER - flags_cover = GLASSESCOVERSEYES + visor_flags_cover = GLASSESCOVERSEYES custom_materials = list(/datum/material/iron = SMALL_MATERIAL_AMOUNT*2.5) tint = 2 visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT diff --git a/code/modules/clothing/head/hat.dm b/code/modules/clothing/head/hat.dm index 3f63ef69a4f..ee2d95ef0e3 100644 --- a/code/modules/clothing/head/hat.dm +++ b/code/modules/clothing/head/hat.dm @@ -405,3 +405,9 @@ worn_icon_state = "paper" dog_fashion = /datum/dog_fashion/head custom_materials = list(/datum/material/paper = HALF_SHEET_MATERIAL_AMOUNT / 2) + +/obj/item/clothing/head/costume/paper_hat/savior + name = "ancient paper hat" + desc = "An ancient hat made of paper. \"Savior of the Universe\" is spelled out on the rim in orange marker. " + icon_state = "paper_savior" + worn_icon_state = "paper_savior" diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index f83b70bfa2f..1687bc22132 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -124,6 +124,12 @@ icon_state = "capcap" dog_fashion = null +/obj/item/clothing/head/hats/caphat/bicorne + name = "captain's bicorne" + desc = "Why be king when you can be Emperor?" + icon_state = "capbicorne" + dog_fashion = null + /obj/item/clothing/head/caphat/beret name = "captain's beret" desc = "For the Captains known for their sense of fashion." @@ -187,7 +193,6 @@ /// Cooldown for retrieving precious candy corn with rmb COOLDOWN_DECLARE(candy_cooldown) - /datum/armor/fedora_det_hat melee = 25 bullet = 5 @@ -239,6 +244,12 @@ /obj/item/clothing/head/fedora/det_hat/minor flask_path = /obj/item/reagent_containers/cup/glass/flask/det/minor +/obj/item/clothing/head/fedora/det_hat/noir + name = "detective's noir fedora" + desc = "There's only one man who can recklessly discharge a firearm into a crowded street while trying to stop a criminal, \ + and he's likely wearing this hat." + icon_state = /obj/item/clothing/head/fedora::icon_state + ///Detectives Fedora, but like Inspector Gadget. Not a subtype to not inherit candy corn stuff /obj/item/clothing/head/fedora/inspector_hat name = "inspector's fedora" diff --git a/code/modules/clothing/masks/gas_filter.dm b/code/modules/clothing/masks/gas_filter.dm index 1399a1a07d4..98abaf220dd 100644 --- a/code/modules/clothing/masks/gas_filter.dm +++ b/code/modules/clothing/masks/gas_filter.dm @@ -70,26 +70,26 @@ for(var/gas_id in breath.gases) if(gas_id in high_filtering_gases) if(breath.gases[gas_id][MOLES] > HIGH_FILTERING_MOLES) - breath.gases[gas_id][MOLES] = max(breath.gases[gas_id][MOLES] - filter_strength_high * filter_efficiency * HIGH_FILTERING_RATIO, 0) + breath.set_gas(gas_id, max(breath.gases[gas_id][MOLES] - filter_strength_high * filter_efficiency * HIGH_FILTERING_RATIO, 0)) danger_points += 1 continue - breath.gases[gas_id][MOLES] = max(breath.gases[gas_id][MOLES] - filter_strength_high * filter_efficiency * LOW_FILTERING_RATIO, 0) + breath.set_gas(gas_id, max(breath.gases[gas_id][MOLES] - filter_strength_high * filter_efficiency * LOW_FILTERING_RATIO, 0)) danger_points += 0.2 continue if(gas_id in mid_filtering_gases) if(breath.gases[gas_id][MOLES] > MID_FILTERING_MOLES) - breath.gases[gas_id][MOLES] = max(breath.gases[gas_id][MOLES] - filter_strength_mid * filter_efficiency * HIGH_FILTERING_RATIO, 0) + breath.set_gas(gas_id, max(breath.gases[gas_id][MOLES] - filter_strength_mid * filter_efficiency * HIGH_FILTERING_RATIO, 0)) danger_points += 1.25 continue - breath.gases[gas_id][MOLES] = max(breath.gases[gas_id][MOLES] - filter_strength_mid * filter_efficiency * LOW_FILTERING_RATIO, 0) + breath.set_gas(gas_id, max(breath.gases[gas_id][MOLES] - filter_strength_mid * filter_efficiency * LOW_FILTERING_RATIO, 0)) danger_points += 0.25 continue if(gas_id in low_filtering_gases) if(breath.gases[gas_id][MOLES] > LOW_FILTERING_MOLES) - breath.gases[gas_id][MOLES] = max(breath.gases[gas_id][MOLES] - filter_strength_low * filter_efficiency * HIGH_FILTERING_RATIO, 0) + breath.set_gas(gas_id, max(breath.gases[gas_id][MOLES] - filter_strength_low * filter_efficiency * HIGH_FILTERING_RATIO, 0)) danger_points += 1.5 continue - breath.gases[gas_id][MOLES] = max(breath.gases[gas_id][MOLES] - filter_strength_low * filter_efficiency * LOW_FILTERING_RATIO, 0) + breath.set_gas(gas_id, max(breath.gases[gas_id][MOLES] - filter_strength_low * filter_efficiency * LOW_FILTERING_RATIO, 0)) danger_points += 0.5 continue diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index f3b01676c0e..c9217ee5dd8 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -287,6 +287,16 @@ GLOBAL_LIST_INIT(clown_mask_options, list( /obj/item/clothing/mask/gas/syndicate/plasmaman starting_filter_type = /obj/item/gas_filter/plasmaman +/obj/item/clothing/mask/gas/syndicate/cybersun + name = "\improper Cybersun mask" + desc = "It's really more about making a statement than protecting you from environmental hazards." + icon_state = "cybersun" + flags_cover = MASKCOVERSMOUTH + flags_inv = HIDEFACE|HIDEFACIALHAIR|HIDESNOUT + visor_flags_inv = HIDEFACE|HIDEFACIALHAIR|HIDESNOUT + visor_flags_cover = MASKCOVERSMOUTH + alternate_worn_layer = BENEATH_HAIR_LAYER + /obj/item/clothing/mask/gas/clown_hat name = "clown wig and mask" desc = "A true prankster's facial attire. A clown is incomplete without his wig and mask." diff --git a/code/modules/clothing/neck/_neck.dm b/code/modules/clothing/neck/_neck.dm index 94a4bfb9673..5ed9edd61a0 100644 --- a/code/modules/clothing/neck/_neck.dm +++ b/code/modules/clothing/neck/_neck.dm @@ -520,6 +520,10 @@ return name = "[initial(name)] - [tagname]" +/obj/item/clothing/neck/petcollar/wearable/cyber + desc = "You wear the tie, or you wear this. Your choice." + icon_state = "petcollar_cyber" + ////////////// //DOPE BLING// ////////////// diff --git a/code/modules/clothing/spacesuits/_spacesuits.dm b/code/modules/clothing/spacesuits/_spacesuits.dm index 24cdeac580f..6ad579e8b93 100644 --- a/code/modules/clothing/spacesuits/_spacesuits.dm +++ b/code/modules/clothing/spacesuits/_spacesuits.dm @@ -22,16 +22,27 @@ strip_delay = 5 SECONDS equip_delay_other = 5 SECONDS flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF + visor_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | HEADINTERNALS + visor_flags_inv = HIDEMASK | HIDEEYES | HIDEFACE | HIDESNOUT + visor_flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF + visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT resistance_flags = NONE dog_fashion = null sound_vary = TRUE equip_sound = 'sound/items/handling/helmet/helmet_equip1.ogg' pickup_sound = 'sound/items/handling/helmet/helmet_pickup1.ogg' drop_sound = 'sound/items/handling/helmet/helmet_drop1.ogg' + visor_toggle_up_sound = SFX_VISOR_UP + visor_toggle_down_sound = SFX_VISOR_DOWN + actions_types = list(/datum/action/item_action/adjust_visor) + toggle_message = "You pull your helmet's visor down." + alt_toggle_message = "You pull your helmet's visor up." ///How much this helmet affects fishing difficulty var/fishing_modifier = 3 ///Icon state applied when we get spraypainted/peppersprayed. If null, does not add the dirt component var/visor_dirt = "helm_dirt" + /// Whether the helmet has a visor you can flip up + var/has_visor = FALSE /obj/item/clothing/head/helmet/space/Initialize(mapload) . = ..() @@ -44,6 +55,23 @@ /obj/item/clothing/head/helmet/space/proc/add_stabilizer(loose_hat = TRUE) AddComponent(/datum/component/hat_stabilizer, loose_hat = loose_hat) +/obj/item/clothing/head/helmet/space/attack_self(mob/living/user) + . = ..() + if(. || !has_visor) + return + + return adjust_visor(user) + +/obj/item/clothing/head/helmet/space/click_alt(mob/user) + if(!has_visor) + return NONE + + return adjust_visor(user) ? CLICK_ACTION_SUCCESS : CLICK_ACTION_BLOCKING + +/obj/item/clothing/head/helmet/space/update_icon_state() + . = ..() + icon_state = "[initial(icon_state)][up ? "-novisor" : ""]" + /datum/armor/helmet_space bio = 100 fire = 80 diff --git a/code/modules/clothing/spacesuits/pirate.dm b/code/modules/clothing/spacesuits/pirate.dm index 1a0dcca025d..de7b3680403 100644 --- a/code/modules/clothing/spacesuits/pirate.dm +++ b/code/modules/clothing/spacesuits/pirate.dm @@ -7,7 +7,8 @@ strip_delay = 4 SECONDS equip_delay_other = 2 SECONDS fishing_modifier = -2 - visor_dirt = null + visor_dirt = "space_dirt" + has_visor = TRUE /datum/armor/space_pirate melee = 30 diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm index b94861539e6..b96d5144402 100644 --- a/code/modules/clothing/spacesuits/plasmamen.dm +++ b/code/modules/clothing/spacesuits/plasmamen.dm @@ -75,7 +75,7 @@ desc = "A special containment helmet that allows plasma-based lifeforms to exist safely in an oxygenated environment. It is space-worthy, and may be worn in tandem with other EVA gear." icon = 'icons/obj/clothing/head/plasmaman_hats.dmi' worn_icon = 'icons/mob/clothing/head/plasmaman_head.dmi' - clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | SNUG_FIT | STACKABLE_HELMET_EXEMPT | PLASMAMAN_PREVENT_IGNITION | HEADINTERNALS + clothing_flags = parent_type::clothing_flags | PLASMAMAN_PREVENT_IGNITION icon_state = "plasmaman-helm" inhand_icon_state = "plasmaman-helm" strip_delay = 8 SECONDS @@ -90,10 +90,9 @@ light_on = FALSE fishing_modifier = 0 actions_types = list(/datum/action/item_action/toggle_helmet_light, /datum/action/item_action/toggle_welding_screen) - visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT - flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT - flags_cover = HEADCOVERSMOUTH|HEADCOVERSEYES|PEPPERPROOF - visor_flags_inv = HIDEEYES|HIDEFACE + visor_flags = NONE + visor_flags_inv = HIDEEYES|HIDEFACE|HIDESNOUT + visor_flags_cover = NONE visor_dirt = null var/helmet_on = FALSE var/smile = FALSE @@ -141,7 +140,6 @@ to_chat(user, span_notice("Your helmet's torch can't pass through your welding visor!")) set_light_on(FALSE) helmet_on = FALSE - playsound(src, up ? SFX_VISOR_UP : SFX_VISOR_DOWN, 50, TRUE) update_appearance() /obj/item/clothing/head/helmet/space/plasmaman/update_icon_state() diff --git a/code/modules/clothing/spacesuits/softsuit.dm b/code/modules/clothing/spacesuits/softsuit.dm index 72841de62df..d6cb7bf0c89 100644 --- a/code/modules/clothing/spacesuits/softsuit.dm +++ b/code/modules/clothing/spacesuits/softsuit.dm @@ -1,25 +1,25 @@ //NASA Voidsuit /obj/item/clothing/head/helmet/space/nasavoid - name = "NASA Void Helmet" + name = "\improper NASA void helmet" desc = "An old, NASA CentCom branch designed, dark red space suit helmet." icon_state = "void" inhand_icon_state = "void_helmet" /obj/item/clothing/suit/space/nasavoid - name = "NASA Voidsuit" + name = "\improper NASA voidsuit" icon_state = "void" inhand_icon_state = "void_suit" desc = "An old, NASA CentCom branch designed, dark red space suit." allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/multitool) /obj/item/clothing/head/helmet/space/nasavoid/old - name = "Engineering Void Helmet" + name = "\improper engineering void helmet" desc = "A CentCom engineering dark red space suit helmet. While old and dusty, it still gets the job done." icon_state = "void" visor_dirt = "void_dirt" /obj/item/clothing/suit/space/nasavoid/old - name = "Engineering Voidsuit" + name = "\improper engineering voidsuit" icon_state = "void" inhand_icon_state = "void_suit" desc = "A CentCom engineering dark red space suit. Age has degraded the suit making it difficult to move around in." @@ -28,20 +28,21 @@ //EVA suit /obj/item/clothing/suit/space/eva - name = "EVA suit" + name = "\improper EVA suit" icon_state = "space" inhand_icon_state = "s_suit" desc = "A lightweight space suit with the basic ability to protect the wearer from the vacuum of space during emergencies." armor_type = /datum/armor/space_eva /obj/item/clothing/head/helmet/space/eva - name = "EVA helmet" + name = "\improper EVA helmet" icon_state = "space" inhand_icon_state = "space_helmet" desc = "A lightweight space helmet with the basic ability to protect the wearer from the vacuum of space during emergencies." flash_protect = FLASH_PROTECTION_NONE armor_type = /datum/armor/space_eva visor_dirt = "space_dirt" + has_visor = TRUE /datum/armor/space_eva bio = 100 diff --git a/code/modules/clothing/spacesuits/specialops.dm b/code/modules/clothing/spacesuits/specialops.dm index d0f06f89a67..570db863b79 100644 --- a/code/modules/clothing/spacesuits/specialops.dm +++ b/code/modules/clothing/spacesuits/specialops.dm @@ -1,5 +1,5 @@ /obj/item/clothing/head/helmet/space/beret - name = "CentCom officer's beret" + name = "\improper CentCom officer's beret" desc = "An armored beret commonly used by special operations officers. Uses advanced force field technology to protect the head from space." icon = 'icons/map_icons/clothing/head/_head.dmi' icon_state = "/obj/item/clothing/head/helmet/space/beret" @@ -9,7 +9,8 @@ inhand_icon_state = null greyscale_colors = "#397F3F#FFCE5B" clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | SNUG_FIT - flags_inv = 0 + flags_inv = /obj/item/clothing/head/beret::flags_inv + flags_cover = /obj/item/clothing/head/beret::flags_cover armor_type = /datum/armor/space_beret strip_delay = 13 SECONDS max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT @@ -30,7 +31,7 @@ wound = 15 /obj/item/clothing/suit/space/officer - name = "CentCom officer's coat" + name = "\improper CentCom officer's coat" desc = "An armored, space-proof coat used in special operations." icon_state = "centcom_coat" icon = 'icons/obj/clothing/suits/jacket.dmi' diff --git a/code/modules/clothing/spacesuits/syndi.dm b/code/modules/clothing/spacesuits/syndi.dm index fb5bc428a5c..e145e7f3d79 100644 --- a/code/modules/clothing/spacesuits/syndi.dm +++ b/code/modules/clothing/spacesuits/syndi.dm @@ -186,7 +186,8 @@ GLOBAL_LIST_INIT(syndicate_space_suits_to_helmets,list( w_class = WEIGHT_CLASS_SMALL icon_state = "syndicate-contract-helm" inhand_icon_state = "contractor_helmet" - visor_dirt = null + visor_dirt = "void_dirt" + has_visor = TRUE /obj/item/clothing/suit/space/syndicate/contract name = "contractor space suit" diff --git a/code/modules/clothing/suits/reactive_armour.dm b/code/modules/clothing/suits/reactive_armour.dm index 2f524915820..a38ffbadce8 100644 --- a/code/modules/clothing/suits/reactive_armour.dm +++ b/code/modules/clothing/suits/reactive_armour.dm @@ -534,7 +534,7 @@ shock_turf_windup(owner.loc) /obj/item/clothing/suit/armor/reactive/weather/proc/shock_turf_windup(turf/target) - new /obj/effect/temp_visual/telegraphing/thunderbolt(target) + new /obj/effect/temp_visual/telegraphing/circle(target) addtimer(CALLBACK(src, PROC_REF(shock_turf), target), 1 SECONDS) /obj/item/clothing/suit/armor/reactive/weather/proc/shock_turf(turf/target) diff --git a/code/modules/clothing/under/jobs/command.dm b/code/modules/clothing/under/jobs/command.dm index b90e2007e6b..e0b753a4388 100644 --- a/code/modules/clothing/under/jobs/command.dm +++ b/code/modules/clothing/under/jobs/command.dm @@ -28,3 +28,8 @@ icon_state = "captain_parade" inhand_icon_state = null can_adjust = FALSE + +/obj/item/clothing/under/rank/captain/royal + name = "captain's royal uniform" + desc = "A captain's royal uniform. Fit for commanding your Officers in the midst of a nuclear incursion." + icon_state = "caproyal" diff --git a/code/modules/clothing/under/syndicate.dm b/code/modules/clothing/under/syndicate.dm index 5d2f301484a..c195718dc3a 100644 --- a/code/modules/clothing/under/syndicate.dm +++ b/code/modules/clothing/under/syndicate.dm @@ -114,6 +114,15 @@ can_adjust = FALSE supports_variations_flags = NONE +/obj/item/clothing/under/syndicate/cybersun + name = "\improper Cybersun businesswear" + desc = "This black and orange businesswear appears to be made of some kind of protective lightweight material. \ + Perfect for hostile takeovers and budget meetings." + icon_state = "cybersun_suit" + inhand_icon_state = "bl_suit" + can_adjust = FALSE + supports_variations_flags = NONE + /obj/item/clothing/under/syndicate/floortilecamo name = "floortile camouflage fatigues" desc = "The newest floortile camouflage fatigues used for hallway warfare. \ diff --git a/code/modules/deathmatch/deathmatch_loadouts.dm b/code/modules/deathmatch/deathmatch_loadouts.dm index 7b282ca6160..06f0e6f7f6d 100644 --- a/code/modules/deathmatch/deathmatch_loadouts.dm +++ b/code/modules/deathmatch/deathmatch_loadouts.dm @@ -1127,3 +1127,107 @@ shoes = /obj/item/clothing/shoes/bronze 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 + +//syndicate spaceman + +/datum/outfit/deathmatch_loadout/syndicate_spaceman + name = "DM: Syndicate Spaceman" + display_name = "Syndicate Spaceman" + desc = "A syndicate operative suited up for some space reconnaissance." + + uniform = /obj/item/clothing/under/syndicate + belt = /obj/item/storage/belt/holster + r_pocket = /obj/item/tank/internals/emergency_oxygen/double + l_pocket = /obj/item/knife/combat/survival + internals_slot = ITEM_SLOT_RPOCKET + shoes = /obj/item/clothing/shoes/combat + gloves = /obj/item/clothing/gloves/combat + back = /obj/item/tank/jetpack/harness + id = /obj/item/card/id/advanced/black/syndicate_command/crew_id + +/datum/outfit/deathmatch_loadout/syndicate_spaceman/pre_equip(mob/living/carbon/human/user, visualsOnly = FALSE) + if(user.jumpsuit_style == PREF_SKIRT) + uniform = /obj/item/clothing/under/syndicate/skirt + // pick a random syndicate spess suit + suit = pick(GLOB.syndicate_space_suits_to_helmets) + head = GLOB.syndicate_space_suits_to_helmets[suit] + +/datum/outfit/deathmatch_loadout/syndicate_spaceman/post_equip(mob/living/carbon/human/syndicate_spaceman, visuals_only) + . = ..() + var/obj/item/card/id/id_card = syndicate_spaceman.get_item_by_slot(ITEM_SLOT_ID) + var/obj/item/storage/belt/belt = syndicate_spaceman.get_item_by_slot(ITEM_SLOT_BELT) + if(belt) + new /obj/item/gun/ballistic/automatic/pistol/m1911(belt) + if(id_card) + SSid_access.apply_trim_to_card(id_card, /datum/id_trim/syndicom/crew) + id_card.registered_name = syndicate_spaceman.real_name + id_card.update_label() + id_card.update_appearance() + +//cargo spaceman + +/datum/outfit/deathmatch_loadout/cargo_spaceman + name = "DM: Spaceman" + display_name = "Spaceman" + desc = "A spaceman from spacestation 13 equipped for space." + + uniform = /obj/item/clothing/under/rank/cargo/tech + belt = /obj/item/storage/belt/utility/full + suit = /obj/item/clothing/suit/space + head = /obj/item/clothing/head/helmet/space + internals_slot = ITEM_SLOT_SUITSTORE + r_pocket = /obj/item/ammo_casing/strilka310 + suit_store = /obj/item/tank/internals/oxygen/yellow + shoes = /obj/item/clothing/shoes/sneakers + gloves = /obj/item/clothing/gloves/fingerless + back = /obj/item/gun/ballistic/rifle/boltaction + id = /obj/item/card/id/advanced + +/datum/outfit/deathmatch_loadout/cargo_spaceman/pre_equip(mob/living/carbon/human/cargo_spaceman, visualsOnly = FALSE) + if(cargo_spaceman.jumpsuit_style == PREF_SKIRT) + uniform = /obj/item/clothing/under/rank/cargo/tech/skirt + +/datum/outfit/deathmatch_loadout/cargo_spaceman/post_equip(mob/living/carbon/human/cargo_spaceman, visuals_only) + . = ..() + var/obj/item/card/id/id_card = cargo_spaceman.get_item_by_slot(ITEM_SLOT_ID) + if(id_card) + SSid_access.apply_trim_to_card(id_card, /datum/id_trim/job/cargo_technician) + id_card.registered_name = cargo_spaceman.real_name + id_card.update_label() + id_card.update_appearance() + +//spacetider + +/datum/outfit/deathmatch_loadout/spacetider + name = "DM: Assistant (Spaceworthy)" + display_name = "Assistant (Spaceworthy)" + desc = "A spacetiding assistant." + + uniform = /obj/item/clothing/under/color/grey + mask = /obj/item/clothing/mask/breath + belt = /obj/item/gun/energy/disabler/smoothbore + suit = /obj/item/clothing/suit/utility/fire/firefighter + head = /obj/item/clothing/head/utility/hardhat/red + r_pocket = /obj/item/reagent_containers/cup/glass/coffee + l_pocket = /obj/item/knife + internals_slot = ITEM_SLOT_SUITSTORE + suit_store = /obj/item/tank/internals/oxygen/red + shoes = /obj/item/clothing/shoes/sneakers + gloves = /obj/item/clothing/gloves/color/grey/protects_cold + back = /obj/item/gun/energy/laser/musket + id = /obj/item/card/id/advanced + +/datum/outfit/deathmatch_loadout/spacetider/pre_equip(mob/living/carbon/human/spacetider, visualsOnly = FALSE) + if(spacetider.jumpsuit_style == PREF_SKIRT) + uniform = /obj/item/clothing/under/color/jumpskirt/grey + +/datum/outfit/deathmatch_loadout/spacetider/post_equip(mob/living/carbon/human/spacetider, visuals_only) + . = ..() + spacetider.reagents.add_reagent(/datum/reagent/consumable/coffee, 30) //pre prime the coffee + var/obj/item/card/id/id_card = spacetider.get_item_by_slot(ITEM_SLOT_ID) + if(!id_card) + return + SSid_access.apply_trim_to_card(id_card, /datum/id_trim/job/assistant) + id_card.registered_name = spacetider.real_name + id_card.update_label() + id_card.update_appearance() diff --git a/code/modules/deathmatch/deathmatch_maps.dm b/code/modules/deathmatch/deathmatch_maps.dm index f2822cf331a..ff0372c6c63 100644 --- a/code/modules/deathmatch/deathmatch_maps.dm +++ b/code/modules/deathmatch/deathmatch_maps.dm @@ -246,3 +246,12 @@ /datum/turf_reservation/indestructible_plating turf_type = /turf/open/indestructible/plating //a little hacky but i guess it has to be done + +/datum/lazy_template/deathmatch/deep_space + name = "Deep Space" + desc = "A deep-space cargo shipping station has fallen under attack by a Syndicate boarding party." + max_players = 8 + automatic_gameend_time = 15 MINUTES //its a pretty big map + allowed_loadouts = list(/datum/outfit/deathmatch_loadout/cargo_spaceman, /datum/outfit/deathmatch_loadout/syndicate_spaceman, /datum/outfit/deathmatch_loadout/spacetider) + map_name = "deep_space" + key = "deep_space" diff --git a/code/modules/detectivework/scanner.dm b/code/modules/detectivework/scanner.dm index a7cebef7bf2..bb1285c11a5 100644 --- a/code/modules/detectivework/scanner.dm +++ b/code/modules/detectivework/scanner.dm @@ -117,7 +117,7 @@ // Start gathering log_entry.scan_target = scanned_atom.name - log_entry.scan_time = station_time_timestamp() + log_entry.scan_time = round_timestamp() var/list/atom_fibers = GET_ATOM_FIBRES(scanned_atom) if(length(atom_fibers)) diff --git a/code/modules/economy/account.dm b/code/modules/economy/account.dm index 80a97caa1d6..6b34477b4e3 100644 --- a/code/modules/economy/account.dm +++ b/code/modules/economy/account.dm @@ -25,8 +25,8 @@ var/account_id ///Amount of money that's been crabbed, if you lose enough from one series of CRAB-17's, you get a negative moodlet. var/money_crabbed - ///Is there a CRAB 17 on the station draining funds? Prevents manual fund transfer. pink levels are rising - var/being_dumped = FALSE + ///Lazylist of CRAB 17s on the station draining funds. Prevents manual fund transfer. pink levels are rising + var/list/being_dumped ///Reference to the current civilian bounty that the account is working on. var/datum/bounty/civilian_bounty ///If player is currently picking a civilian bounty to do, these options are held here to prevent soft-resetting through the UI. @@ -117,15 +117,15 @@ /** * Sets the bank_account to behave as though a CRAB-17 event is happening. */ -/datum/bank_account/proc/dumpeet() - being_dumped = TRUE +/datum/bank_account/proc/dumpeet(obj/structure/checkoutmachine/dump_machine) + LAZYADD(being_dumped, dump_machine) money_crabbed = 0 /** * Stops the dumping of the bank account. */ -/datum/bank_account/proc/stop_dump() - being_dumped = FALSE +/datum/bank_account/proc/stop_dump(obj/structure/checkoutmachine/dump_machine) + LAZYREMOVE(being_dumped, dump_machine) if(money_crabbed < NO_MY_MONEY) return for(var/obj/card as anything in bank_cards) diff --git a/code/modules/emote_panel/emote_panel.dm b/code/modules/emote_panel/emote_panel.dm index d064161c232..c39631fbe3c 100644 --- a/code/modules/emote_panel/emote_panel.dm +++ b/code/modules/emote_panel/emote_panel.dm @@ -53,12 +53,3 @@ /datum/emote_panel/ui_state(mob/user) return GLOB.always_state - -/mob/living/verb/emote_panel() - set name = "Emote Panel" - set category = "IC" - - var/static/datum/emote_panel/emote_panel - if(isnull(emote_panel)) - emote_panel = new - emote_panel.ui_interact(src) diff --git a/code/modules/error_handler/error_handler.dm b/code/modules/error_handler/error_handler.dm index 7620c7e2cb0..127bc413f09 100644 --- a/code/modules/error_handler/error_handler.dm +++ b/code/modules/error_handler/error_handler.dm @@ -110,7 +110,7 @@ GLOBAL_VAR_INIT(total_runtimes_skipped, 0) var/skipcount = abs(error_cooldown[erroruid]) - 1 error_cooldown[erroruid] = 0 if(skipcount > 0) - SEND_TEXT(world.log, "\[[time_stamp()]] Skipped [skipcount] runtimes in [E.file],[E.line].") + SEND_TEXT(world.log, "\[[server_timestamp()]] Skipped [skipcount] runtimes in [E.file],[E.line].") GLOB.error_cache.log_error(E, skip_count = skipcount) error_last_seen[erroruid] = world.time @@ -158,7 +158,7 @@ GLOBAL_VAR_INIT(total_runtimes_skipped, 0) if(GLOB.error_cache) GLOB.error_cache.log_error(E, desclines) - var/main_line = "\[[time_stamp()]] Runtime in [E.file],[E.line]: [E]" + var/main_line = "\[[server_timestamp()]] Runtime in [E.file],[E.line]: [E]" SEND_TEXT(world.log, main_line) for(var/line in desclines) SEND_TEXT(world.log, line) diff --git a/code/modules/error_handler/error_viewer.dm b/code/modules/error_handler/error_viewer.dm index c1c337aaf79..b87bc51e0b0 100644 --- a/code/modules/error_handler/error_viewer.dm +++ b/code/modules/error_handler/error_viewer.dm @@ -131,10 +131,10 @@ GLOBAL_DATUM(error_cache, /datum/error_viewer/error_cache) /datum/error_viewer/error_source/New(exception/e) if (!istype(e)) - name = "\[[time_stamp()]] Uncaught exceptions" + name = "\[[server_timestamp()]] Uncaught exceptions" return - name = "\[[time_stamp()]] Runtime in [e.file], line [e.line]: [html_encode(e.name)]" + name = "\[[server_timestamp()]] Runtime in [e.file], line [e.line]: [html_encode(e.name)]" /datum/error_viewer/error_source/show_to(user, datum/error_viewer/back_to, linear) if (!istype(back_to)) @@ -156,15 +156,15 @@ GLOBAL_DATUM(error_cache, /datum/error_viewer/error_cache) /datum/error_viewer/error_entry/New(exception/e, list/desclines, skip_count) if (!istype(e)) - name = "\[[time_stamp()]] Uncaught exception: [html_encode(e.name)]" + name = "\[[server_timestamp()]] Uncaught exception: [html_encode(e.name)]" return if(skip_count) - name = "\[[time_stamp()]] Skipped [skip_count] runtimes in [e.file],[e.line]." + name = "\[[server_timestamp()]] Skipped [skip_count] runtimes in [e.file],[e.line]." is_skip_count = TRUE return - name = "\[[time_stamp()]] Runtime in [e.file], line [e.line]: [html_encode(e.name)]" + name = "\[[server_timestamp()]] Runtime in [e.file], line [e.line]: [html_encode(e.name)]" exc = e if (istype(desclines)) for (var/line in desclines) diff --git a/code/modules/escape_menu/admin_page.dm b/code/modules/escape_menu/admin_page.dm new file mode 100644 index 00000000000..3eeacf70e93 --- /dev/null +++ b/code/modules/escape_menu/admin_page.dm @@ -0,0 +1,83 @@ +/datum/escape_menu/proc/show_admin_page() + page_holder.give_screen_object( + new /atom/movable/screen/escape_menu/lobby_button/small( + null, + /* hud_owner = */ null, + "Back", + /* tooltip_text = */ null, + /* button_screen_loc = */ "TOP:-30,LEFT:30", + CALLBACK(src, PROC_REF(open_home_page)), + /* button_overlay = */ "back", + ) + ) + + page_holder.give_screen_object( + new /atom/movable/screen/escape_menu/text/clickable/admin_help( + null, + /* hud_owner = */ null, + /* escape_menu = */ src, + /* button_text = */ "Create Admin Ticket", + /* offset = */ list(-136, 28), + /* font_size = */ 24, + /* on_click_callback = */ CALLBACK(src, PROC_REF(create_ticket)), + ) + ) + + page_holder.give_screen_object( + new /atom/movable/screen/escape_menu/text/clickable/admin_ticket_notification( + null, + /* hud_owner = */ null, + /* escape_menu = */ src, + /* button_text = */ "View Latest Ticket", + /* offset = */ list(-171, 28), + /* font_size = */ 24, + /* on_click_callback = */ CALLBACK(src, PROC_REF(view_latest_ticket)), + ) + ) + page_holder.give_screen_object( + new /atom/movable/screen/escape_menu/text/clickable( + null, + /* hud_owner = */ null, + /* escape_menu = */ src, + /* button_text = */ "Pray", + /* offset = */ list(-206, 30), + /* font_size = */ 24, + /* on_click_callback = */ CALLBACK(src, PROC_REF(pray)), + ) + ) + + if(CONFIG_GET(flag/see_own_notes)) + page_holder.give_screen_object( + new /atom/movable/screen/escape_menu/text/clickable( + null, + /* hud_owner = */ null, + /* escape_menu = */ src, + /* button_text = */ "See Notes", + /* offset = */ list(-241, 30), + /* font_size = */ 24, + /* on_click_callback = */ CALLBACK(src, PROC_REF(see_notes)), + ) + ) + +/datum/escape_menu/proc/create_ticket() + if(!(/client/verb/adminhelp in client?.verbs)) + return + client?.adminhelp() + qdel(src) + +///Opens your latest admin ticket. +/datum/escape_menu/proc/view_latest_ticket() + client?.view_latest_ticket() + +///Manually calls the user's pray() hotkey (which is where prefs is taken into account). +/datum/escape_menu/proc/pray() + var/datum/keybinding/client/communication/pray/pray_verb = GLOB.keybindings_by_name[/datum/keybinding/client/communication/pray::name] + pray_verb.down(client) + qdel(src) + +/datum/escape_menu/proc/see_notes() + if(!CONFIG_GET(flag/see_own_notes)) + to_chat(client.mob, span_notice("Seeing notes has been disabled on this server.")) + return + browse_messages(null, client.ckey, null, TRUE) + qdel(src) diff --git a/code/modules/escape_menu/details.dm b/code/modules/escape_menu/details.dm index 00267ecba5d..69a6cc8f4d8 100644 --- a/code/modules/escape_menu/details.dm +++ b/code/modules/escape_menu/details.dm @@ -1,42 +1,16 @@ -// This doesn't instantiate right away, since we rely on other GLOBs -GLOBAL_DATUM(escape_menu_details, /atom/movable/screen/escape_menu/details) - -/// Provides a singleton for the escape menu details screen. -/proc/give_escape_menu_details() - if (isnull(GLOB.escape_menu_details)) - GLOB.escape_menu_details = new - - return GLOB.escape_menu_details - /atom/movable/screen/escape_menu/details - screen_loc = "EAST:-180,NORTH:-34" + screen_loc = "EAST:-175,NORTH:-40" maptext_height = 100 maptext_width = 200 -/atom/movable/screen/escape_menu/details/Initialize(mapload, datum/hud/hud_owner) - . = ..() - - update_text() - START_PROCESSING(SSescape_menu, src) - -/atom/movable/screen/escape_menu/details/Destroy() - if (GLOB.escape_menu_details == src) - stack_trace("Something tried to delete the escape menu details screen") - return QDEL_HINT_LETMELIVE - - STOP_PROCESSING(SSescape_menu, src) - return ..() - -/atom/movable/screen/escape_menu/details/process(seconds_per_tick) - update_text() - -/atom/movable/screen/escape_menu/details/proc/update_text() +/atom/movable/screen/escape_menu/details/proc/update_text(client/client_owner) var/new_maptext = {" Round ID: [GLOB.round_id || "Unset"]
    - Round Time: [ROUND_TIME()]
    + Server Time (NST): [server_timestamp(format = "hh:mm:ss", ic_time = TRUE, twelve_hour_clock = client_owner.prefs.read_preference(/datum/preference/toggle/twelve_hour))]
    + Shift Time (PT): [(SSticker.round_start_time == 0) ? "Pre-Game" : round_timestamp()]
    Map: [SSmapping.current_map.return_map_name(webmap_included = TRUE) || "Loading..."]
    - Time Dilation: [round(SStime_track.time_dilation_current,1)]%
    + Time Dilation: [round(SStime_track.time_dilation_current, 1)]%
    "} diff --git a/code/modules/escape_menu/escape_menu.dm b/code/modules/escape_menu/escape_menu.dm index 0042a6f7332..8e86d78d647 100644 --- a/code/modules/escape_menu/escape_menu.dm +++ b/code/modules/escape_menu/escape_menu.dm @@ -16,6 +16,7 @@ GLOBAL_LIST_EMPTY(escape_menus) new /datum/escape_menu(src) #define PAGE_HOME "PAGE_HOME" +#define PAGE_ADMIN "ADMIN_PAGE" #define PAGE_LEAVE_BODY "PAGE_LEAVE_BODY" #define PAGE_QUIT_GAME "PAGE_QUIT_GAME" @@ -24,6 +25,8 @@ GLOBAL_LIST_EMPTY(escape_menus) var/client/client /// A weakref to the hud this escape menu currently applies to var/datum/weakref/our_hud_ref + /// The details at the top right that persists through all screens, showing round info. + var/atom/movable/screen/escape_menu/details/detail_screen VAR_PRIVATE ckey @@ -49,6 +52,8 @@ GLOBAL_LIST_EMPTY(escape_menus) base_holder = new(client) if(isnull(dim_screen)) dim_screen = new() + detail_screen = new() + detail_screen.update_text(client) populate_base_ui() page_holder = new(client) @@ -64,7 +69,10 @@ GLOBAL_LIST_EMPTY(escape_menus) if (!isnull(ckey)) GLOB.escape_menus[ckey] = src + START_PROCESSING(SSescape_menu, src) + /datum/escape_menu/Destroy(force) + STOP_PROCESSING(SSescape_menu, src) QDEL_NULL(base_holder) QDEL_NULL(page_holder) resource_panels = null // list contents were already qdeled in QDEL_NULL(page_holder), so we can safely null this @@ -82,6 +90,9 @@ GLOBAL_LIST_EMPTY(escape_menus) return ..() +/datum/escape_menu/process(seconds_per_tick) + detail_screen.update_text(client) + /datum/escape_menu/proc/on_client_qdel() SIGNAL_HANDLER PRIVATE_PROC(TRUE) @@ -116,6 +127,8 @@ GLOBAL_LIST_EMPTY(escape_menus) switch (menu_page) if (PAGE_HOME) show_home_page() + if (PAGE_ADMIN) + show_admin_page() if (PAGE_LEAVE_BODY) show_leave_body_page() if(PAGE_QUIT_GAME) @@ -127,7 +140,7 @@ GLOBAL_LIST_EMPTY(escape_menus) PRIVATE_PROC(TRUE) base_holder.give_protected_screen_object(dim_screen) - base_holder.give_protected_screen_object(give_escape_menu_details()) + base_holder.give_screen_object(detail_screen) /datum/escape_menu/proc/open_home_page() PRIVATE_PROC(TRUE) @@ -135,6 +148,12 @@ GLOBAL_LIST_EMPTY(escape_menus) menu_page = PAGE_HOME show_page() +/datum/escape_menu/proc/open_admin_page() + PRIVATE_PROC(TRUE) + + menu_page = PAGE_ADMIN + show_page() + /datum/escape_menu/proc/open_leave_body() PRIVATE_PROC(TRUE) @@ -152,5 +171,6 @@ GLOBAL_LIST_EMPTY(escape_menus) clear_with_screen = FALSE #undef PAGE_HOME +#undef PAGE_ADMIN #undef PAGE_LEAVE_BODY #undef PAGE_QUIT_GAME diff --git a/code/modules/escape_menu/home_page.dm b/code/modules/escape_menu/home_page.dm index 641be0d3a34..aead9cc8d51 100644 --- a/code/modules/escape_menu/home_page.dm +++ b/code/modules/escape_menu/home_page.dm @@ -37,12 +37,14 @@ ) page_holder.give_screen_object( - new /atom/movable/screen/escape_menu/text/clickable/admin_help( + new /atom/movable/screen/escape_menu/text/clickable/admin_ticket_notification( null, /* hud_owner = */ null, /* escape_menu = */ src, /* button_text = */ "Admin Help", /* offset = */ list(-241, 30), + /* font_size = */ 24, + /* on_click_callback = */ CALLBACK(src, PROC_REF(open_admin_page)), ) ) diff --git a/code/modules/escape_menu/screen_objects/admin_text.dm b/code/modules/escape_menu/screen_objects/admin_text.dm index 2a7260785b3..abedf2cba3f 100644 --- a/code/modules/escape_menu/screen_objects/admin_text.dm +++ b/code/modules/escape_menu/screen_objects/admin_text.dm @@ -1,12 +1,12 @@ -/atom/movable/screen/escape_menu/text/clickable/admin_help +///Text that gets highlighted when you have an admin ticket notification. +/atom/movable/screen/escape_menu/text/clickable/admin_ticket_notification VAR_PRIVATE current_blink = FALSE is_blinking = FALSE last_blink_time = 0 - blink_interval = 0.4 SECONDS -/atom/movable/screen/escape_menu/text/clickable/admin_help/Initialize( +/atom/movable/screen/escape_menu/text/clickable/admin_ticket_notification/Initialize( mapload, datum/hud/hud_owner, datum/escape_menu/escape_menu, @@ -18,7 +18,6 @@ . = ..() RegisterSignal(escape_menu.client, COMSIG_ADMIN_HELP_RECEIVED, PROC_REF(on_admin_help_received)) - RegisterSignals(escape_menu.client, list(COMSIG_CLIENT_VERB_ADDED, COMSIG_CLIENT_VERB_REMOVED), PROC_REF(on_client_verb_changed)) var/datum/admin_help/current_ticket = escape_menu.client?.current_ticket if (!isnull(current_ticket)) @@ -26,48 +25,12 @@ if (!current_ticket?.player_replied) begin_processing() -/atom/movable/screen/escape_menu/text/clickable/admin_help/Click(location, control, params) - if (!enabled()) - return - - QDEL_IN(escape_menu, 0) - - var/client/client = escape_menu.client - - if (has_open_adminhelp()) - client?.view_latest_ticket() - else - client?.adminhelp() - -/atom/movable/screen/escape_menu/text/clickable/admin_help/proc/has_open_adminhelp() - var/client/client = escape_menu.client - - var/datum/admin_help/current_ticket = client?.current_ticket - - // This is null with a closed ticket. - // This is okay since the View Latest Ticket panel already tells you if your ticket is closed, intentionally. - if (isnull(current_ticket)) - return FALSE - - // If we sent a ticket, but nobody has responded, send another one instead. - // Not worth opening a menu when there's nothing to read, you're only going to want to send. - if (length(current_ticket.admins_involved - client?.ckey) == 0) - return FALSE - - return TRUE - -/atom/movable/screen/escape_menu/text/clickable/admin_help/proc/on_admin_help_received() +/atom/movable/screen/escape_menu/text/clickable/admin_ticket_notification/proc/on_admin_help_received() SIGNAL_HANDLER begin_processing() -/atom/movable/screen/escape_menu/text/clickable/admin_help/proc/on_client_verb_changed(client/source, list/verbs_changed) - SIGNAL_HANDLER - - if (/client/verb/adminhelp in verbs_changed) - update_text() - -/atom/movable/screen/escape_menu/text/clickable/admin_help/proc/begin_processing() +/atom/movable/screen/escape_menu/text/clickable/admin_ticket_notification/proc/begin_processing() if (is_blinking) return @@ -76,7 +39,7 @@ START_PROCESSING(SSescape_menu, src) update_text() -/atom/movable/screen/escape_menu/text/clickable/admin_help/proc/end_processing() +/atom/movable/screen/escape_menu/text/clickable/admin_ticket_notification/proc/end_processing() if (!is_blinking) return @@ -85,26 +48,17 @@ STOP_PROCESSING(SSescape_menu, src) update_text() -/atom/movable/screen/escape_menu/text/clickable/admin_help/proc/connect_ticket(datum/admin_help/admin_help) +/atom/movable/screen/escape_menu/text/clickable/admin_ticket_notification/proc/connect_ticket(datum/admin_help/admin_help) ASSERT(istype(admin_help)) RegisterSignal(admin_help, COMSIG_ADMIN_HELP_REPLIED, PROC_REF(on_admin_help_replied)) -/atom/movable/screen/escape_menu/text/clickable/admin_help/proc/on_admin_help_replied() +/atom/movable/screen/escape_menu/text/clickable/admin_ticket_notification/proc/on_admin_help_replied() SIGNAL_HANDLER end_processing() -/atom/movable/screen/escape_menu/text/clickable/admin_help/enabled() - if (!..()) - return FALSE - - if (!has_open_adminhelp()) - return /client/verb/adminhelp in escape_menu.client?.verbs - - return TRUE - -/atom/movable/screen/escape_menu/text/clickable/admin_help/process(seconds_per_tick) +/atom/movable/screen/escape_menu/text/clickable/admin_ticket_notification/process(seconds_per_tick) if (world.time - last_blink_time < blink_interval) return @@ -112,19 +66,42 @@ last_blink_time = world.time update_text() -/atom/movable/screen/escape_menu/text/clickable/admin_help/text_color() +/atom/movable/screen/escape_menu/text/clickable/admin_ticket_notification/text_color() if (!enabled()) return ..() return current_blink ? "red" : ..() -/atom/movable/screen/escape_menu/text/clickable/admin_help/MouseEntered(location, control, params) +/atom/movable/screen/escape_menu/text/clickable/admin_ticket_notification/MouseEntered(location, control, params) . = ..() if (is_blinking) openToolTip(usr, src, params, content = "An admin is trying to talk to you!") -/atom/movable/screen/escape_menu/text/clickable/admin_help/MouseExited(location, control, params) +/atom/movable/screen/escape_menu/text/clickable/admin_ticket_notification/MouseExited(location, control, params) . = ..() closeToolTip(usr) + +///The button used for adminhelping, this is used to grey it out when you're on cooldown. +/atom/movable/screen/escape_menu/text/clickable/admin_help/Initialize( + mapload, + datum/hud/hud_owner, + datum/escape_menu/escape_menu, + button_text, + list/offset, + font_size = 24, + on_click_callback, +) + . = ..() + + RegisterSignals(escape_menu.client, list(COMSIG_CLIENT_VERB_ADDED, COMSIG_CLIENT_VERB_REMOVED), PROC_REF(on_client_verb_changed)) + +/atom/movable/screen/escape_menu/text/clickable/admin_help/proc/on_client_verb_changed(client/source, list/verbs_changed) + SIGNAL_HANDLER + + if (/client/verb/adminhelp in verbs_changed) + update_text() + +/atom/movable/screen/escape_menu/text/clickable/admin_help/enabled() + return (/client/verb/adminhelp in escape_menu.client?.verbs) diff --git a/code/modules/escape_menu/screen_objects/text.dm b/code/modules/escape_menu/screen_objects/text.dm index fe08bd021dc..529bd034c86 100644 --- a/code/modules/escape_menu/screen_objects/text.dm +++ b/code/modules/escape_menu/screen_objects/text.dm @@ -23,7 +23,7 @@ //this decides how far out you can 'click' on this, so it's important to keep it short. //yes even here, maptext can still embed links without using clickable subtype. - src.maptext_width = round((max(length(button_text), 20) * (font_size / 2.25)), 1) + src.maptext_width = max(round(length(button_text) * font_size * 0.75), font_size * 4) src.maptext_height = (maptext_height * (font_size / 5)) src.maptext_height *= length(splittext(button_text, "\n")) diff --git a/code/modules/events/ghost_role/sentience.dm b/code/modules/events/ghost_role/sentience.dm index 4fc837169d2..5d4668f640c 100644 --- a/code/modules/events/ghost_role/sentience.dm +++ b/code/modules/events/ghost_role/sentience.dm @@ -17,7 +17,7 @@ GLOBAL_LIST_INIT(high_priority_sentience, typecacheof(list( /mob/living/basic/sloth, /mob/living/basic/snake, /mob/living/basic/spider/giant/sgt_araneus, - /mob/living/simple_animal/bot/secbot/beepsky, + /mob/living/basic/bot/secbot/beepsky, /mob/living/basic/bear/snow/misha, /mob/living/basic/mining/lobstrosity/juvenile, ))) diff --git a/code/modules/events/grid_check.dm b/code/modules/events/grid_check.dm index 8fd3b86f14b..d68cdb72f14 100644 --- a/code/modules/events/grid_check.dm +++ b/code/modules/events/grid_check.dm @@ -27,4 +27,4 @@ COOLDOWN_START(controller, announcement_spam_protection, 30 SECONDS) /datum/round_event/grid_check/start() - power_fail(30, 120) + power_fail(60, 240) // 1 to 4 minutes diff --git a/code/modules/events/heart_attack.dm b/code/modules/events/heart_attack.dm index 6b826267726..4d82f558175 100644 --- a/code/modules/events/heart_attack.dm +++ b/code/modules/events/heart_attack.dm @@ -68,7 +68,10 @@ */ /datum/round_event/heart_attack/proc/attack_heart() var/mob/living/carbon/human/winner = pick_weight(victims) - if(winner.has_status_effect(/datum/status_effect/exercised)) //Stuff that should "block" a heart attack rather than just deny eligibility for one goes here. + // Our fitness level can potentially block a heart attack outright. + var/fitness_protection_probability = winner.mind?.get_skill_modifier(/datum/skill/athletics, SKILL_RANDS_MODIFIER) + + if(prob(fitness_protection_probability * 2)) //Stuff that should "block" a heart attack rather than just deny eligibility for one goes here. winner.visible_message(span_warning("[winner] grunts and clutches their chest for a moment, catching [winner.p_their()] breath."), span_medal("Your chest lurches in pain for a brief moment, which quickly fades. \ You feel like you've just avoided a serious health disaster."), span_hear("You hear someone's breathing sharpen for a moment, followed by a sigh of relief."), 4) winner.playsound_local(get_turf(winner), 'sound/effects/health/slowbeat.ogg', 40, 0, channel = CHANNEL_HEARTBEAT, use_reverb = FALSE) diff --git a/code/modules/events/immovable_rod/immovable_rod.dm b/code/modules/events/immovable_rod/immovable_rod.dm index e2404bbc090..9306fa7939a 100644 --- a/code/modules/events/immovable_rod/immovable_rod.dm +++ b/code/modules/events/immovable_rod/immovable_rod.dm @@ -245,6 +245,7 @@ span_boldwarning("[strongman] suplexes [src] into the ground!"), span_warning("As you suplex [src] into the ground, your body ripples with power!") ) + sound_to_playing_players('sound/items/handling/lead_pipe/lead_pipe_drop.ogg') new /obj/structure/festivus/anchored(drop_location()) new /obj/effect/anomaly/flux(drop_location()) diff --git a/code/modules/events/nightshift.dm b/code/modules/events/nightshift.dm new file mode 100644 index 00000000000..785ad8e04ac --- /dev/null +++ b/code/modules/events/nightshift.dm @@ -0,0 +1,78 @@ +/datum/round_event_control/nightshift + name = "Night Shift" + typepath = /datum/round_event/nightshift + weight = 2 + max_occurrences = 1 + earliest_start = 30 SECONDS + category = EVENT_CATEGORY_FRIENDLY + description = "Sets the station's lights to Night Shift mode for the next 20 minutes." + +/datum/round_event_control/nightshift/New() + . = ..() + if(!CONFIG_GET(flag/enable_night_shifts)) + max_occurrences = 0 + +/datum/round_event/nightshift + announce_when = 1 + start_when = 1 + end_when = 700 //~22 Minutes + fakeable = FALSE + + ///Whether the nightshift is on or not, synced to the alert level (which decides whether we're active) + ///TRUE means they are disabled by red alert. + var/nightshift_disabled = FALSE + ///APCs to update through ticks to account for lag. + var/list/currentrun + +/datum/round_event/nightshift/announce(fake) + update_nightshift(active = TRUE, announce = TRUE) + +/datum/round_event/nightshift/tick() + var/emergency = (SSsecurity_level.get_current_level_as_number() >= SEC_LEVEL_RED) + if(nightshift_disabled != emergency) + nightshift_disabled = emergency + if(emergency) + update_nightshift(active = FALSE, resume = TRUE) + else + update_nightshift(active = TRUE, resume = TRUE) + + update_machines() + +/datum/round_event/nightshift/end() + update_nightshift(active = FALSE, announce = TRUE) + +///Called several times, to start & stop nightlights including during red alert/de-red alerting. +/datum/round_event/nightshift/proc/update_nightshift(active, resume = FALSE, announce = FALSE) + currentrun = SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/power/apc) + + if(announce) + if(active) + send_announcement("Good evening, crew. To reduce power consumption and stimulate the circadian rhythms of some species, all of the lights aboard the station have been dimmed for the night.") + else + send_announcement("Good morning, crew. As it is now day time, all of the lights aboard the station have been restored to their former brightness.") + + if(resume) + if(active) + send_announcement("Restoring night lighting configuration to normal operation.") + else + send_announcement("Disabling night lighting: Station is in a state of emergency.") + + update_machines() + +///Called on process that will slowly update all APCs to be nightlight +/datum/round_event/nightshift/proc/update_machines() + for(var/obj/machinery/power/apc/APC as anything in currentrun) + currentrun -= APC + if (APC.area && (APC.area.type in GLOB.the_station_areas)) + APC.set_nightshift(!nightshift_disabled) + if(TICK_CHECK) + return + +///Custom messages sent throughout the event that we'll do here, instead of using the `announce` proc that's only at the start. +/datum/round_event/nightshift/proc/send_announcement(message) + priority_announce( + text = message, + sound = 'sound/announcer/notice/notice2.ogg', + sender_override = "Automated Lighting System Announcement", + color_override = "grey", + ) diff --git a/code/modules/events/radiation_storm.dm b/code/modules/events/radiation_storm.dm index 5b2b6b71ea1..fdc37f29715 100644 --- a/code/modules/events/radiation_storm.dm +++ b/code/modules/events/radiation_storm.dm @@ -7,8 +7,13 @@ min_wizard_trigger_potency = 3 max_wizard_trigger_potency = 7 -/datum/round_event/radiation_storm +/datum/round_event_control/radiation_storm/New() + . = ..() + if(max_occurrences > 0 && weight > 0 && check_holidays(CHERNOBYL_ANNIVERSARY)) + weight *= 2 + max_occurrences += 2 +/datum/round_event/radiation_storm /datum/round_event/radiation_storm/setup() start_when = 3 diff --git a/code/modules/events/space_vines/vine_mutations.dm b/code/modules/events/space_vines/vine_mutations.dm index ab6a3a2d394..542e8f092c9 100644 --- a/code/modules/events/space_vines/vine_mutations.dm +++ b/code/modules/events/space_vines/vine_mutations.dm @@ -268,6 +268,7 @@ /datum/spacevine_mutation/transparency/on_birth(obj/structure/spacevine/holder) holder.light_state = PASS_LIGHT holder.alpha = 125 + holder.unblock_sunlight() /datum/spacevine_mutation/gas_eater abstract_type = /datum/spacevine_mutation/gas_eater @@ -287,7 +288,7 @@ if(!gas_mix.gases[gas_type]) return - gas_mix.gases[gas_type][MOLES] = max(gas_mix.gases[gas_type][MOLES] - GAS_MUTATION_REMOVAL_MULTIPLIER * holder.growth_stage, 0) + gas_mix.set_gas(gas_type, max(gas_mix.gases[gas_type][MOLES] - GAS_MUTATION_REMOVAL_MULTIPLIER * holder.growth_stage, 0)) gas_mix.garbage_collect() /datum/spacevine_mutation/gas_eater/oxy_eater diff --git a/code/modules/events/space_vines/vine_structure.dm b/code/modules/events/space_vines/vine_structure.dm index da56c5359b8..f44e0da923f 100644 --- a/code/modules/events/space_vines/vine_structure.dm +++ b/code/modules/events/space_vines/vine_structure.dm @@ -38,6 +38,7 @@ AddElement(/datum/element/connect_loc, loc_connections) AddElement(/datum/element/atmos_sensitive, mapload) AddComponent(/datum/component/storm_hating) + block_sunlight() /obj/structure/spacevine/examine(mob/user) . = ..() @@ -215,3 +216,9 @@ . = ..() if(isvineimmune(mover)) return TRUE + +/obj/structure/spacevine/proc/block_sunlight() + AddElement(/datum/element/give_turf_traits, string_list(list(TRAIT_TURF_SUN_BLOCKED))) + +/obj/structure/spacevine/proc/unblock_sunlight() + RemoveElement(/datum/element/give_turf_traits, string_list(list(TRAIT_TURF_SUN_BLOCKED))) diff --git a/code/modules/fishing/fish/_fish.dm b/code/modules/fishing/fish/_fish.dm index f62b5573b3b..1ee2e416631 100644 --- a/code/modules/fishing/fish/_fish.dm +++ b/code/modules/fishing/fish/_fish.dm @@ -271,7 +271,11 @@ GLOBAL_LIST_INIT(fish_compatible_fluid_types, list( user.set_combat_mode(TRUE) ADD_TRAIT(user, TRAIT_COMBAT_MODE_LOCK, REF(src)) slapperoni(user, iteration = 1) - return MANUAL_SUICIDE + REMOVE_TRAIT(user, TRAIT_COMBAT_MODE_LOCK, REF(src)) + if (user.stat == DEAD) + return MANUAL_SUICIDE + user.visible_message(span_suicide("[user] slaps [user.p_them()]self with [src], but fails to go through with it!")) + return SHAME /obj/item/fish/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 == OVERWHELMING_ATTACK) diff --git a/code/modules/fishing/fish/fish_traits.dm b/code/modules/fishing/fish/fish_traits.dm index 342bfc981fd..ae97235cfe5 100644 --- a/code/modules/fishing/fish/fish_traits.dm +++ b/code/modules/fishing/fish/fish_traits.dm @@ -340,8 +340,8 @@ GLOBAL_LIST_INIT(spontaneous_fish_traits, populate_spontaneous_fish_traits()) return var/datum/gas_mixture/stench = new - ADD_GAS(/datum/gas/miasma, stench.gases) - stench.gases[/datum/gas/miasma][MOLES] = MIASMA_CORPSE_MOLES * 2 * seconds_per_tick + + stench.set_gas(/datum/gas/miasma, MIASMA_CORPSE_MOLES * 2 * seconds_per_tick) stench.temperature = mob.bodytemperature our_turf.assume_air(stench) diff --git a/code/modules/fishing/fishing_rod.dm b/code/modules/fishing/fishing_rod.dm index 8f21acb8829..ce2abbc6b99 100644 --- a/code/modules/fishing/fishing_rod.dm +++ b/code/modules/fishing/fishing_rod.dm @@ -92,11 +92,12 @@ set_slot(new line(src), ROD_SLOT_LINE) 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)) + AddComponent(/datum/component/bane, \ + damage_multiplier = 2.25, \ + should_bane_callback = CALLBACK(src, PROC_REF(should_bane_fish_infusions)), \ + on_bane_callback = CALLBACK(src, PROC_REF(on_bane_fish_infusions)), \ + label_text = "fishpeople", \ + ) /obj/item/fishing_rod/add_context(atom/source, list/context, obj/item/held_item, mob/user) if(src == held_item) @@ -260,18 +261,13 @@ material_chance += user.mind?.get_skill_level(/datum/skill/fishing) * 1.5 return material_chance -///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 +/obj/item/fishing_rod/proc/should_bane_fish_infusions(mob/living/target) + return force > 0 && HAS_TRAIT(target, TRAIT_WATER_ADAPTATION) -///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/proc/on_bane_fish_infusions(mob/living/target, mob/living/attacker) + target.adjust_staggered_up_to(STAGGERED_SLOWDOWN_LENGTH, 4 SECONDS) + target.adjust_confusion_up_to(1.5 SECONDS, 3 SECONDS) + target.adjust_wet_stacks(-4) /obj/item/fishing_rod/interact(mob/user) if(currently_hooked) diff --git a/code/modules/fishing/sources/subtypes/surgery.dm b/code/modules/fishing/sources/subtypes/surgery.dm index 2192d2ed5c8..de1fc0092e8 100644 --- a/code/modules/fishing/sources/subtypes/surgery.dm +++ b/code/modules/fishing/sources/subtypes/surgery.dm @@ -10,6 +10,7 @@ fishing_difficulty = -10 //The range for waiting is also a bit narrower, so it cannot take as few as 3 seconds or as many as 25 to snatch an organ. wait_time_range = list(6 SECONDS, 12 SECONDS) + fish_source_flags = FISH_SOURCE_FLAG_EXPLOSIVE_NONE /datum/fish_source/surgery/spawn_reward(reward_path, atom/spawn_location, atom/fishing_spot, obj/item/fishing_rod/used_rod) if(reward_path != FISHING_RANDOM_ORGAN) diff --git a/code/modules/flufftext/dreaming.dm b/code/modules/flufftext/dreaming.dm index 9ebb8cd41ad..73520a1625c 100644 --- a/code/modules/flufftext/dreaming.dm +++ b/code/modules/flufftext/dreaming.dm @@ -21,20 +21,17 @@ /mob/living/carbon/proc/dream() set waitfor = FALSE - var/datum/dream/chosen_dream - var/can_heretic_dream = ((IS_HERETIC(src) || HAS_TRAIT(src, TRAIT_HERETICAL_DREAMS)) && !mob_mood.get_mood_event("mansus_dream_fatigue")) + var/list/dream_pool = list() - if (can_heretic_dream && GLOB.reality_smash_track.smashes.len) - /// If someone attempts to have a heretical dream and there is an avaliable influence, one is picked randomly for a dream - chosen_dream = new /datum/dream/heretic(pick(GLOB.reality_smash_track.smashes)) - else if (can_heretic_dream && !IS_HERETIC(src) && !GLOB.reality_smash_track.smashes.len) - /// If a non-heretic attempts to have a heretic dream, but there aren't any influences due to there not being any real heretics, they are instead given a fake dream based on a random location. - chosen_dream = new /datum/dream/heretic(get_safe_random_station_turf_equal_weight()) - else - chosen_dream = pick_weight(GLOB.dreams) + SEND_SIGNAL(src, COMSIG_PRE_DREAMING, dream_pool) + if(!length(dream_pool)) + dream_pool = GLOB.dreams + + var/datum/dream/chosen_dream = pick_weight(dream_pool) ADD_TRAIT(src, TRAIT_DREAMING, DREAMING_SOURCE) + SEND_SIGNAL(src, COMSIG_START_DREAMING, chosen_dream) dream_sequence(chosen_dream.GenerateDream(src), chosen_dream) /** @@ -52,6 +49,7 @@ if(stat != UNCONSCIOUS || HAS_TRAIT(src, TRAIT_CRITICAL_CONDITION)) REMOVE_TRAIT(src, TRAIT_DREAMING, DREAMING_SOURCE) current_dream.OnDreamEnd(src) + SEND_SIGNAL(src, COMSIG_END_DREAMING, current_dream) return var/next_message = dream_fragments[1] dream_fragments.Cut(1,2) @@ -70,6 +68,7 @@ else REMOVE_TRAIT(src, TRAIT_DREAMING, DREAMING_SOURCE) current_dream.OnDreamEnd(src) + SEND_SIGNAL(src, COMSIG_END_DREAMING, current_dream) //------------------------- // DREAM DATUMS @@ -111,12 +110,9 @@ GLOBAL_LIST_INIT(dreams, populate_dream_list()) weight = 1000 /datum/dream/random/GenerateDream(mob/living/carbon/dreamer) - var/list/custom_dream_nouns = list() + var/list/custom_dream_nouns = get_dream_nouns(dreamer) || list() var/fragment = "" - for(var/obj/item/bedsheet/sheet in dreamer.loc) - custom_dream_nouns += sheet.dream_messages - . = list() . += "you see" @@ -159,6 +155,12 @@ GLOBAL_LIST_INIT(dreams, populate_dream_list()) fragment = "\a [replacetext(fragment, "%A% ", "")]" . += fragment +/datum/dream/random/proc/get_dream_nouns(mob/living/carbon/dreamer) + var/list/custom_dream_nouns = list() + for(var/obj/item/bedsheet/sheet in dreamer.loc) + custom_dream_nouns += sheet.dream_messages + return custom_dream_nouns + /// Dream plays a random sound at you, chosen from all sounds in the folder /datum/dream/hear_something weight = 500 @@ -193,76 +195,4 @@ GLOBAL_LIST_INIT(dreams, populate_dream_list()) /datum/dream/hear_something/proc/StopSound(mob/living/carbon/dreamer) SEND_SOUND(dreamer, sound(channel=reserved_sound_channel)) -/// Heretics can see dreams about random machinery from the perspective of a random unused influence -/datum/dream/heretic - sleep_until_finished = TRUE - /// The location of the influence (or lack thereof in the case of a fake dream) we will be dreaming about - var/atom/dream_center - /// The distance to the objects visible from the influence during the dream - var/dream_view_range = 5 - var/list/what_you_can_see = list( - /obj/item, - /obj/structure, - /obj/machinery, - ) - var/static/list/what_you_cant_see = typecacheof(list( - // Underfloor stuff and default wallmounts - /obj/item/radio/intercom, - /obj/structure/cable, - /obj/structure/disposalpipe/segment, - /obj/machinery/atmospherics/pipe/smart/manifold4w, - /obj/machinery/atmospherics/components/unary/vent_scrubber, - /obj/machinery/atmospherics/components/unary/vent_pump, - /obj/machinery/duct, - /obj/machinery/navbeacon, - /obj/machinery/power/terminal, - /obj/machinery/power/apc, - /obj/machinery/light_switch, - /obj/machinery/light, - /obj/machinery/camera, - /obj/machinery/door/firedoor, - /obj/machinery/firealarm, - /obj/machinery/airalarm, - /obj/structure/window/fulltile, - /obj/structure/window/reinforced/fulltile, - )) - /// Cached list of allowed typecaches for each type in what_you_can_see - var/static/list/allowed_typecaches_by_root_type = null - -/datum/dream/heretic/New(atom/dream_center) - src.dream_center = dream_center - -/datum/dream/heretic/GenerateDream(mob/living/carbon/dreamer) - . = list() - . += "You wander through the forest of Mansus" - . += "There is a " + pick("pond", "well", "lake", "puddle", "stream", "spring", "brook", "marsh") - - dreamer.add_mood_event("mansus_dream_fatigue", /datum/mood_event/mansus_dream_fatigue) - - if(isnull(allowed_typecaches_by_root_type)) - allowed_typecaches_by_root_type = list() - for(var/type in what_you_can_see) - allowed_typecaches_by_root_type[type] = typecacheof(type) - what_you_cant_see - - var/list/all_objects = oview(dream_view_range, dream_center) - var/something_found = FALSE - for(var/object_type in allowed_typecaches_by_root_type) - var/list/filtered_objects = typecache_filter_list(all_objects, allowed_typecaches_by_root_type[object_type]) - if(filtered_objects.len) - if (!something_found) - . += "Its waters reflect" - something_found = TRUE - var/obj/found_object = pick(filtered_objects) - . += initial(found_object.name) - if(!something_found) - . += pick("It's pitch black", "The reflections are vague", "You stroll aimlessly") - else - . += "The images fade in the ripples" - . += "You feel exhausted" - -/datum/mood_event/mansus_dream_fatigue - description = "I must recover before I can dream of Mansus again." - mood_change = -2 - timeout = 5 MINUTES - #undef DREAMING_SOURCE diff --git a/code/modules/food_and_drinks/machinery/smartfridge.dm b/code/modules/food_and_drinks/machinery/smartfridge.dm index a8b4235a920..ee06061f745 100644 --- a/code/modules/food_and_drinks/machinery/smartfridge.dm +++ b/code/modules/food_and_drinks/machinery/smartfridge.dm @@ -506,7 +506,7 @@ use_energy(active_power_usage) /obj/machinery/smartfridge/drying/accept_check(obj/item/O) - return HAS_TRAIT(O, TRAIT_DRYABLE) + return HAS_TRAIT(O, TRAIT_DRYABLE) && !HAS_TRAIT(O, TRAIT_DRIED) /** * Toggles drying on or off diff --git a/code/modules/food_and_drinks/recipes/drinks/drinks_alcoholic.dm b/code/modules/food_and_drinks/recipes/drinks/drinks_alcoholic.dm index 77e184e3d88..0b800fc6a87 100644 --- a/code/modules/food_and_drinks/recipes/drinks/drinks_alcoholic.dm +++ b/code/modules/food_and_drinks/recipes/drinks/drinks_alcoholic.dm @@ -741,8 +741,8 @@ required_reagents = list(/datum/reagent/consumable/orangejuice = 4, /datum/reagent/consumable/ethanol/aperitivo = 1) /datum/chemical_reaction/drink/improved_whiskey - results=list(/datum/reagent/consumable/ethanol/improved_whiskey = 12) - required_reagents = list(/datum/reagent/consumable/ethanol/sazerac = 10, /datum/reagent/consumable/ethanol/maraschino = 2) + results=list(/datum/reagent/consumable/ethanol/improved_whiskey = 7) + required_reagents = list(/datum/reagent/consumable/ethanol/sazerac = 6, /datum/reagent/consumable/ethanol/maraschino = 1) /datum/chemical_reaction/drink/jungle_bird results=list(/datum/reagent/consumable/ethanol/jungle_bird = 9) @@ -774,8 +774,8 @@ required_reagents = list(/datum/reagent/consumable/ethanol/martini = 3, /datum/reagent/consumable/ethanol/herbal_liqueur = 1) /datum/chemical_reaction/drink/pousse_cafe - results=list(/datum/reagent/consumable/ethanol/pousse_cafe = 50) // if you managed to make this properly, the least it can do is fit into a glass neatly - required_reagents = list(/datum/reagent/consumable/ethanol/navy_rum = 12, /datum/reagent/consumable/ethanol/whiskey = 11, /datum/reagent/consumable/ethanol/fernet = 10, /datum/reagent/consumable/ethanol/herbal_liqueur = 9, /datum/reagent/consumable/ethanol/kahlua = 8, /datum/reagent/consumable/grenadine = 7) // Since I have no way to simulate layering a cocktail, I will instead make it have absolutely godawful ratios to emulate the fiddling nessecary for something like this. + results=list(/datum/reagent/consumable/ethanol/pousse_cafe = 10) + required_reagents = list(/datum/reagent/consumable/ethanol/herbal_liqueur = 1, /datum/reagent/consumable/ethanol/bitters = 1, /datum/reagent/consumable/ethanol/branca_menta = 1, /datum/reagent/consumable/ethanol/irish_cream = 1, /datum/reagent/consumable/ethanol/yuyake = 1, /datum/reagent/consumable/ethanol/aperitivo = 1, /datum/reagent/consumable/ethanol/amaretto = 1, /datum/reagent/consumable/ethanol/curacao = 1, /datum/reagent/consumable/ethanol/maraschino = 1, /datum/reagent/consumable/toechtauese_syrup = 1) // In case someone wants to implement some sort of actual layering mechanic, these are listed from left to right by their specific gravity more or less /datum/chemical_reaction/drink/spritz results=list(/datum/reagent/consumable/ethanol/spritz = 6) diff --git a/code/modules/food_and_drinks/recipes/food_mixtures.dm b/code/modules/food_and_drinks/recipes/food_mixtures.dm index 15368d2c543..31458a4a129 100644 --- a/code/modules/food_and_drinks/recipes/food_mixtures.dm +++ b/code/modules/food_and_drinks/recipes/food_mixtures.dm @@ -121,8 +121,7 @@ /datum/chemical_reaction/food/chocolatepudding/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume) . = ..() - var/station_time = station_time() - if(!ISINRANGE(station_time, 3 HOURS + 45 MINUTES, 4 HOURS + 15 MINUTES)) + if(!ISINRANGE(world.timeofday, 3 HOURS + 45 MINUTES, 4 HOURS + 15 MINUTES)) return var/lastkey = holder.my_atom?.fingerprintslast if(!lastkey) diff --git a/code/modules/food_and_drinks/recipes/soup_mixtures.dm b/code/modules/food_and_drinks/recipes/soup_mixtures.dm index eef072eb192..ab9a2175a89 100644 --- a/code/modules/food_and_drinks/recipes/soup_mixtures.dm +++ b/code/modules/food_and_drinks/recipes/soup_mixtures.dm @@ -66,7 +66,7 @@ //number of ingredients who's requested amounts has been satisfied var/completed_ingredients = 0 for(var/obj/item/ingredient as anything in pot.added_ingredients) - var/ingredient_type = ingredient.type + var/datum/ingredient_type = ingredient.type do { var/ingredient_count = reqs_copy[ingredient_type] @@ -91,7 +91,7 @@ //means we have to look for subtypes else if(isnull(ingredient_count)) - ingredient_type = type2parent(ingredient_type) + ingredient_type = ingredient_type::parent_type //means we have no more remaining ingredients so bail, can happen if multiple ingredients of the same type/subtype are in the pot else diff --git a/code/modules/forensics/_forensics.dm b/code/modules/forensics/_forensics.dm index e03790e27b0..af37a9b5958 100644 --- a/code/modules/forensics/_forensics.dm +++ b/code/modules/forensics/_forensics.dm @@ -214,7 +214,7 @@ var/mob/living/carbon/human/human_suspect = suspect if(human_suspect.gloves) has_gloves = "(gloves)" - var/current_time = time_stamp() + var/current_time = round_timestamp() if(!LAZYACCESS(hiddenprints, suspect.key)) LAZYSET(hiddenprints, suspect.key, "First: \[[current_time]\] \"[suspect.real_name]\"[has_gloves]. Ckey: [suspect.ckey]") else diff --git a/code/modules/hallucination/bubblegum_attack.dm b/code/modules/hallucination/bubblegum_attack.dm index 64a4f0e2036..b1f735798e4 100644 --- a/code/modules/hallucination/bubblegum_attack.dm +++ b/code/modules/hallucination/bubblegum_attack.dm @@ -49,7 +49,7 @@ hallucinator.playsound_local(wall_source, 'sound/effects/meteorimpact.ogg', 150, TRUE) if(haunt_them) - to_chat(hallucinator, pick(hallucination_lines)) + to_chat(hallucinator, span_colossus(pick(hallucination_lines))) var/obj/effect/client_image_holder/hallucination/bubblegum/fake_bubbles = new(wall_source, hallucinator, src) addtimer(CALLBACK(src, PROC_REF(charge_loop), fake_bubbles, target_landing_turf), 1 SECONDS) diff --git a/code/modules/hallucination/mother.dm b/code/modules/hallucination/mother.dm index 77ed2cfb639..2d9a7ad6b59 100644 --- a/code/modules/hallucination/mother.dm +++ b/code/modules/hallucination/mother.dm @@ -81,11 +81,16 @@ /obj/effect/client_image_holder/hallucination/your_mother/Initialize(mapload, list/mobs_which_see_us, datum/hallucination/parent) var/mob/living/hallucinator = parent.hallucinator - if (ishuman(hallucinator)) + if (ishuman(hallucinator) && !isplasmaman(hallucinator)) //Plasmapeople don't have parents in a traditional sense, so their mother is different. var/mob/living/carbon/dna_haver = hallucinator image_icon = image(get_dynamic_human_appearance(/datum/outfit/yourmother, dna_haver.dna.species.type)) return ..() + if (isplasmaman(hallucinator)) + image_icon = 'icons/turf/floors.dmi' + image_state = "liquidplasma" + return ..() + if (istype(hallucinator, /mob/living/basic/pet/dog/corgi/ian)) image_icon = getFlatIcon(get_dynamic_human_appearance(/datum/outfit/job/hop)) name = "Head of Personnel" diff --git a/code/modules/holiday/holidays.dm b/code/modules/holiday/holidays.dm index 2f22d1afa97..78975a9c2d9 100644 --- a/code/modules/holiday/holidays.dm +++ b/code/modules/holiday/holidays.dm @@ -298,10 +298,6 @@ GLOBAL_LIST_INIT(holiday_mail, list()) . = ..() SSjob.set_overflow_role(/datum/job/clown) SSticker.set_lobby_music('sound/music/lobby_music/clown.ogg', override = TRUE) - for(var/i in GLOB.new_player_list) - var/mob/dead/new_player/P = i - if(P.client) - P.client.playtitlemusic() /datum/holiday/april_fools/get_holiday_colors(atom/thing_to_color) return "#[random_short_color()]" @@ -354,6 +350,21 @@ GLOBAL_LIST_INIT(holiday_mail, list()) /datum/holiday/anz/getStationPrefix() return pick("Australian","New Zealand","Poppy", "Southern Cross") +/datum/holiday/chernobyl + name = CHERNOBYL_ANNIVERSARY + begin_day = 26 + begin_month = APRIL + +/datum/holiday/chernobyl/getStationPrefix() + if(prob(3)) + return "Not Great, Not Terrible" + + return pick("Atomic", "Nuclear", "Radiation", "Plutonium", "Uranium", "Corium", "Zirconium", "Graphite", "Scram", "Explosion") + +/datum/holiday/chernobyl/greet() + return "On this day in 1986, the Chernobyl nuclear power plant melted down, causing one of the worst nuclear disasters in human history. \ + Today serves as a reminder to the lives lost and to the rigorous safety standards our engineers must adhere to when providing power to the station." + // MAY /datum/holiday/labor diff --git a/code/modules/holodeck/holo_effect.dm b/code/modules/holodeck/holo_effect.dm index 55535d4b570..7a035b94a6d 100644 --- a/code/modules/holodeck/holo_effect.dm +++ b/code/modules/holodeck/holo_effect.dm @@ -55,18 +55,42 @@ var/mob/our_mob = null /obj/effect/holodeck_effect/mobspawner/activate(obj/machinery/computer/holodeck/HC) + . = list() + if(islist(mobtype)) mobtype = pick(mobtype) our_mob = new mobtype(loc) our_mob.flags_1 |= HOLOGRAM_1 + . += our_mob + + for(var/atom/holo_atom as anything in our_mob.contents) + holo_atom.flags_1 |= HOLOGRAM_1 + . += holo_atom + + if(iscarbon(our_mob)) + var/mob/living/carbon/holo_carbon_mob = our_mob + for(var/obj/item/organ/holo_organ as anything in holo_carbon_mob.organs) + holo_organ.flags_1 |= HOLOGRAM_1 + . += holo_organ // these vars are not really standardized but all would theoretically create stuff on death our_mob.add_traits(list(TRAIT_PERMANENTLY_MORTAL, TRAIT_NO_BLOOD_OVERLAY, TRAIT_NOBLOOD, TRAIT_NOHUNGER, TRAIT_SPAWNED_MOB), INNATE_TRAIT) RegisterSignal(our_mob, COMSIG_QDELETING, PROC_REF(handle_mob_delete)) - return our_mob + + return . /obj/effect/holodeck_effect/mobspawner/deactivate(obj/machinery/computer/holodeck/HC) if(our_mob) + for(var/atom/holo_atom as anything in our_mob.contents) + if(holo_atom.flags_1 & HOLOGRAM_1) + HC.derez(holo_atom) + + if(iscarbon(our_mob)) + var/mob/living/carbon/holo_carbon_mob = our_mob + for(var/obj/item/organ/holo_organ as anything in holo_carbon_mob.organs) + if(holo_organ.flags_1 & HOLOGRAM_1) + HC.derez(holo_organ) + HC.derez(our_mob) qdel(src) @@ -100,13 +124,6 @@ /obj/effect/holodeck_effect/mobspawner/monkey mobtype = /mob/living/carbon/human/species/monkey -/obj/effect/holodeck_effect/mobspawner/monkey/activate(obj/machinery/computer/holodeck/computer) - var/mob/living/carbon/human/monkey = ..() - . = list() + monkey - - for(var/atom/atom as anything in monkey.contents + monkey.organs) - . += atom - /obj/effect/holodeck_effect/mobspawner/penguin mobtype = /mob/living/basic/pet/penguin/emperor/neuter diff --git a/code/modules/holodeck/holodeck_map_templates.dm b/code/modules/holodeck/holodeck_map_templates.dm index 3e79de6ea43..06cb3004ca1 100644 --- a/code/modules/holodeck/holodeck_map_templates.dm +++ b/code/modules/holodeck/holodeck_map_templates.dm @@ -157,3 +157,9 @@ template_id = "holodeck_refuelingstation" mappath = "_maps/templates/holodeck_refuelingstation.dmm" restricted = TRUE + +/datum/map_template/holodeck/prison + name = "Holodeck - Prison Block" + template_id = "holodeck_prison" + mappath = "_maps/templates/holodeck_prison.dmm" + restricted = TRUE diff --git a/code/modules/holodeck/turfs.dm b/code/modules/holodeck/turfs.dm index 7ef38b1a778..afc68ef468b 100644 --- a/code/modules/holodeck/turfs.dm +++ b/code/modules/holodeck/turfs.dm @@ -11,8 +11,9 @@ /turf/open/floor/holofloor/item_interaction(mob/living/user, obj/item/tool, list/modifiers) return ITEM_INTERACT_BLOCKING // Fuck you -/turf/open/floor/holofloor/crowbar_act(mob/living/user, obj/item/I) - return NONE // Fuck you +/turf/open/floor/holofloor/Initialize(mapload) + . = ..() + AddElement(/datum/element/tool_blocker, TOOL_CROWBAR, TOOL_ACT_PRIMARY) /turf/open/floor/holofloor/burn_tile() return //you can't burn a hologram! diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm index 78538b3e8b9..6e2db6c05ba 100644 --- a/code/modules/hydroponics/biogenerator.dm +++ b/code/modules/hydroponics/biogenerator.dm @@ -214,14 +214,14 @@ return . /obj/machinery/biogenerator/crowbar_act(mob/living/user, obj/item/tool) - if(!default_deconstruction_crowbar(tool)) - return ITEM_INTERACT_BLOCKING + . = default_deconstruction_crowbar(user, tool) + if(!(. & ITEM_INTERACT_SUCCESS)) + return var/turf/drop_location = drop_location() if(biomass > 0) drop_location.visible_message(span_warning("Biomass spills from \the [src]'s biomass tank!")) playsound(drop_location, 'sound/effects/slosh.ogg', 25, vary = TRUE) new /obj/effect/decal/cleanable/greenglow(drop_location) - return ITEM_INTERACT_SUCCESS /obj/machinery/biogenerator/item_interaction(mob/living/user, obj/item/tool, list/modifiers) if(user.combat_mode) diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index f5f58af7bbf..fd84b1a0fd3 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -82,6 +82,7 @@ reagents.clear_reagents() seed.prepare_result(src) transform *= TRANSFORM_USING_VARIABLE(seed.potency, 100) + 0.5 //Makes the resulting produce's sprite larger or smaller based on potency! + ADD_TRAIT(src, TRAIT_VALID_DNA_INFUSION, INNATE_TRAIT) /obj/item/food/grown/Destroy() if(isatom(seed)) diff --git a/code/modules/hydroponics/growninedible.dm b/code/modules/hydroponics/growninedible.dm index 82c69a8ef09..0502a500ef2 100644 --- a/code/modules/hydroponics/growninedible.dm +++ b/code/modules/hydroponics/growninedible.dm @@ -43,6 +43,7 @@ seed.prepare_result(src) transform *= TRANSFORM_USING_VARIABLE(seed.potency, 100) + 0.5 add_juice() + ADD_TRAIT(src, TRAIT_VALID_DNA_INFUSION, INNATE_TRAIT) /obj/item/grown/Destroy() if(isatom(seed)) diff --git a/code/modules/hydroponics/hydroitemdefines.dm b/code/modules/hydroponics/hydroitemdefines.dm index 158a9f1708c..cea1a45d157 100644 --- a/code/modules/hydroponics/hydroitemdefines.dm +++ b/code/modules/hydroponics/hydroitemdefines.dm @@ -173,11 +173,8 @@ /obj/item/scythe/Initialize(mapload) . = ..() - AddComponent(/datum/component/butchering, \ - speed = 9 SECONDS, \ - effectiveness = 105, \ - ) - AddElement(/datum/element/bane, mob_biotypes = MOB_PLANT, damage_multiplier = 0.5, requires_combat_mode = FALSE) + AddComponent(/datum/component/butchering, speed = 9 SECONDS, effectiveness = 105) + AddComponent(/datum/component/bane, affected_biotypes = MOB_PLANT, damage_multiplier = 1.5) /obj/item/scythe/suicide_act(mob/living/user) user.visible_message(span_suicide("[user] is beheading [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!")) diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index 97aecdfbf2c..4701c002673 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -795,6 +795,7 @@ set_pestlevel(0, update_icon = FALSE) // Pests die lastproduce = 0 SEND_SIGNAL(src, COMSIG_HYDROTRAY_PLANT_DEATH) + remove_shared_particles(/particles/pollen) //We shouldn't look like we're pollenating if we're dead. if(update_icon) update_appearance() @@ -1168,6 +1169,9 @@ if(myseed) to_chat(user, span_warning("[src] already has a plant growing in it!")) return + if(young_plant.seed_flags & NO_PLANTING) + to_chat(user, span_warning("[young_plant] cannot be planted in [src]!")) + return if(istype(young_plant, /obj/item/seeds/kudzu)) investigate_log("had Kudzu planted in it by [key_name(user)] at [AREACOORD(src)].", INVESTIGATE_BOTANY) if(!user.transferItemToLoc(young_plant, src)) diff --git a/code/modules/hydroponics/unique_plant_genes.dm b/code/modules/hydroponics/unique_plant_genes.dm index c2fcd8bef29..729a3d4a6e6 100644 --- a/code/modules/hydroponics/unique_plant_genes.dm +++ b/code/modules/hydroponics/unique_plant_genes.dm @@ -681,8 +681,8 @@ return var/datum/gas_mixture/stank = new - ADD_GAS(/datum/gas/miasma, stank.gases) - stank.gases[/datum/gas/miasma][MOLES] = (seed.yield + 6) * 3.5 * MIASMA_CORPSE_MOLES * seconds_per_tick // this process is only being called about 2/7 as much as corpses so this is 12-32 times a corpses + + stank.set_gas(/datum/gas/miasma, (seed.yield + 6) * 3.5 * MIASMA_CORPSE_MOLES * seconds_per_tick) // this process is only being called about 2/7 as much as corpses so this is 12-32 times a corpses stank.temperature = T20C // without this the room would eventually freeze and miasma mining would be easier tray_turf.assume_air(stank) diff --git a/code/modules/instruments/songs/editor.dm b/code/modules/instruments/songs/editor.dm index aef02858c03..93c84f5c74b 100644 --- a/code/modules/instruments/songs/editor.dm +++ b/code/modules/instruments/songs/editor.dm @@ -7,6 +7,11 @@ /datum/song/ui_host(mob/user) return parent +/datum/song/ui_state(mob/user) + if(ispAI(user)) + return GLOB.always_state + return ..() + /datum/song/ui_data(mob/user) var/list/data = ..() data["id"] = id diff --git a/code/modules/jobs/job_types/antagonists/nuclear_operative.dm b/code/modules/jobs/job_types/antagonists/nuclear_operative.dm index f2e38bf27d7..ac4b7be3435 100644 --- a/code/modules/jobs/job_types/antagonists/nuclear_operative.dm +++ b/code/modules/jobs/job_types/antagonists/nuclear_operative.dm @@ -2,26 +2,20 @@ title = ROLE_OPERATIVE /datum/job/nuclear_operative/get_roundstart_spawn_point() - return pick(GLOB.nukeop_start) + return pick(GLOB.nukeop_elevator_start) /datum/job/nuclear_operative/get_latejoin_spawn_point() - return pick(GLOB.nukeop_start) + return pick(GLOB.nukeop_base_start) /datum/job/nuclear_operative/leader -/datum/job/nuclear_operative/leader/get_roundstart_spawn_point() - return pick(GLOB.nukeop_leader_start) - /datum/job/nuclear_operative/leader/get_latejoin_spawn_point() - return pick(GLOB.nukeop_leader_start) + return pick(GLOB.nukeop_base_leader_start) /datum/job/nuclear_operative/clown_operative title = ROLE_CLOWN_OPERATIVE /datum/job/nuclear_operative/clown_operative/leader -/datum/job/nuclear_operative/clown_operative/leader/get_roundstart_spawn_point() - return pick(GLOB.nukeop_leader_start) - /datum/job/nuclear_operative/clown_operative/leader/get_latejoin_spawn_point() - return pick(GLOB.nukeop_leader_start) + return pick(GLOB.nukeop_base_leader_start) diff --git a/code/modules/jobs/job_types/assistant/gimmick_assistants.dm b/code/modules/jobs/job_types/assistant/gimmick_assistants.dm index e7caf881d3a..cd4746328f6 100644 --- a/code/modules/jobs/job_types/assistant/gimmick_assistants.dm +++ b/code/modules/jobs/job_types/assistant/gimmick_assistants.dm @@ -168,6 +168,7 @@ head = /obj/item/clothing/head/utility/hardhat uniform = /obj/item/clothing/under/color/yellow l_pocket = /obj/item/modular_computer/pda/assistant + pda_slot = ITEM_SLOT_LPOCKET outfit_weight = 6 diff --git a/code/modules/jobs/job_types/chaplain/chaplain_vorpal_scythe.dm b/code/modules/jobs/job_types/chaplain/chaplain_vorpal_scythe.dm index 91823a073c8..c06f8993b53 100644 --- a/code/modules/jobs/job_types/chaplain/chaplain_vorpal_scythe.dm +++ b/code/modules/jobs/job_types/chaplain/chaplain_vorpal_scythe.dm @@ -79,12 +79,8 @@ If the scythe isn't empowered when you sheath it, you take a heap of damage and /obj/item/vorpalscythe/Initialize(mapload) . = ..() AddElement(/datum/element/nullrod_core, chaplain_spawnable = FALSE, rune_remove_line = "TO DUST WITH YE!! AWAY!!") // The implant is the actual item the chappie can select - AddComponent( - /datum/component/butchering, \ - speed = 3 SECONDS, \ - effectiveness = 125, \ - ) - AddElement(/datum/element/bane, mob_biotypes = MOB_PLANT, damage_multiplier = 0.5, requires_combat_mode = FALSE) //also good at killing plants + AddComponent(/datum/component/bane, affected_biotypes = MOB_PLANT, damage_multiplier = 1.5) //also good at killing plants + AddComponent(/datum/component/butchering, speed = 3 SECONDS, effectiveness = 125) /obj/item/vorpalscythe/attack(mob/living/target, mob/living/user, list/modifiers, list/attack_modifiers) if(ismonkey(target) && !target.mind) //Don't empower from hitting monkeys. Hit a corgi or something, I don't know. diff --git a/code/modules/jobs/job_types/janitor.dm b/code/modules/jobs/job_types/janitor.dm index d7c52c8255b..52735aad579 100644 --- a/code/modules/jobs/job_types/janitor.dm +++ b/code/modules/jobs/job_types/janitor.dm @@ -39,7 +39,7 @@ uniform = /obj/item/clothing/under/rank/civilian/janitor belt = /obj/item/modular_computer/pda/janitor ears = /obj/item/radio/headset/headset_srv - skillchips = list(/obj/item/skillchip/job/janitor) + skillchips = list(/obj/item/skillchip/job/janitor, /obj/item/skillchip/disposals) backpack_contents = list(/obj/item/access_key) /datum/outfit/job/janitor/pre_equip(mob/living/carbon/human/human_equipper, visuals_only) diff --git a/code/modules/jobs/job_types/shaft_miner.dm b/code/modules/jobs/job_types/shaft_miner.dm index ed2916913a9..d8d87c2562b 100644 --- a/code/modules/jobs/job_types/shaft_miner.dm +++ b/code/modules/jobs/job_types/shaft_miner.dm @@ -97,6 +97,7 @@ l_pocket = /obj/item/modular_computer/pda/shaftminer r_pocket = /obj/item/extinguisher/mini belt = /obj/item/storage/belt/mining/healing + pda_slot = ITEM_SLOT_LPOCKET /datum/outfit/job/miner/equipped/combat/post_equip(mob/living/carbon/human/miner, visuals_only = FALSE) . = ..() diff --git a/code/modules/library/bibles.dm b/code/modules/library/bibles.dm index 07a83912f00..597c245a7c3 100644 --- a/code/modules/library/bibles.dm +++ b/code/modules/library/bibles.dm @@ -365,13 +365,13 @@ GLOBAL_LIST_INIT(bibleitemstates, list( /obj/item/book/bible/syndicate/Initialize(mapload) . = ..() AddComponent(/datum/component/anti_magic, MAGIC_RESISTANCE|MAGIC_RESISTANCE_HOLY) + AddComponent(/datum/component/bane, affected_biotypes = MOB_SPIRIT, added_damage = 25) AddComponent(/datum/component/effect_remover, \ success_feedback = "You disrupt the magic of %THEEFFECT with %THEWEAPON.", \ success_forcesay = "BEGONE FOUL MAGIKS!!", \ tip_text = "Clear rune", \ effects_we_clear = list(/obj/effect/rune, /obj/effect/heretic_rune, /obj/effect/cosmic_rune), \ ) - AddElement(/datum/element/bane, mob_biotypes = MOB_SPIRIT, damage_multiplier = 0, added_damage = 25, requires_combat_mode = FALSE) /obj/item/book/bible/syndicate/attack_self(mob/living/carbon/human/user, modifiers) if(!uses || !istype(user)) diff --git a/code/modules/library/book_info.dm b/code/modules/library/book_info.dm index 8663069644d..e9a4810818e 100644 --- a/code/modules/library/book_info.dm +++ b/code/modules/library/book_info.dm @@ -39,15 +39,19 @@ if(trusted) content = _content return - content = trim(html_encode(_content), MAX_PAPER_LENGTH) + content = trim(html_encode(trim(_content, MAX_PAPER_LENGTH)), MAX_BOOK_LENGTH) /datum/book_info/proc/set_content_using_paper(obj/item/paper/paper) // Just the paper's raw data. var/raw_content = "" for(var/datum/paper_input/text_input as anything in paper.raw_text_inputs) raw_content += text_input.to_raw_html() + raw_content += (text_input.raw_text[length(text_input.raw_text)] == "\n") ? "\n" : "\n\n" - content = trim(html_encode(raw_content), MAX_PAPER_LENGTH) + // Paper raw inputs should already be trimmed to maximum paper length, + // so we don't trim here again to avoid cutting into the expanded html. + // We still trim to a more lenient length to avoid abuse. + content = trim(html_encode(raw_content), MAX_BOOK_LENGTH) /datum/book_info/proc/get_content(default="N/A") return html_decode(content) || "N/A" diff --git a/code/modules/library/skill_learning/generic_skillchips/misc.dm b/code/modules/library/skill_learning/generic_skillchips/misc.dm index 288b164bc63..253d411ab87 100644 --- a/code/modules/library/skill_learning/generic_skillchips/misc.dm +++ b/code/modules/library/skill_learning/generic_skillchips/misc.dm @@ -154,3 +154,13 @@ /datum/action/cooldown/fishing_tip/Activate(atom/target_atom) . = ..() send_tip_of_the_round(owner, pick(GLOB.fishing_tips), source = "Ancient fishing wisdom") + +/obj/item/skillchip/disposals + name = "T4RG3T.bin skillchip" + desc = "Become a dauntless disposaler, target trash right where it belongs." + auto_traits = list(TRAIT_THROWINGARM) + skill_name = "Dauntless Disposaler" + skill_description = "You have an uncanny ability to perfectly land every toss into disposal units." + skill_icon = "trash-can" + activate_message = span_notice("You seem laser focused on the nearby disposal unit.") + deactivate_message = span_notice("The nearby disposal unit fades into the background of your vision.") diff --git a/code/modules/lighting/lighting_corner.dm b/code/modules/lighting/lighting_corner.dm index 4c35a8f2bb3..1323f45f1e6 100644 --- a/code/modules/lighting/lighting_corner.dm +++ b/code/modules/lighting/lighting_corner.dm @@ -141,7 +141,7 @@ return #endif - var/datum/lighting_object/lighting_object = master_NE?.lighting_object + var/atom/movable/lighting_object/lighting_object = master_NE?.lighting_object if (lighting_object && !lighting_object.needs_update) lighting_object.needs_update = TRUE SSlighting.objects_queue += lighting_object @@ -163,10 +163,6 @@ self_destruct_if_idle() - -/datum/lighting_corner/dummy/New() - return - /datum/lighting_corner/Destroy(force) if (!force) return QDEL_HINT_LETMELIVE diff --git a/code/modules/lighting/lighting_object.dm b/code/modules/lighting/lighting_object.dm index c5ce42e45ed..85bcd6c0c31 100644 --- a/code/modules/lighting/lighting_object.dm +++ b/code/modules/lighting/lighting_object.dm @@ -1,32 +1,50 @@ -/datum/lighting_object - ///the underlay we are currently applying to our turf to apply light - var/mutable_appearance/current_underlay - +/atom/movable/lighting_object + name = "" + anchored = TRUE + plane = LIGHTING_PLANE + icon = LIGHTING_ICON + icon_state = null + color = null //we manually set color in init instead + appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + invisibility = INVISIBILITY_LIGHTING + move_resist = INFINITY ///whether we are already in the SSlighting.objects_queue list var/needs_update = FALSE ///the turf that our light is applied to var/turf/affected_turf -// Global list of lighting underlays, indexed by z level -GLOBAL_LIST_EMPTY(default_lighting_underlays_by_z) - -/datum/lighting_object/New(turf/source) - if(!isturf(source)) - qdel(src, force=TRUE) - stack_trace("a lighting object was assigned to [source], a non turf! ") - return +/atom/movable/lighting_object/Initialize(mapload, turf/affected_turf) + if(!isnull(loc)) + if(isturf(loc)) + affected_turf = loc + moveToNullspace() + stack_trace("a lighting object was improperly initialized - they should have a null loc, with the affected turf being the second argument") + else + qdel(src, force = TRUE) + CRASH("a lighting object tried to be spawned for a non-turf!") + if(!isturf(affected_turf)) + qdel(src, force = TRUE) + CRASH("a lighting object was assigned to [affected_turf], a non turf!") . = ..() - current_underlay = new(GLOB.default_lighting_underlays_by_z[source.z]) + verbs.Cut() - affected_turf = source + src.affected_turf = affected_turf + layer = affected_turf.z * 0.01 + if(SSmapping.max_plane_offset) + // generates the offset lighting plane to use. NOTE: this assumes the turf lighting + // plane is ALWAYS offsettable which is technically dependent on a plane master var. + // checking for that is slower and this is hot enough that this is a worthwhile risk to take + plane = LIGHTING_PLANE - (PLANE_RANGE * GET_Z_PLANE_OFFSET(affected_turf.z)) if (affected_turf.lighting_object) qdel(affected_turf.lighting_object, force = TRUE) stack_trace("a lighting object was assigned to a turf that already had a lighting object!") affected_turf.lighting_object = src + affected_turf.vis_contents += src // Default to fullbright, so things can "see" if they use view() before we update affected_turf.luminosity = 1 @@ -38,18 +56,20 @@ GLOBAL_LIST_EMPTY(default_lighting_underlays_by_z) needs_update = TRUE SSlighting.objects_queue += src -/datum/lighting_object/Destroy(force) +/atom/movable/lighting_object/Destroy(force) if (!force) return QDEL_HINT_LETMELIVE SSlighting.objects_queue -= src if (isturf(affected_turf)) + affected_turf.vis_contents -= src affected_turf.lighting_object = null affected_turf.luminosity = 1 - affected_turf.underlays -= current_underlay affected_turf = null return ..() -/datum/lighting_object/proc/update() +/atom/movable/lighting_object/proc/update() + var/turf/affected_turf = src.affected_turf + // To the future coder who sees this and thinks // "Why didn't he just use a loop?" // Well my man, it's because the loop performed like shit. @@ -60,8 +80,6 @@ GLOBAL_LIST_EMPTY(default_lighting_underlays_by_z) var/static/datum/lighting_corner/dummy/dummy_lighting_corner = new - var/turf/affected_turf = src.affected_turf - #ifdef VISUALIZE_LIGHT_UPDATES affected_turf.add_atom_colour(COLOR_BLUE_LIGHT, ADMIN_COLOUR_PRIORITY) animate(affected_turf, 10, color = null) @@ -84,20 +102,12 @@ GLOBAL_LIST_EMPTY(default_lighting_underlays_by_z) var/set_luminosity = max > 1e-6 #endif - var/mutable_appearance/current_underlay = src.current_underlay - affected_turf.underlays -= current_underlay - if(red_corner.cache_r & green_corner.cache_r & blue_corner.cache_r & alpha_corner.cache_r && \ - (red_corner.cache_g + green_corner.cache_g + blue_corner.cache_g + alpha_corner.cache_g + \ - red_corner.cache_b + green_corner.cache_b + blue_corner.cache_b + alpha_corner.cache_b == 8)) - //anything that passes the first case is very likely to pass the second, and addition is a little faster in this case - current_underlay.icon_state = "lighting_transparent" - current_underlay.color = null - else if(!set_luminosity) - current_underlay.icon_state = "lighting_dark" - current_underlay.color = null + if(!set_luminosity) + icon_state = "lighting_dark" + color = null else - current_underlay.icon_state = null - current_underlay.color = list( + icon_state = null + color = list( red_corner.cache_r, red_corner.cache_g, red_corner.cache_b, 00, green_corner.cache_r, green_corner.cache_g, green_corner.cache_b, 00, blue_corner.cache_r, blue_corner.cache_g, blue_corner.cache_b, 00, @@ -105,7 +115,34 @@ GLOBAL_LIST_EMPTY(default_lighting_underlays_by_z) 00, 00, 00, 01 ) - // Of note. Most of the cost in this proc is here, I think because color matrix'd underlays DO NOT cache well, which is what adding to underlays does - // We use underlays because objects on each tile would fuck with maptick. if that ever changes, use an object for this instead - affected_turf.underlays += current_underlay - affected_turf.luminosity = set_luminosity + luminosity = set_luminosity + +// Variety of overrides so the overlays don't get affected by weird things. + +/atom/movable/lighting_object/ex_act(severity) + return FALSE + +/atom/movable/lighting_object/singularity_act() + return + +/atom/movable/lighting_object/singularity_pull() + return + +/atom/movable/lighting_object/blob_act() + return + +/atom/movable/lighting_object/on_changed_z_level(turf/old_turf, turf/new_turf, same_z_layer, notify_contents = TRUE) + SHOULD_CALL_PARENT(FALSE) + return + +/atom/movable/lighting_object/wash(clean_types) + SHOULD_CALL_PARENT(FALSE) // lighting objects are dirty, confirmed + return + +// Override here to prevent things accidentally moving around overlays. +/atom/movable/lighting_object/forceMove(atom/destination, no_tp = FALSE, harderforce = FALSE) + if(harderforce) + return ..() + +/atom/movable/lighting_object/ref_search_details() + return "[text_ref(src)] (turf: [affected_turf ? "[affected_turf.type] @ [AREACOORD(affected_turf)]" : "null"] needs_update: [needs_update ? "true" : "false"])" diff --git a/code/modules/lighting/lighting_turf.dm b/code/modules/lighting/lighting_turf.dm index 949d9b59b8f..f3feed46bcf 100644 --- a/code/modules/lighting/lighting_turf.dm +++ b/code/modules/lighting/lighting_turf.dm @@ -14,7 +14,7 @@ if (lighting_object) qdel(lighting_object, force=TRUE) //Shitty fix for lighting objects persisting after death - new /datum/lighting_object(src) + new /atom/movable/lighting_object(null, src) // Used to get a scaled lumcount. /turf/proc/get_lumcount(minlum = 0, maxlum = 1) diff --git a/code/modules/logging/log_holder.dm b/code/modules/logging/log_holder.dm index fa295c5e292..666390613ec 100644 --- a/code/modules/logging/log_holder.dm +++ b/code/modules/logging/log_holder.dm @@ -32,13 +32,10 @@ GLOBAL_REAL(logger, /datum/log_holder) GENERAL_PROTECT_DATUM(/datum/log_holder) -ADMIN_VERB(log_viewer_new, R_ADMIN|R_DEBUG, "View Round Logs", "View the rounds logs.", ADMIN_CATEGORY_MAIN) +ADMIN_VERB(log_viewer_new, R_ADMIN, "View Round Logs", "View the rounds logs.", ADMIN_CATEGORY_MAIN) logger.ui_interact(user.mob) /datum/log_holder/ui_interact(mob/user, datum/tgui/ui) - if(!check_rights_for(user.client, R_ADMIN)) - return - ui = SStgui.try_update_ui(user, src, ui) if(isnull(ui)) ui = new(user, src, "LogViewer") @@ -46,7 +43,7 @@ ADMIN_VERB(log_viewer_new, R_ADMIN|R_DEBUG, "View Round Logs", "View the rounds ui.open() /datum/log_holder/ui_state(mob/user) - return ADMIN_STATE(R_ADMIN | R_DEBUG) + return ADMIN_STATE(R_ADMIN) /datum/log_holder/ui_static_data(mob/user) var/list/data = list( diff --git a/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm b/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm index 0674ff97cb8..ffcd8c07a49 100644 --- a/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm +++ b/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm @@ -325,14 +325,6 @@ new /obj/effect/decal/cleanable/blood/gibs/old(src) new /obj/item/book/granter/crafting_recipe/boneyard_notes(src) -/obj/structure/closet/crate/grave/skeleton - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF - affect_mood = TRUE - -/obj/structure/closet/crate/grave/skeleton/PopulateContents() - . = ..() - new /mob/living/carbon/human/species/skeleton(src) - //***Fluff items for lore/intrigue /obj/item/paper/crumpled/muddy/fluff/elephant_graveyard name = "posted warning" diff --git a/code/modules/mapfluff/ruins/objects_and_mobs/ash_walker_den.dm b/code/modules/mapfluff/ruins/objects_and_mobs/ash_walker_den.dm index ce57035a766..b18e740f8cb 100644 --- a/code/modules/mapfluff/ruins/objects_and_mobs/ash_walker_den.dm +++ b/code/modules/mapfluff/ruins/objects_and_mobs/ash_walker_den.dm @@ -123,4 +123,77 @@ resistance_flags = FIRE_PROOF | LAVA_PROOF max_integrity = 200 +/obj/effect/light_emitter/tendril + set_luminosity = 4 + set_cap = 2.5 + light_color = LIGHT_COLOR_LAVA + +/obj/effect/collapse + name = "collapsing necropolis tendril" + desc = "Get your loot and get clear!" + layer = TABLE_LAYER + icon = 'icons/mob/simple/lavaland/nest.dmi' + icon_state = "tendril" + anchored = TRUE + density = TRUE + /// weakref list of which mobs have gotten their loot from this effect. + var/list/collected = list() + /// a bit of light as to make less unfair deaths from the chasm + var/obj/effect/light_emitter/tendril/emitted_light + +/obj/effect/collapse/Initialize(mapload) + . = ..() + emitted_light = new(loc) + visible_message(span_bolddanger("The tendril writhes in fury as the earth around it begins to crack and break apart! Get back!")) + balloon_alert_to_viewers("interact to grab loot before collapse!", vision_distance = 7) + playsound(loc,'sound/effects/tendril_destroyed.ogg', 200, FALSE, 50, TRUE, TRUE) + addtimer(CALLBACK(src, PROC_REF(collapse)), 5 SECONDS) + +/obj/effect/collapse/examine(mob/user) + var/list/examine_messages = ..() + if(isliving(user)) + if(has_collected(user)) + examine_messages += span_boldnotice("You've grabbed what you can, now get out!") + else + examine_messages += span_boldnotice("You might have some time to grab some goodies with an open hand before it collapses!") + return examine_messages + +/obj/effect/collapse/attack_hand(mob/living/collector, list/modifiers) + . = ..() + if(has_collected(collector)) + to_chat(collector, span_danger("You've already gotten some loot, just get out of there with it!")) + return + visible_message(span_warning("Something falls free of the tendril!")) + var/obj/structure/closet/crate/necropolis/tendril/loot = new /obj/structure/closet/crate/necropolis/tendril(loc) + collector.start_pulling(loot) + collected += WEAKREF(collector) + +/obj/effect/collapse/Destroy() + collected.Cut() + QDEL_NULL(emitted_light) + return ..() + +///Helper proc that resolves weakrefs to determine if collector is in collected list, returning a boolean. +/obj/effect/collapse/proc/has_collected(mob/collector) + for(var/datum/weakref/weakref as anything in collected) + var/mob/living/resolved = weakref.resolve() + //it could have been collector, it could not have been, we don't care + if(!resolved) + continue + if(resolved == collector) + return TRUE + return FALSE + +/obj/effect/collapse/proc/collapse() + for(var/mob/viewer in range(7, src)) + shake_camera(viewer, 15, 1) + playsound(get_turf(src),'sound/effects/explosion/explosionfar.ogg', 200, TRUE) + visible_message(span_bolddanger("The tendril falls inward, the ground around it widening into a yawning chasm!")) + for(var/turf/ground in RANGE_TURFS(2, src)) + if(HAS_TRAIT(ground, TRAIT_NO_TERRAFORM)) + continue + if(!ground.density) + ground.TerraformTurf(/turf/open/chasm/lavaland, /turf/open/chasm/lavaland, flags = CHANGETURF_INHERIT_AIR) + qdel(src) + #undef ASH_WALKER_SPAWN_THRESHOLD diff --git a/code/modules/mapfluff/ruins/objects_and_mobs/museum.dm b/code/modules/mapfluff/ruins/objects_and_mobs/museum.dm index 2917c8b88e7..13963576232 100644 --- a/code/modules/mapfluff/ruins/objects_and_mobs/museum.dm +++ b/code/modules/mapfluff/ruins/objects_and_mobs/museum.dm @@ -161,11 +161,10 @@ /obj/machinery/vending/hotdog/museum all_products_free = TRUE -/obj/machinery/vending/hotdog/museum/screwdriver_act(mob/living/user, obj/item/attack_item) - return NONE - -/obj/machinery/vending/hotdog/museum/crowbar_act(mob/living/user, obj/item/attack_item) - return NONE +/obj/machinery/vending/hotdog/museum/Initialize(mapload) + . = ..() + AddElement(/datum/element/tool_blocker, TOOL_SCREWDRIVER, TOOL_ACT_PRIMARY) + AddElement(/datum/element/tool_blocker, TOOL_CROWBAR, TOOL_ACT_PRIMARY) #define CAFE_KEYCARD_TOILETS "museum_cafe_key_toilets" diff --git a/code/modules/mapfluff/ruins/objects_and_mobs/necropolis_gate.dm b/code/modules/mapfluff/ruins/objects_and_mobs/necropolis_gate.dm index 733cd8330bc..cb9bb33a92f 100644 --- a/code/modules/mapfluff/ruins/objects_and_mobs/necropolis_gate.dm +++ b/code/modules/mapfluff/ruins/objects_and_mobs/necropolis_gate.dm @@ -264,7 +264,7 @@ GLOBAL_DATUM(necropolis_gate, /obj/structure/necropolis_gate/legion_gate) var/static/list/give_turf_traits if(!give_turf_traits) - give_turf_traits = string_list(list(TRAIT_LAVA_STOPPED, TRAIT_CHASM_STOPPED, TRAIT_IMMERSE_STOPPED)) + give_turf_traits = string_list(list(TRAIT_TURF_IGNORE_SLOWDOWN, TRAIT_LAVA_STOPPED, TRAIT_CHASM_STOPPED, TRAIT_IMMERSE_STOPPED)) AddElement(/datum/element/give_turf_traits, give_turf_traits) /obj/structure/stone_tile/singularity_pull(atom/singularity, current_size) diff --git a/code/modules/mapfluff/ruins/shoe_factory.dm b/code/modules/mapfluff/ruins/shoe_factory.dm new file mode 100644 index 00000000000..db2f8b20d93 --- /dev/null +++ b/code/modules/mapfluff/ruins/shoe_factory.dm @@ -0,0 +1,116 @@ +/area/ruin/shoe_factory + name = "\improper Shoe Factory" + +/obj/effect/spawner/random/mining_loot/shoe_factory + name = "random shoe factory loot" + desc = "Spawns shoes from the loot list. Shoes have a randomized slowdown modifier." + icon = 'icons/obj/clothing/shoes.dmi' + icon_state = "sneakers" + loot = list() + loot_subtype_path = /obj/item/clothing/shoes + spawn_loot_count = 5 + spawn_scatter_radius = 2 + spawn_random_offset = TRUE + +/obj/effect/spawner/random/mining_loot/shoe_factory/make_item(spawn_loc, type_path_to_make) + var/obj/item/clothing/shoes/shoe = ..() + if(istype(shoe)) + // shoes will spawn anywhere from -0.5 speed modifer (fast) to +0.5 speed (slow) + // See https://tadeohepperle.com/dice-calculator-frontend/?d1=%2B5d3 to view dice chances for rolls (higher rolls == faster shoes) + var/dice_result = roll("5d3") + var/slowdown_modifier = (1 - (dice_result * 0.1)) + shoe.slowdown += slowdown_modifier + + return shoe + +/obj/item/paper/fluff/ruins/shoe_factory/osha_shutdown + name = "Official Spess OSHA Closure Notice" + desc = "A heavily stamped document with a bright red 'CONDEMNED' watermark." + default_raw_text = "SPESS OCCUPATIONAL SAFETY & HEALTH ADMINISTRATION

    \ + ORDER OF IMMEDIATE CLOSURE

    \ + Facility 44-S (Footwear Manufacturing Division) is hereby ordered to cease all operations indefinitely pending a Class-A kinetic anomaly investigation.

    \ + Citations:
    \ +
      \ +
    • Violation 882.A: Extreme deviation in product density. Random inspections reveal that approximately 99% of 'Sprint-Mate' footwear units possess a localized gravitational anomaly. Users report immense physical exertion, equating standard walking to 'dragging an asteroid through wet cement.'
    • \ +
    • Violation 882.B: Lethal kinetic acceleration. The remaining 1% of the production line exhibits zero-friction bluespace properties. A OSHA inspector testing a pair was accelerated to 150 km/h into a reinforced plasma glass window, resulting in critical injuries and a localized hull breach.
    • \ +

    \ + All assets are frozen. Do not attempt to transport the remaining stock. If you must move a crate, DO NOT wear the contents." + + +/obj/item/paper/fluff/shoe_factory_osha + name = "Space OSHA Inspection Notice" + default_raw_text = {" +
    NANOTRASEN OCCUPATIONAL SAFETY AND HAZARD ADMINISTRATION
    + Form 77-B: Mandatory Facility Closure Order

    +
    + Facility: Cobbleton & Sons Shoe Manufacturing, Ltd.
    + Inspector: H. Bootsworth, Senior Field Auditor
    + Date of Inspection: ██/██/25██
    + Outcome: IMMEDIATE CLOSURE ORDERED
    +
    + Summary of Violations:
    +
    + Following a routine workplace safety audit, the following CRITICAL violations + were observed on the factory floor:
    +
    + 1. Multiple pairs of finished footwear were found to exhibit anomalous and + hazardous properties inconsistent with standard shoe behavior. Products were + observed (REDACTED), emitting unlicensed energy signatures, and in one case + actively resisting removal from the test subject's feet.
    +
    + 2. ZERO quality assurance records were found on-site. When asked about QA + procedures, the floor manager gestured vaguely at a clown and said + "he tries them on sometimes."
    +
    + 3. The manufacturing line lacks any form of anomalous material handling + protocols despite the finished product clearly being outside baseline + safety parameters.
    +
    + Closing Remarks:
    +
    + I have been a Safety Auditor for 15 years across 3 sectors. I have shut down + plasma refineries. I have cited singularity engine rooms. I have written + violations for clown cars exceeding maximum occupancy by a factor of eleven.
    +
    + I have never seen shoes do the things these shoes do.
    +
    + This facility is to remain sealed until such time as a full anomalous item + review board can assess the product line. Any remaining inventory is + NOT to be removed from the premises.
    +
    + (Addendum: if anyone from Corporate is reading this - no, you cannot + sell these. I don't care how much the profit margin is. Stop asking.)
    +
    + This notice is the property of Space OSHA. Removal or defacement of this + notice is punishable under Nanotrasen Workplace Safety Code § 4.77.2 + "} + +/obj/item/paper/fluff/shoe_factory_closure + name = "NOTICE OF CLOSURE" + desc = "An official-looking document bearing the Space OSHA seal. Someone has drawn a tiny angry face on the corner." + default_raw_text = {"
    SPACE OCCUPATIONAL SAFETY & HAZARDS ADMINISTRATION
    +
    OFFICIAL NOTICE OF FACILITY CLOSURE
    +
    +Facility: Unnamed Bootwear Manufactory, Sector (REDACTED)
    +Inspecting Officer: Senior Agent Greaves, Division VII
    +Status: PERMANENTLY CLOSED, pending owner's response (owner has not responded in 14 standard months).
    +
    + +To whom it may concern,

    + +Following a routine compliance audit, this facility has been found in gross violation of no fewer than thirty-two distinct Space OSHA regulations. A full list is appended in Annex B. For the purposes of this summary notice, the most egregious are reproduced below:

    + +1. Complete absence of any functioning Quality Assurance pipeline. Upon questioning, the foreman claimed the previous QA officer "left in a hurry" through an unpatched hole in the ceiling. The hole has been independently verified. The QA officer has not.

    + +2. Production of footwear containing undeclared active components. This office has recovered several finished units displaying behavior wildly inconsistent with what a reasonable being would call "a shoe." The proprietor insists these are "premium features" for "the discerning adventurer." This office insists they are lawsuits.

    + +3. Failure to properly label hazardous stock. If you are reading this notice, and you are standing in the facility, and you are considering putting on a pair of the shoes on the floor: please do not. Or do. We are no longer liable either way.

    + +4. No fire exits. No fire extinguishers. Considerable amounts of flammable leather. We don't even know where to start.

    + +By the authority vested in this office, all operations are to cease immediately. Any remaining inventory is the property of the Crown and/or whoever gets here first.

    + +Stay safe out there.

    + +— Sr. Agent Greaves, Space OSHA
    +"If it looks unsafe, it probably is. If it looks safe, it probably still is.""} diff --git a/code/modules/mapping/map_template.dm b/code/modules/mapping/map_template.dm index 0f6ff85eed9..a0a309849dc 100644 --- a/code/modules/mapping/map_template.dm +++ b/code/modules/mapping/map_template.dm @@ -90,14 +90,7 @@ return SSatoms.InitializeAtoms(areas + turfs + movables, returns_created_atoms ? created_atoms : null) - - for(var/turf/unlit as anything in turfs) - if(unlit.space_lit) - continue - var/area/loc_area = unlit.loc - if(!loc_area.static_lighting) - continue - unlit.lighting_build_overlay() + SSlighting.setup_static_lighting_if_needed(turfs) // NOTE, now that Initialize and LateInitialize run correctly, do we really // need these two below? diff --git a/code/modules/meteors/meteor_mode_controller.dm b/code/modules/meteors/meteor_mode_controller.dm index d19d5522bb7..ca22627233d 100644 --- a/code/modules/meteors/meteor_mode_controller.dm +++ b/code/modules/meteors/meteor_mode_controller.dm @@ -9,8 +9,6 @@ GLOBAL_DATUM(meteor_mode, /datum/meteor_mode_controller) var/rampupdelta = 5 /datum/meteor_mode_controller/proc/start_meteor() - if(datum_flags & DF_ISPROCESSING) - return START_PROCESSING(SSprocessing, src) /datum/meteor_mode_controller/process(seconds_per_tick) diff --git a/code/modules/mining/aux_base.dm b/code/modules/mining/aux_base.dm index 82cdaffa714..ff4bf581cd8 100644 --- a/code/modules/mining/aux_base.dm +++ b/code/modules/mining/aux_base.dm @@ -147,7 +147,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/computer/auxiliary_base, 32) return var/shuttle_error = SSshuttle.moveShuttle(shuttleId, params["shuttle_id"], 1) if(launch_warning) - say("Launch sequence activated! Prepare for drop!!", spans = list("danger")) + say("Launch sequence activated! Prepare for drop!!", spans = list(SPAN_DANGER)) playsound(loc, 'sound/machines/warning-buzzer.ogg', 70, FALSE) launch_warning = FALSE blind_drop_ready = FALSE diff --git a/code/modules/mining/boulder_processing/_boulder_processing.dm b/code/modules/mining/boulder_processing/_boulder_processing.dm index 86a8679d036..324c616ae84 100644 --- a/code/modules/mining/boulder_processing/_boulder_processing.dm +++ b/code/modules/mining/boulder_processing/_boulder_processing.dm @@ -22,6 +22,8 @@ var/points_held = 0 ///The action verb to display to players var/action = "processing" + /// What reagent should be produced when a boost chemical is replaced by the booster_reagent? + var/datum/reagent/waste_chemical = /datum/reagent/water /// Cooldown associated with the sound played for collecting mining points. COOLDOWN_DECLARE(sound_cooldown) @@ -75,14 +77,18 @@ /obj/machinery/bouldertech/examine(mob/user) . = ..() - . += span_notice("The machine reads that it has [span_bold("[points_held] mining points")] stored. Swipe an ID to claim them.") - . += span_notice("Click to remove a stored boulder.") + + . += span_suppradio("The machine reads that it has [EXAMINE_HINT("[points_held] mining points")] stored. Swipe an ID to claim them.") var/boulder_count = 0 for(var/obj/item/boulder/potential_boulder in contents) boulder_count += 1 - . += span_notice("Storage capacity = [boulder_count]/[boulders_held_max] boulders.") - . += span_notice("Can process up to [boulders_processing_count] boulders at a time.") + + if(boulder_count >= 1) + . += span_notice("[EXAMINE_HINT("Right Click")] to manually remove a stored boulder.
    ") + + . += span_info("Storage capacity = [boulder_count]/[boulders_held_max] boulders.") + . += span_info("This machine can process up to [EXAMINE_HINT("[boulders_processing_count] boulders")] at a time.") if(anchored) . += span_notice("It's [EXAMINE_HINT("anchored")] in place.") @@ -94,6 +100,16 @@ if(panel_open) . += span_notice("The whole machine can be [EXAMINE_HINT("pried")] apart.") +/obj/machinery/bouldertech/examine_more(mob/user) + . = ..() + + var/list/datum/reagents/booster_list = get_booster_reagents() + if(length(booster_list)) + . += span_notice("This machine's output is boosted by chemical intake:
    ") + for(var/datum/reagent/increment as anything in booster_list) + . += span_info("• [increment::name]: Provides [booster_list[increment] * 10]% Boost") + . += span_notice("
    Upon being boosted successfully, \the [src] will produce [EXAMINE_HINT("[waste_chemical.name]")].") + /obj/machinery/bouldertech/update_icon_state() . = ..() var/suffix = "" @@ -102,7 +118,7 @@ icon_state ="[base_icon_state][suffix]" /obj/machinery/bouldertech/CanAllowThrough(atom/movable/mover, border_dir) - if(!anchored) + if(!anchored || !(dir == border_dir || dir == REVERSE_DIR(border_dir))) return FALSE if(istype(mover, /obj/item/stack/sheet)) return TRUE @@ -235,6 +251,12 @@ refining_efficiency = initial(refining_efficiency) //Reset refining efficiency to 100%. +///Returns a map of reagent -> boost amount to increase this machines efficiency +/obj/machinery/bouldertech/proc/get_booster_reagents() + RETURN_TYPE(/list/datum/reagents) + + return list() + /** * Checks if this machine can process this material * Arguments @@ -338,7 +360,8 @@ //if boulders are kept inside because there is no space to eject them, then they could be reprocessed, lets avoid that if(!chosen_boulder.processed_by) - check_for_boosts() + if(length(reagents.reagent_list)) + check_for_boosts() //Handles the mineral boosting, as well as creating waste. Must have reagents in the machine. //here we loop through the boulder's ores var/list/rejected_mats = list() @@ -347,7 +370,7 @@ if(!can_process_material(possible_mat)) rejected_mats[possible_mat] = quantity continue - points_held = round(points_held + (quantity * possible_mat.points_per_unit * MINING_POINT_MACHINE_MULTIPLIER)) // put point total here into machine + points_held += round(quantity * possible_mat.points_per_boulder_unit) // put point total here into machine if(isnull(silo_materials.silo) || !silo_materials.mat_container.insert_amount_mat(quantity, possible_mat)) new possible_mat.sheet_type(drop_location(), floor(quantity / SHEET_MATERIAL_AMOUNT)) @@ -358,9 +381,9 @@ if(!length(chosen_boulder.custom_materials)) playsound(loc, usage_sound, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) if(istype(chosen_boulder, /obj/item/boulder/artifact)) - points_held = round((points_held + MINER_POINT_MULTIPLIER) * MINING_POINT_MACHINE_MULTIPLIER) /// Artifacts give bonus points! + points_held = round((points_held + MINER_POINT_MULTIPLIER)) /// Artifacts give bonus points! chosen_boulder.break_apart() - return//We've processed all the materials in the boulder, so we can just destroy it in break_apart. + return //We've processed all the materials in the boulder, so we can just destroy it in break_apart. chosen_boulder.processed_by = src @@ -387,7 +410,7 @@ breakdown_boulder(potential_boulder) boulders_found = FALSE - //when the boulder is removed it plays sound and displays a balloon alert. don't overlap when that happens + //when the boulder is removed it plays sound and displays a balloon alert. Don't overlap when that happens if(boulders_found) playsound(loc, usage_sound, 29, FALSE, SHORT_RANGE_SOUND_EXTRARANGE) balloon_alert_to_viewers(action) diff --git a/code/modules/mining/boulder_processing/boulder.dm b/code/modules/mining/boulder_processing/boulder.dm index 08376a2efd3..a7ffa8f3a0b 100644 --- a/code/modules/mining/boulder_processing/boulder.dm +++ b/code/modules/mining/boulder_processing/boulder.dm @@ -34,7 +34,7 @@ register_context() AddComponent(/datum/component/two_handed, require_twohands = TRUE, force_unwielded = 0, force_wielded = 5) //Heavy as all hell, it's a boulder, dude. AddComponent(/datum/component/sisyphus_awarder) - AddElement(/datum/element/bane, mob_biotypes = MOB_SPECIAL, added_damage = 20, requires_combat_mode = FALSE) + AddComponent(/datum/component/bane, affected_biotypes = MOB_SPECIAL, added_damage = 20) /obj/item/boulder/Destroy(force) SSore_generation.available_boulders -= src @@ -110,6 +110,7 @@ return if(HAS_TRAIT(user, TRAIT_BOULDER_BREAKER)) manual_process(null, user, INATE_BOULDER_SPEED_MULTIPLIER) //A little hacky but it works around the speed of the blackboard task selection process for now. + return TRUE /obj/item/boulder/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) . = ..() diff --git a/code/modules/mining/boulder_processing/boulder_types.dm b/code/modules/mining/boulder_processing/boulder_types.dm index ec67648fe2a..1a6979f3885 100644 --- a/code/modules/mining/boulder_processing/boulder_types.dm +++ b/code/modules/mining/boulder_processing/boulder_types.dm @@ -1,3 +1,6 @@ +#define BONUS_MATS_MINIMUM 1 +#define BONUS_MATS_MAXIMUM 5 + ///Boulders with special artificats that can give higher mining points /obj/item/boulder/artifact name = "artifact boulder" @@ -7,10 +10,14 @@ var/artifact_type = /obj/item/relic/lavaland /// References to the relic inside the boulder, if any. var/obj/item/artifact_inside + /// Bonus materials to add to this boulder, in addition to existing materials created by the ore vent. + var/datum/material/bonus_mat /obj/item/boulder/artifact/Initialize(mapload) . = ..() artifact_inside = new artifact_type(src) /// This could be poggers for archaeology in the future. + if(bonus_mat) + add_bonus_mats() /obj/item/boulder/artifact/Destroy(force) QDEL_NULL(artifact_inside) @@ -27,7 +34,24 @@ /obj/item/boulder/artifact/update_icon_state() . = ..() - icon_state = "boulder_artifact" // Hardset to artifact sprites for consistency + icon_state = initial(icon_state) // Hardset to artifact sprites for consistency + +/// Adds a random amount of material to an artifact boulder, determined by BONUS_MAT defines and of the type bonus_mat defined on the boulder. +/obj/item/boulder/artifact/proc/add_bonus_mats() + var/list/bonus_mats = list() + if(custom_materials) + bonus_mats = custom_materials.Copy() + bonus_mats[bonus_mat] += rand(BONUS_MATS_MINIMUM, BONUS_MATS_MAXIMUM) * SHEET_MATERIAL_AMOUNT + set_custom_materials(bonus_mats) + + +/obj/item/boulder/artifact/bluespace + icon_state = "boulder_artifact_BS" + bonus_mat = /datum/material/bluespace + +/obj/item/boulder/artifact/diamond + icon_state = "boulder_artifact_diamond" + bonus_mat = /datum/material/diamond ///Boulders usually spawned in lavaland labour camp area /obj/item/boulder/gulag @@ -77,3 +101,6 @@ desc = "A bizarre, twisted boulder. Wait, wait no, it's just a rock." custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 1.1, /datum/material/glass = SHEET_MATERIAL_AMOUNT * 1.1) durability = 1 + +#undef BONUS_MATS_MINIMUM +#undef BONUS_MATS_MAXIMUM diff --git a/code/modules/mining/boulder_processing/refinery.dm b/code/modules/mining/boulder_processing/refinery.dm index 861829219e2..f65669d3b40 100644 --- a/code/modules/mining/boulder_processing/refinery.dm +++ b/code/modules/mining/boulder_processing/refinery.dm @@ -5,12 +5,40 @@ */ /obj/machinery/bouldertech/refinery name = "boulder refinery" - desc = "BR for short. Accepts boulders and refines non-metallic ores into sheets using internal chemicals." + desc = "Accepts boulders and refines non-metallic ores into sheets using internal chemicals." icon_state = "stacker" base_icon_state = "stacker" circuit = /obj/item/circuitboard/machine/refinery usage_sound = 'sound/machines/mining/refinery.ogg' action = "crushing" + waste_chemical = /datum/reagent/toxin/acid/industrial_waste + pixel_y = 1 + +/obj/machinery/bouldertech/refinery/Initialize(mapload) + . = ..() + AddComponent(/datum/component/plumbing/boulder_reactions) + AddElement(/datum/element/simple_rotation) + update_appearance(UPDATE_OVERLAYS) + +/obj/machinery/bouldertech/refinery/update_icon_state() + . = ..() + set_light_on(anchored && is_operational && !panel_open) + +/obj/machinery/bouldertech/refinery/create_reagents(max_vol, flags) + QDEL_NULL(reagents) + reagents = new /datum/reagents/plumbing(max_vol, flags) + reagents.my_atom = src + +/obj/machinery/bouldertech/refinery/get_booster_reagents() + var/static/list/booster_reagents + if(!length(booster_reagents)) + booster_reagents = list( + /datum/reagent/toxin/acid = 1, + /datum/reagent/toxin/acid/fluacid = 2, + /datum/reagent/toxin/acid/nitracid = 3, + /datum/reagent/teslium = 5, + ) + return booster_reagents /obj/machinery/bouldertech/refinery/can_process_material(datum/material/possible_mat) var/static/list/processable_materials @@ -37,6 +65,43 @@ boulders_processing_count += servo.tier boulders_processing_count = ROUND_UP((boulders_processing_count / 8) * boulders_held_max) + var/new_volume = 0 + for(var/obj/item/reagent_containers/beaker in component_parts) + new_volume += beaker.volume + if(!reagents) + create_reagents(new_volume, OPENCONTAINER) + reagents.maximum_volume = new_volume + + +/obj/machinery/bouldertech/refinery/check_for_boosts() + . = ..() //resets to 1.00 efficiency in the parent + + var/highest_boost = 0 + var/datum/reagent/biggest_booster + var/list/datum/reagents/booster_list = get_booster_reagents() + for(var/datum/reagent/booster as anything in booster_list) + var/booster_volume = booster_list[booster] + if(!reagents.has_reagent(booster, booster_volume)) //check that we have the associated quantity of the chem in order to perform the boost. + continue + if(booster_list[booster] > highest_boost) + highest_boost = booster_volume + biggest_booster = booster + + if(!biggest_booster) + return + + reagents.remove_reagent(biggest_booster, highest_boost) //remove the associated amount from the reagents + refining_efficiency = 1 + (highest_boost / 10) //Results in a boost from 10-30% + reagents.add_reagent(waste_chemical, highest_boost) + +/obj/machinery/bouldertech/refinery/plunger_act(obj/item/plunger/attacking_plunger, mob/living/user, reinforced) + . = ..() + balloon_alert(user, "emptying...") + if(do_after(user, 2 SECONDS, src)) + reagents.expose(drop_location()) + reagents.clear_reagents() + + /** * Your other new favorite industrial waste magnet! * Accepts boulders and produces sheets of metallic materials. @@ -44,7 +109,7 @@ */ /obj/machinery/bouldertech/refinery/smelter name = "boulder smelter" - desc = "BS for short. Accept boulders and refines metallic ores into sheets." + desc = "Accept boulders and refines metallic ores into sheets." icon_state = "smelter" base_icon_state = "smelter" light_system = OVERLAY_LIGHT @@ -54,11 +119,24 @@ circuit = /obj/item/circuitboard/machine/smelter usage_sound = 'sound/machines/mining/smelter.ogg' action = "smelting" + pixel_x = -1 /obj/machinery/bouldertech/refinery/smelter/Initialize(mapload) . = ..() update_light_value() + +/obj/machinery/bouldertech/refinery/smelter/get_booster_reagents() + var/static/list/booster_reagents + if(!length(booster_reagents)) + booster_reagents = list( + /datum/reagent/fuel = 1, + /datum/reagent/thermite = 2, + /datum/reagent/gunpowder = 3, + /datum/reagent/liquid_dark_matter = 5, + ) + return booster_reagents + /obj/machinery/bouldertech/refinery/smelter/can_process_material(datum/material/possible_mat) var/static/list/processable_materials if(!length(processable_materials)) diff --git a/code/modules/mining/equipment/kinetic_crusher/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher/kinetic_crusher.dm index 55533341d89..9f72047fcde 100644 --- a/code/modules/mining/equipment/kinetic_crusher/kinetic_crusher.dm +++ b/code/modules/mining/equipment/kinetic_crusher/kinetic_crusher.dm @@ -218,7 +218,7 @@ var/backstabbed = FALSE var/def_check = target.getarmor(type = BOMB) // Backstab bonus - if(check_behind(user, target) || boosted_mark) + if(check_behind(user, target) && !HAS_TRAIT(target, TRAIT_BACKSTAB_IMMUNE) || boosted_mark) backstabbed = TRUE combined_damage += backstab_bonus playsound(user, backstab_sound, 100, TRUE) //Seriously who spelled it wrong @@ -336,6 +336,9 @@ fired_from = null return ..() +/obj/projectile/destabilizer/is_hostile_projectile() + return TRUE + /obj/projectile/destabilizer/proc/on_parry(mob/user) SIGNAL_HANDLER boosted = TRUE diff --git a/code/modules/mining/equipment/kinetic_crusher/trophies_fauna.dm b/code/modules/mining/equipment/kinetic_crusher/trophies_fauna.dm index 9b6b6561aff..dfa4cf8e502 100644 --- a/code/modules/mining/equipment/kinetic_crusher/trophies_fauna.dm +++ b/code/modules/mining/equipment/kinetic_crusher/trophies_fauna.dm @@ -144,7 +144,7 @@ // Bileworm /obj/item/crusher_trophy/bileworm_spewlet name = "bileworm spewlet" - icon = 'icons/mob/simple/lavaland/bileworm.dmi' + icon = 'icons/obj/mining_zones/artefacts.dmi' icon_state = "bileworm_spewlet" desc = "A baby bileworm. Suitable as a trophy for a kinetic crusher." denied_type = /obj/item/crusher_trophy/bileworm_spewlet @@ -179,7 +179,7 @@ /obj/item/crusher_trophy/bileworm_spewlet/on_projectile_hit_mineral(turf/closed/mineral, mob/living/user) for(var/turf/closed/mineral/mineral_turf in RANGE_TURFS(1, mineral) - mineral) - mineral_turf.gets_drilled(user, 1) + mineral_turf.drill_aoe(user, 0.2) //yes this is a /mob_cooldown subtype being added to an item. I can't recommend you do what I'm doing /datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/spewlet diff --git a/code/modules/mining/equipment/mineral_scanner.dm b/code/modules/mining/equipment/mineral_scanner.dm index 8d763fd2f67..93b0a26a3df 100644 --- a/code/modules/mining/equipment/mineral_scanner.dm +++ b/code/modules/mining/equipment/mineral_scanner.dm @@ -27,10 +27,10 @@ /obj/item/mining_scanner/admin /obj/item/mining_scanner/admin/attack_self(mob/user) - for(var/turf/closed/mineral/mineral_turf in world) - if(mineral_turf.scan_state) - mineral_turf.icon = mineral_turf.scan_icon - mineral_turf.icon_state = mineral_turf.scan_state + for(var/turf/closed/mineral/rock in world) + if(rock.scan_state) + var/mutable_appearance/rock_overlay = mutable_appearance(rock.scan_icon, rock.scan_state, FLASH_LAYER, rock, ABOVE_LIGHTING_PLANE, appearance_flags = RESET_TRANSFORM) + rock.add_overlay(rock_overlay) qdel(src) /obj/item/t_scanner/adv_mining_scanner @@ -86,19 +86,8 @@ vent.add_mineral_overlays() for(var/turf/closed/mineral/mineral in RANGE_TURFS(range, start_turf)) - if(!mineral.scan_state) - continue - - var/obj/effect/temp_visual/mining_overlay/scan_overlay = locate(/obj/effect/temp_visual/mining_overlay) in mineral - if(!scan_overlay) - scan_overlay = new(mineral) - scan_overlay.icon = mineral.scan_icon - scan_overlay.icon_state = mineral.scan_state - continue - - deltimer(scan_overlay.timerid) - scan_overlay.timerid = QDEL_IN_STOPPABLE(scan_overlay, scan_overlay.duration) - animate(scan_overlay, alpha = 0, time = scan_overlay.duration, easing = scan_overlay.easing_style) + if(mineral.scan_state) + mineral.flash_scan() if(vents_nearby && scanner) if(undiscovered) @@ -111,7 +100,8 @@ /obj/effect/temp_visual/mining_overlay plane = HIGH_GAME_PLANE layer = FLASH_LAYER - icon = 'icons/effects/ore_visuals.dmi' + icon = 'icons/blanks/480x480.dmi' + icon_state = "nothing" appearance_flags = NONE // to avoid having TILE_BOUND in the flags, so that the 480x480 icon states let you see it no matter where you are duration = 3.5 SECONDS pixel_x = -224 diff --git a/code/modules/mining/equipment/mining_tools.dm b/code/modules/mining/equipment/mining_tools.dm index 73ebdf10a71..d16be7e4b4c 100644 --- a/code/modules/mining/equipment/mining_tools.dm +++ b/code/modules/mining/equipment/mining_tools.dm @@ -185,7 +185,7 @@ /obj/item/shovel/serrated/Initialize(mapload) . = ..() - AddElement(/datum/element/bane, mob_biotypes = MOB_ORGANIC, damage_multiplier = 1) //You may be horridly cursed now, but at least you kill the living a whole lot more easily! + AddComponent(/datum/component/bane, affected_biotypes = MOB_ORGANIC, damage_multiplier = 2) //You may be horridly cursed now, but at least you kill the living a whole lot more easily! /obj/item/shovel/serrated/examine(mob/user) . = ..() diff --git a/code/modules/mining/equipment/monster_organs/rush_gland.dm b/code/modules/mining/equipment/monster_organs/rush_gland.dm index 894a9dbe0db..f22bf029a8c 100644 --- a/code/modules/mining/equipment/monster_organs/rush_gland.dm +++ b/code/modules/mining/equipment/monster_organs/rush_gland.dm @@ -24,6 +24,7 @@ /obj/item/organ/monster_core/rush_gland/on_mob_insert(mob/living/carbon/organ_owner) . = ..() RegisterSignal(organ_owner, COMSIG_GOLIATH_TENTACLED_GRABBED, PROC_REF(trigger_organ_action_on_sig)) + RegisterSignal(organ_owner, COMSIG_TENDRIL_TENTACLED_GRABBED, PROC_REF(trigger_organ_action_on_sig)) /obj/item/organ/monster_core/rush_gland/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) . = ..() @@ -34,7 +35,9 @@ /obj/item/organ/monster_core/rush_gland/proc/trigger_organ_action_on_sig(datum/source) SIGNAL_HANDLER + INVOKE_ASYNC(src, PROC_REF(trigger_organ_action)) + return COMPONENT_GOLIATH_CANCEL_TENTACLE_GRAB /** * Status effect: Makes you run faster and ignore damage speed penalties for a short duration. diff --git a/code/modules/mining/equipment/resonator.dm b/code/modules/mining/equipment/resonator.dm index 8c5ffb873a7..dcd980e71cd 100644 --- a/code/modules/mining/equipment/resonator.dm +++ b/code/modules/mining/equipment/resonator.dm @@ -131,8 +131,9 @@ SEND_SIGNAL(creator, COMSIG_LIVING_RESONATOR_BURST, creator, attacked_living) to_chat(attacked_living, span_userdanger("[src] ruptured with you in it!")) attacked_living.apply_damage(resonance_damage, BRUTE) - attacked_living.add_movespeed_modifier(/datum/movespeed_modifier/resonance) - addtimer(CALLBACK(attacked_living, TYPE_PROC_REF(/mob, remove_movespeed_modifier), /datum/movespeed_modifier/resonance), 10 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE) + if(!QDELETED(attacked_living)) + attacked_living.add_movespeed_modifier(/datum/movespeed_modifier/resonance) + addtimer(CALLBACK(attacked_living, TYPE_PROC_REF(/mob, remove_movespeed_modifier), /datum/movespeed_modifier/resonance), 10 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE) for(var/obj/effect/temp_visual/resonance/field in orange(1, src)) if(field.rupturing) continue diff --git a/code/modules/mining/equipment/survival_pod.dm b/code/modules/mining/equipment/survival_pod.dm index 7ba37130ebc..1f31fbb6053 100644 --- a/code/modules/mining/equipment/survival_pod.dm +++ b/code/modules/mining/equipment/survival_pod.dm @@ -267,20 +267,12 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/door/window/survival_pod/left, 0) max_n_of_items = 10 pixel_y = -4 -/obj/machinery/smartfridge/survival_pod/welder_act(mob/living/user, obj/item/tool) - return NONE - -/obj/machinery/smartfridge/survival_pod/wrench_act(mob/living/user, obj/item/tool) - return NONE - -/obj/machinery/smartfridge/survival_pod/screwdriver_act(mob/living/user, obj/item/tool) - return NONE - -/obj/machinery/smartfridge/survival_pod/crowbar_act(mob/living/user, obj/item/tool) - return NONE - /obj/machinery/smartfridge/survival_pod/Initialize(mapload) AddElement(/datum/element/update_icon_blocker) + AddElement(/datum/element/tool_blocker, TOOL_WELDER, TOOL_ACT_PRIMARY) + AddElement(/datum/element/tool_blocker, TOOL_SCREWDRIVER, TOOL_ACT_PRIMARY) + AddElement(/datum/element/tool_blocker, TOOL_WRENCH, TOOL_ACT_PRIMARY) + AddElement(/datum/element/tool_blocker, TOOL_CROWBAR, TOOL_ACT_PRIMARY) return ..() /obj/machinery/smartfridge/survival_pod/preloaded/Initialize(mapload) diff --git a/code/modules/mining/fulton.dm b/code/modules/mining/fulton.dm index 8738752af33..e75e36e55fa 100644 --- a/code/modules/mining/fulton.dm +++ b/code/modules/mining/fulton.dm @@ -96,6 +96,10 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons) if(!do_after(user, 5 SECONDS, target = thing)) return ITEM_INTERACT_BLOCKING + if(QDELETED(beacon)) + balloon_alert(user, "beacon lost!") + return ITEM_INTERACT_BLOCKING + balloon_alert_to_viewers("extracting!") if(loc == user && ishuman(user)) var/mob/living/carbon/human/human_user = user @@ -125,6 +129,7 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons) return ITEM_INTERACT_SUCCESS /obj/item/extraction_pack/proc/create_balloon(atom/movable/thing, mob/living/user, obj/effect/extraction_holder/holder_obj, mutable_appearance/balloon2) + var/turf/beacon_turf = get_turf(beacon_ref.resolve()) var/mutable_appearance/balloon = mutable_appearance('icons/effects/fulton_balloon.dmi', "fulton_balloon", layer = VEHICLE_LAYER, appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM | KEEP_APART) balloon.pixel_z = 10 holder_obj.cut_overlay(balloon2) @@ -151,7 +156,6 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons) sleep(3 SECONDS) var/turf/flooring_near_beacon = list() - var/turf/beacon_turf = get_turf(beacon_ref.resolve()) for(var/turf/floor as anything in RANGE_TURFS(1, beacon_turf)) if(!floor.is_blocked_turf()) flooring_near_beacon += floor diff --git a/code/modules/mining/laborcamp/laborstacker.dm b/code/modules/mining/laborcamp/laborstacker.dm index 2478b84b7f7..170baf58a3d 100644 --- a/code/modules/mining/laborcamp/laborstacker.dm +++ b/code/modules/mining/laborcamp/laborstacker.dm @@ -29,7 +29,8 @@ /obj/machinery/mineral/labor_claim_console/proc/register_shuttle_signal() SIGNAL_HANDLER var/obj/docking_port/mobile/laborshuttle = SSshuttle.getShuttle("laborcamp") - RegisterSignal(laborshuttle, COMSIG_SHUTTLE_SHOULD_MOVE, PROC_REF(on_laborshuttle_can_move)) + if(laborshuttle) + RegisterSignal(laborshuttle, COMSIG_SHUTTLE_SHOULD_MOVE, PROC_REF(on_laborshuttle_can_move)) UnregisterSignal(SSshuttle, COMSIG_SUBSYSTEM_POST_INITIALIZE) /obj/machinery/mineral/labor_claim_console/Destroy() @@ -77,6 +78,11 @@ data["can_go_home"] = can_go_home return data +/obj/machinery/mineral/labor_claim_console/ui_static_data(mob/user) + var/list/data = list() + data["shuttle_exists"] = !isnull(SSshuttle.getShuttle("laborcamp")) + return data + /obj/machinery/mineral/labor_claim_console/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) . = ..() if(.) @@ -103,6 +109,12 @@ COOLDOWN_START(src, say_cooldown, 2 SECONDS) if("move_shuttle") + if(isnull(SSshuttle.getShuttle("laborcamp"))) + if(COOLDOWN_FINISHED(src, say_cooldown)) + say("Shuttle not found.") + COOLDOWN_START(src, say_cooldown, 2 SECONDS) + return + var/list/labor_shuttle_mobs = find_labor_shuttle_mobs() if(length(labor_shuttle_mobs) > 1 || labor_shuttle_mobs[1] != user_mob) if(COOLDOWN_FINISHED(src, say_cooldown)) @@ -171,6 +183,7 @@ /**********************Prisoner Collection Unit**************************/ /obj/machinery/mineral/stacking_machine/laborstacker + name = "labor camp collection unit" force_connect = TRUE damage_deflection = 21 //otherwise prisoners will destroy it ///Idle points sitting in the machine left to be claimed. diff --git a/code/modules/mining/lavaland/ash_flora.dm b/code/modules/mining/lavaland/ash_flora.dm index 778b2be395d..87279ec4c8d 100644 --- a/code/modules/mining/lavaland/ash_flora.dm +++ b/code/modules/mining/lavaland/ash_flora.dm @@ -40,7 +40,7 @@ icon_state = base_icon_state /obj/structure/flora/ash/tall_shroom //exists only so that the spawning check doesn't allow these spawning near other things - regrowth_time_low = 4200 + regrowth_time_low = 7 MINUTES /obj/structure/flora/ash/leaf_shroom name = "leafy mushrooms" @@ -54,8 +54,8 @@ harvest_message_med = "You pluck a number of leaves, leaving a few unsuitable ones." harvest_message_high = "You pluck quite a lot of suitable leaves." harvest_time = 20 - regrowth_time_low = 2400 - regrowth_time_high = 6000 + regrowth_time_low = 4 MINUTES + regrowth_time_high = 10 MINUTES /obj/structure/flora/ash/leaf_shroom/get_potential_products() return list(/obj/item/food/grown/ash_flora/mushroom_leaf = 1) @@ -72,8 +72,8 @@ harvest_message_med = "You slice off a few conks from the larger mushrooms." harvest_message_high = "You slice off a number of caps and conks from these mushrooms." harvest_time = 50 - regrowth_time_low = 3000 - regrowth_time_high = 5400 + regrowth_time_low = 5 MINUTES + regrowth_time_high = 9 MINUTES /obj/structure/flora/ash/cap_shroom/get_potential_products() return list(/obj/item/food/grown/ash_flora/mushroom_cap = 1) @@ -92,8 +92,8 @@ harvest_message_med = "You pick and decapitate several mushrooms for their stems." harvest_message_high = "You acquire a number of stems from these mushrooms." harvest_time = 40 - regrowth_time_low = 3000 - regrowth_time_high = 6000 + regrowth_time_low = 5 MINUTES + regrowth_time_high = 10 MINUTES /obj/structure/flora/ash/stem_shroom/get_potential_products() return list(/obj/item/food/grown/ash_flora/mushroom_stem = 1) @@ -110,8 +110,8 @@ harvest_message_med = "You pick several cactus fruit." //shouldn't show up, because you can't get more than two harvest_message_high = "You pick a pair of cactus fruit." harvest_time = 10 - regrowth_time_low = 4800 - regrowth_time_high = 7200 + regrowth_time_low = 8 MINUTES + regrowth_time_high = 12 MINUTES can_uproot = FALSE //Don't want 50 in one tile to decimate whoever dare step on the mass of cacti /obj/structure/flora/ash/cacti/Initialize(mapload) @@ -133,8 +133,8 @@ harvest_message_med = "You grab a good haul of mushrooms." harvest_message_high = "You hit the mushroom motherlode and make off with a bunch of tasty mushrooms." harvest_time = 25 - regrowth_time_low = 3000 - regrowth_time_high = 5400 + regrowth_time_low = 5 MINUTES + regrowth_time_high = 9 MINUTES number_of_variants = 2 harvest_message_true_thresholds = FALSE @@ -155,8 +155,8 @@ harvest_message_low = "You pluck a single, suitable flower." harvest_message_med = "You pluck a number of flowers, leaving a few unsuitable ones." harvest_message_high = "You pluck quite a lot of suitable flowers." - regrowth_time_low = 2500 - regrowth_time_high = 4000 + regrowth_time_low = 4 MINUTES + regrowth_time_high = 7 MINUTES number_of_variants = 2 /obj/structure/flora/ash/fireblossom/get_potential_products() @@ -174,6 +174,50 @@ update_light() return ..() +/obj/structure/flora/ash/glowgrowth + name = "glowgrowth colony" + desc = "A colony of bioluminescent fungi growing on a hot air vent, feeding off mineral particulate blowing through it." + icon_state = "glowgrowth1" + base_icon_state = "glowgrowth" + density = TRUE // Large rock formations with plants ontop + light_range = 1.7 + light_power = 1.2 + light_color = "#67b6a5" + harvested_name = "hot air vent" + harvested_desc = "A ridged porous rock formation exuming hot air from the depths of the planet." + harvest_amount_high = 4 + harvest_verb = "scrape" + harvest_message_low = "You scrape off a thin layer of glowing fungi." + harvest_message_med = "You pick a sizeable patch of glowing fungi." + harvest_message_high = "You grab a large fistful of glowing fungi." + regrowth_time_low = 8 MINUTES + regrowth_time_high = 16 MINUTES + number_of_variants = 3 + +/obj/structure/flora/ash/glowgrowth/Initialize(mapload) + . = ..() + update_appearance() + +/obj/structure/flora/ash/glowgrowth/get_potential_products() + return list(/obj/item/food/grown/ash_flora/glowgrowth = 1) + +/obj/structure/flora/ash/glowgrowth/after_harvest() + set_light_on(FALSE) + update_light() + update_appearance() + return ..() + +/obj/structure/flora/ash/glowgrowth/regrow() + set_light_on(TRUE) + update_light() + update_appearance() + return ..() + +/obj/structure/flora/ash/glowgrowth/update_overlays() + . = ..() + if (!harvested) + . += emissive_appearance(icon, "[icon_state]e", src, alpha = 120) + ///Snow flora to exist on icebox. /obj/structure/flora/ash/chilly name = "springy grassy fruit" @@ -283,6 +327,13 @@ // Fire flowers make fireproof raptors AddElement(/datum/element/raptor_food, color_chances = string_list(list(/datum/raptor_color/blue = 5))) +/obj/item/food/grown/ash_flora/glowgrowth + name = "glowgrowth sheet" + desc = "A thick sheet of glowing fungi." + icon_state = "glowgrowth" + seed = /obj/item/seeds/lavaland/glowgrowth // Cannot be grown in hydroponics as it feeds off mineral air + wine_power = 50 + // SEEDS /obj/item/seeds/lavaland @@ -410,6 +461,17 @@ growing_icon = 'icons/obj/service/hydroponics/growing_flowers.dmi' reagents_add = list(/datum/reagent/consumable/tinlux = 0.04, /datum/reagent/consumable/nutriment = 0.03, /datum/reagent/carbon = 0.05) +/obj/item/seeds/lavaland/glowgrowth + name = "glowgrowth mycelium pack" + desc = "This mycelium grows into glowgrowth fungi." + plantname = "Glowgrowth Fungi" + icon_state = "mycelium-glowgrowth" + species = "glowgrowth" + product = /obj/item/food/grown/ash_flora/glowgrowth + genes = list(/datum/plant_gene/trait/plant_type/fungal_metabolism, /datum/plant_gene/trait/fire_resistance, /datum/plant_gene/trait/glow/blue) // Fungal metab doesn't do anything (cause it can't be planted) but it shows up in analyzers + reagents_add = list(/datum/reagent/luminescent_fluid/cyan = 0.06, /datum/reagent/consumable/nutriment = 0.01, /datum/reagent/silicon = 0.03) + seed_flags = parent_type::seed_flags | NO_PLANTING + //CRAFTING /datum/crafting_recipe/mushroom_bowl @@ -423,12 +485,9 @@ name = "mushroom bowl" desc = "A bowl made out of mushrooms. Not food, though it might have contained some at some point." icon = 'icons/obj/mining_zones/ash_flora.dmi' + base_icon_state = "mushroom_bowl" icon_state = "mushroom_bowl" fill_icon_state = "fullbowl" fill_icon = 'icons/obj/mining_zones/ash_flora.dmi' custom_materials = null -/obj/item/reagent_containers/cup/bowl/mushroom_bowl/update_icon_state() - if(!reagents.total_volume) - icon_state = "mushroom_bowl" - return ..() diff --git a/code/modules/mining/lavaland/mining_loot/megafauna/colossus.dm b/code/modules/mining/lavaland/mining_loot/megafauna/colossus.dm index a5c24eabb95..f130cd891e5 100644 --- a/code/modules/mining/lavaland/mining_loot/megafauna/colossus.dm +++ b/code/modules/mining/lavaland/mining_loot/megafauna/colossus.dm @@ -383,7 +383,6 @@ possessor.mind.transfer_to(holder_animal) var/datum/action/exit_possession/escape = new(holder_animal) escape.Grant(holder_animal) - remove_verb(holder_animal, /mob/living/verb/pulled) /obj/structure/closet/stasis/dump_contents(kill = TRUE) for(var/mob/living/possessor in src) diff --git a/code/modules/mining/lavaland/mining_loot/megafauna/hierophant.dm b/code/modules/mining/lavaland/mining_loot/megafauna/hierophant.dm index 520502aaf30..38f51568544 100644 --- a/code/modules/mining/lavaland/mining_loot/megafauna/hierophant.dm +++ b/code/modules/mining/lavaland/mining_loot/megafauna/hierophant.dm @@ -2,9 +2,9 @@ /obj/item/hierophant_club name = "hierophant club" - desc = "The strange technology of this large club allows various nigh-magical teleportation feats. It used to beat you, but now you can set the beat." - icon_state = "hierophant_club_ready_beacon" - inhand_icon_state = "hierophant_club_ready_beacon" + desc = "The shriveled remains of the Hierophant hold some remnant of its power. It used it to beat you, but now you can set the beat." + icon_state = "hierophant_club" + inhand_icon_state = "hierophant_club" icon_angle = -135 icon = 'icons/obj/mining_zones/artefacts.dmi' lefthand_file = 'icons/mob/inhands/64x64_lefthand.dmi' @@ -33,6 +33,9 @@ . = ..() AddElement(/datum/element/update_icon_updates_onmob) blink = new(src) + update_appearance(UPDATE_OVERLAYS) + + RegisterSignals(blink, list(COMSIG_DASH_ACTION_CHARGED, COMSIG_DASH_ACTION_DASHED), PROC_REF(on_action_updated)) /obj/item/hierophant_club/Destroy(force) QDEL_NULL(blink) @@ -91,9 +94,23 @@ return ITEM_INTERACT_SUCCESS return NONE -/obj/item/hierophant_club/update_icon_state() - icon_state = inhand_icon_state = "hierophant_club[blink?.current_charges > 0 ? "_ready" : ""][!QDELETED(beacon) ? "" : "_beacon"]" - return ..() +/// When dash action is used or recharges, update icon state +/obj/item/hierophant_club/proc/on_action_updated() + SIGNAL_HANDLER + update_appearance(UPDATE_OVERLAYS) + +/obj/item/hierophant_club/update_overlays() + . = ..() + if (QDELETED(beacon)) + . += "hierophant_beacon" + if (blink?.current_charges) + . += "hierophant_ready" + +/obj/item/hierophant_club/worn_overlays(mutable_appearance/standing, isinhands, icon_file) + . = ..() + if (blink?.current_charges) + . += "hierophant_ready" + /obj/item/hierophant_club/ui_action_click(mob/user, action) if (teleporting) @@ -212,7 +229,7 @@ user.update_mob_action_buttons() user.visible_message(span_hierophant_warning("[user] places a strange machine beneath [user.p_their()] feet!"), span_hierophant("You detach the hierophant beacon, allowing you to teleport yourself and any allies to it at any time!")) to_chat(user, span_hierophant("You can remove the beacon to place it again by striking it with the club.")) - update_appearance(UPDATE_ICON_STATE) + update_appearance(UPDATE_OVERLAYS) /obj/item/hierophant_club/proc/beacon_destroyed(datum/source) SIGNAL_HANDLER @@ -222,7 +239,7 @@ else visible_message(span_hierophant("With a loud snap, a new beacon appears at [src]'s pommel.")) playsound(src, 'sound/effects/magic/blind.ogg', 50, TRUE, -4) - update_appearance(UPDATE_ICON_STATE) + update_appearance(UPDATE_OVERLAYS) #define HIEROPHANT_BLINK_RANGE 5 #define HIEROPHANT_BLINK_COOLDOWN (15 SECONDS) @@ -240,14 +257,10 @@ /datum/action/innate/dash/hierophant/teleport(mob/user, atom/target) var/dist = get_dist(user, target) if(dist > HIEROPHANT_BLINK_RANGE) - user.balloon_alert(user, "destination out of range!") + user.balloon_alert(user, "too far!") return FALSE - . = ..() - - var/obj/item/hierophant_club/club = target - if(!istype(club)) - club.update_appearance(UPDATE_ICON_STATE) + return ..() /datum/action/innate/dash/hierophant/charge() . = ..() diff --git a/code/modules/mining/lavaland/mining_loot/megafauna/legion.dm b/code/modules/mining/lavaland/mining_loot/megafauna/legion.dm index cb8fa553271..4ec0dbfe49e 100644 --- a/code/modules/mining/lavaland/mining_loot/megafauna/legion.dm +++ b/code/modules/mining/lavaland/mining_loot/megafauna/legion.dm @@ -95,7 +95,7 @@ playsound(src, 'sound/effects/magic/lightningshock.ogg', 10, TRUE, extrarange = SILENCED_SOUND_EXTRARANGE, falloff_distance = 0) targeted_turfs += target_turf balloon_alert(user, "you aim at [target_turf]...") - new /obj/effect/temp_visual/telegraphing/thunderbolt(target_turf) + new /obj/effect/temp_visual/telegraphing/circle(target_turf) addtimer(CALLBACK(src, PROC_REF(throw_thunderbolt), target_turf, power_boosted), 1.5 SECONDS) thunder_charges-- addtimer(CALLBACK(src, PROC_REF(recharge)), thunder_charge_time) diff --git a/code/modules/mining/machine_silo.dm b/code/modules/mining/machine_silo.dm index d35002d32f5..deb61dca16b 100644 --- a/code/modules/mining/machine_silo.dm +++ b/code/modules/mining/machine_silo.dm @@ -564,7 +564,7 @@ var/alist/user_data /datum/ore_silo_log/New(obj/machinery/M, _action, _amount, _noun, list/mats=list(), alist/user_data) - timestamp = station_time_timestamp() + timestamp = round_timestamp() machine_name = M.name area_name = get_area_name(M, TRUE) action = _action diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm index 3b8d40d66d6..8f965844558 100644 --- a/code/modules/mining/ores_coins.dm +++ b/code/modules/mining/ores_coins.dm @@ -10,16 +10,29 @@ full_w_class = WEIGHT_CLASS_BULKY singular_name = "ore chunk" material_flags = MATERIAL_EFFECTS - var/points = 0 //How many points this ore gets you from the ore redemption machine - var/refined_type = null //What this ore defaults to being refined into - var/mine_experience = 5 //How much experience do you get for mining this ore? novariants = TRUE // Ore stacks handle their icon updates themselves to keep the illusion that there's more going - var/list/stack_overlays - var/scan_state = "" //Used by mineral turfs for their scan overlay. - var/spreadChance = 0 //Also used by mineral turfs for spreading veins drop_sound = SFX_STONE_DROP pickup_sound = SFX_STONE_PICKUP sound_vary = TRUE + /// How many points this ore gets you from the ore redemption machine + var/points = 0 + /// What this ore defaults to being refined into + var/refined_type = null + /// How much experience do you get for mining this ore? + var/mine_experience = 5 + var/list/stack_overlays + /// Used by mineral turfs for their scan overlay. + var/scan_state = "" + /// Chance that we'll spawn as a vein rather than a sole tile + var/spread_chance = 0 + /// Type of ore vein we spawn, cluster/scatter/plain/branching + var/vein_type = ORE_VEIN_CLUSTER + /// Optimal distance from open turfs for us to spawn, 1 is next to an open tile + var/vein_distance = 1 + /// Minimum distance that a vein can span, radius for cluster/scatter, maximum length for plain/branching + var/min_vein_size = 1 + /// Minimum distance that a vein can span, radius for cluster/scatter, maximum length for plain/branching + var/max_vein_size = 2 /obj/item/stack/ore/update_overlays() . = ..() @@ -52,29 +65,29 @@ return isnull(refined_type) ? null : src /obj/item/stack/ore/welder_act(mob/living/user, obj/item/I) - ..() + . = ..() if(!refined_type) return TRUE - if(I.use_tool(src, user, 0, volume=50)) - new refined_type(drop_location()) - use(1) + if(!I.use_tool(src, user, 0, volume = 50)) + return TRUE + var/sheets_made = values_sum(mats_per_unit) / SHEET_MATERIAL_AMOUNT + new refined_type(drop_location(), max(1, floor(sheets_made))) + use(max(1, ceil(1 / sheets_made))) return TRUE /obj/item/stack/ore/fire_act(exposed_temperature, exposed_volume) . = ..() if(isnull(refined_type)) return - else - var/probability = (rand(0,100))/100 - var/burn_value = probability*amount - var/amountrefined = round(burn_value, 1) - if(amountrefined < 1) - qdel(src) - else - new refined_type(drop_location(),amountrefined) - qdel(src) + + var/probability = rand(0, 100) / 100 + var/burn_value = probability * amount + var/amount_refined = floor(burn_value * values_sum(mats_per_unit) / SHEET_MATERIAL_AMOUNT) + if(amount_refined > 1) + new refined_type(drop_location(), amount_refined) + qdel(src) /obj/item/stack/ore/uranium name = "uranium ore" @@ -82,24 +95,30 @@ singular_name = "uranium ore chunk" points = 30 material_flags = NONE - mats_per_unit = list(/datum/material/uranium=SHEET_MATERIAL_AMOUNT) + mats_per_unit = list(/datum/material/uranium = SHEET_MATERIAL_AMOUNT) refined_type = /obj/item/stack/sheet/mineral/uranium mine_experience = 6 scan_state = "rock_uranium" - spreadChance = 5 + spread_chance = 35 merge_type = /obj/item/stack/ore/uranium + vein_type = ORE_VEIN_PLAIN + vein_distance = 3 + min_vein_size = 1 + max_vein_size = 3 /obj/item/stack/ore/iron name = "iron ore" icon_state = "iron" singular_name = "iron ore chunk" points = 1 - mats_per_unit = list(/datum/material/iron=SHEET_MATERIAL_AMOUNT) + mats_per_unit = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT) refined_type = /obj/item/stack/sheet/iron mine_experience = 1 scan_state = "rock_iron" - spreadChance = 20 + spread_chance = 65 merge_type = /obj/item/stack/ore/iron + min_vein_size = 1 + max_vein_size = 3 /obj/item/stack/ore/glass name = "sand pile" @@ -142,7 +161,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ C.visible_message(span_danger("[C]'s eye protection blocks the sand!"), span_warning("Your eye protection blocks the sand!")) return C.adjust_eye_blur(12 SECONDS) - C.adjust_stamina_loss(15)//the pain from your eyes burning does stamina damage + C.adjust_stamina_loss(15) //the pain from your eyes burning does stamina damage C.adjust_confusion(5 SECONDS) to_chat(C, span_userdanger("\The [src] gets into your eyes! The pain, it burns!")) qdel(src) @@ -151,7 +170,6 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ if(severity) qdel(src) return TRUE - return FALSE /obj/item/stack/ore/glass/thirty @@ -164,17 +182,27 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ mine_experience = 0 merge_type = /obj/item/stack/ore/glass/basalt +/obj/item/stack/ore/glass/siderite + name = "siderite dust" + icon_state = "siderite_sand" + singular_name = "siderite dust pile" + mine_experience = 0 + merge_type = /obj/item/stack/ore/glass/siderite + /obj/item/stack/ore/plasma name = "plasma ore" icon_state = "plasma" singular_name = "plasma ore chunk" points = 15 - mats_per_unit = list(/datum/material/plasma=SHEET_MATERIAL_AMOUNT) + mats_per_unit = list(/datum/material/plasma = SHEET_MATERIAL_AMOUNT) refined_type = /obj/item/stack/sheet/mineral/plasma mine_experience = 5 scan_state = "rock_plasma" - spreadChance = 8 + spread_chance = 45 merge_type = /obj/item/stack/ore/plasma + vein_type = ORE_VEIN_PLAIN + min_vein_size = 2 + max_vein_size = 4 /obj/item/stack/ore/plasma/welder_act(mob/living/user, obj/item/I) to_chat(user, span_warning("You can't hit a high enough temperature to smelt [src] properly!")) @@ -186,11 +214,14 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ singular_name = "silver ore chunk" points = 16 mine_experience = 3 - mats_per_unit = list(/datum/material/silver=SHEET_MATERIAL_AMOUNT) + mats_per_unit = list(/datum/material/silver = SHEET_MATERIAL_AMOUNT) refined_type = /obj/item/stack/sheet/mineral/silver scan_state = "rock_silver" - spreadChance = 5 + spread_chance = 35 merge_type = /obj/item/stack/ore/silver + vein_type = ORE_VEIN_BRANCH + min_vein_size = 0 + max_vein_size = 2 /obj/item/stack/ore/gold name = "gold ore" @@ -198,22 +229,31 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ singular_name = "gold ore chunk" points = 18 mine_experience = 5 - mats_per_unit = list(/datum/material/gold=SHEET_MATERIAL_AMOUNT) + mats_per_unit = list(/datum/material/gold = SHEET_MATERIAL_AMOUNT) refined_type = /obj/item/stack/sheet/mineral/gold scan_state = "rock_gold" - spreadChance = 5 + spread_chance = 35 merge_type = /obj/item/stack/ore/gold + vein_type = ORE_VEIN_BRANCH + vein_distance = 2 + min_vein_size = 0 + max_vein_size = 2 /obj/item/stack/ore/diamond name = "diamond ore" icon_state = "diamond" singular_name = "diamond ore chunk" points = 50 - mats_per_unit = list(/datum/material/diamond=SHEET_MATERIAL_AMOUNT) + mats_per_unit = list(/datum/material/diamond = SHEET_MATERIAL_AMOUNT) refined_type = /obj/item/stack/sheet/mineral/diamond mine_experience = 10 scan_state = "rock_diamond" merge_type = /obj/item/stack/ore/diamond + vein_type = ORE_VEIN_SCATTER + spread_chance = 20 + vein_distance = 4 + min_vein_size = 1 + max_vein_size = 2 /obj/item/stack/ore/diamond/Initialize(mapload) . = ..() @@ -227,23 +267,30 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ icon_state = "bananium" singular_name = "bananium ore chunk" points = 60 - mats_per_unit = list(/datum/material/bananium=SHEET_MATERIAL_AMOUNT) + mats_per_unit = list(/datum/material/bananium = SHEET_MATERIAL_AMOUNT) refined_type = /obj/item/stack/sheet/mineral/bananium mine_experience = 15 scan_state = "rock_bananium" merge_type = /obj/item/stack/ore/bananium + vein_type = ORE_VEIN_PLAIN + spread_chance = 20 + vein_distance = 4 + min_vein_size = 1 + max_vein_size = 2 /obj/item/stack/ore/titanium name = "titanium ore" icon_state = "titanium" singular_name = "titanium ore chunk" points = 50 - mats_per_unit = list(/datum/material/titanium=SHEET_MATERIAL_AMOUNT) + mats_per_unit = list(/datum/material/titanium = SHEET_MATERIAL_AMOUNT) refined_type = /obj/item/stack/sheet/mineral/titanium mine_experience = 3 scan_state = "rock_titanium" - spreadChance = 5 + spread_chance = 35 merge_type = /obj/item/stack/ore/titanium + min_vein_size = 1 + max_vein_size = 2 /obj/item/stack/ore/slag name = "slag" diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index 361f111539d..868926e0320 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -382,13 +382,11 @@ */ /mob/dead/new_player/proc/register_for_interview() // First we detain them by removing all the verbs they have on client - for (var/v in client.verbs) - var/procpath/verb_path = v + for (var/procpath/verb_path as anything in client.verbs) remove_verb(client, verb_path) // Then remove those on their mob as well - for (var/v in verbs) - var/procpath/verb_path = v + for (var/procpath/verb_path as anything in verbs) remove_verb(src, verb_path) // Then we create the interview form and show it to the client diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 55ba216172a..eda2bc9a86e 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -221,18 +221,16 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) if(ghost_accs == GHOST_ACCS_FULL && (icon_state in GLOB.ghost_forms_with_accessories_list)) //check if this form supports accessories and if the client wants to show them if(facial_hairstyle) var/datum/sprite_accessory/S = SSaccessories.facial_hairstyles_list[facial_hairstyle] - if(S) - facial_hair_overlay = mutable_appearance(S.icon, "[S.icon_state]", -HAIR_LAYER) - if(facial_hair_color) - facial_hair_overlay.color = facial_hair_color + if(S && S.icon_state != SPRITE_ACCESSORY_NONE) + facial_hair_overlay = mutable_appearance(S.icon, S.icon_state, -HAIR_LAYER) + facial_hair_overlay.color = facial_hair_color facial_hair_overlay.alpha = 200 add_overlay(facial_hair_overlay) if(hairstyle) var/datum/sprite_accessory/hair/S = SSaccessories.hairstyles_list[hairstyle] - if(S) - hair_overlay = mutable_appearance(S.icon, "[S.icon_state]", -HAIR_LAYER) - if(hair_color) - hair_overlay.color = hair_color + if(S && S.icon_state != SPRITE_ACCESSORY_NONE) + hair_overlay = mutable_appearance(S.icon, S.icon_state, -HAIR_LAYER) + hair_overlay.color = hair_color hair_overlay.alpha = 200 hair_overlay.pixel_z = S.y_offset add_overlay(hair_overlay) @@ -256,18 +254,22 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) lum = max(read_color[3], 80) return rgb(read_color[1], sat, lum, space = COLORSPACE_HSL) -/* -Transfer_mind is there to check if mob is being deleted/not going to have a body. -Works together with spawning an observer, noted above. -*/ - -/mob/proc/ghostize(can_reenter_corpse = TRUE, admin_ghost = FALSE) +/** + * # Ghostize + * + * Creates a /mob/dead/observer and moves the player's key into it (among other handling for player->observer) + * Ignores things like adminghosts and corpselocked (ethereal) players. + * Args: + * can_reenter_corse: Whether the new Ghost will be able to click "Re-enter body", TRUE by default. + * forced: Whether we are forcing this player to be ghosted, ignoring things like corpselocking, FALSE by default. + */ +/mob/proc/ghostize(can_reenter_corpse = TRUE, forced = FALSE) if(!key) return if(IS_FAKE_KEY(key)) // Skip aghosts. return - if(HAS_TRAIT(src, TRAIT_CORPSELOCKED) && !admin_ghost) + if(HAS_TRAIT(src, TRAIT_CORPSELOCKED) && !forced) if(can_reenter_corpse) //If you can re-enter the corpse you can't leave when corpselocked return if(ishuman(usr)) //following code only applies to those capable of having an ethereal heart, ie humans @@ -295,7 +297,7 @@ Works together with spawning an observer, noted above. SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZED) return ghost -/mob/living/ghostize(can_reenter_corpse = TRUE) +/mob/living/ghostize(can_reenter_corpse = TRUE, forced = FALSE) . = ..() if(. && can_reenter_corpse) var/mob/dead/observer/ghost = . @@ -387,8 +389,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp return client.view_size.resetToDefault()//Let's reset so people can't become allseeing gods SStgui.on_transfer(src, mind.current) // Transfer NanoUIs. - if(mind.current.stat == DEAD && SSlag_switch.measures[DISABLE_DEAD_KEYLOOP]) - to_chat(src, span_warning("To leave your body again use the Ghost verb.")) + if(mind.current.stat == DEAD && SSlag_switch.measures[DISABLE_DEAD_KEYLOOP] && !client.holder) + to_chat(src, span_warning("To leave your body again use the 'Ghost verb' (in the command bar).")) mind.current.PossessByPlayer(key) mind.current.client.init_verbs() return TRUE diff --git a/code/modules/mob/dead/observer/observer_movement.dm b/code/modules/mob/dead/observer/observer_movement.dm index 6972d3b265f..cfe505fb0f7 100644 --- a/code/modules/mob/dead/observer/observer_movement.dm +++ b/code/modules/mob/dead/observer/observer_movement.dm @@ -1,14 +1,8 @@ /mob/dead/observer/down() - set name = "Move Down" - set category = "IC" - if(zMove(DOWN, z_move_flags = ZMOVE_FEEDBACK)) to_chat(src, span_notice("You move down.")) /mob/dead/observer/up() - set name = "Move Upwards" - set category = "IC" - if(zMove(UP, z_move_flags = ZMOVE_FEEDBACK)) to_chat(src, span_notice("You move upwards.")) diff --git a/code/modules/mob/eye/eye.dm b/code/modules/mob/eye/eye.dm index fb3c2a4fab7..2b79ab2a19c 100644 --- a/code/modules/mob/eye/eye.dm +++ b/code/modules/mob/eye/eye.dm @@ -27,16 +27,10 @@ return FALSE /mob/eye/up() - set name = "Move Upwards" - set category = "IC" - if(zMove(UP, z_move_flags = ZMOVE_FEEDBACK)) to_chat(src, span_notice("You move upwards.")) /mob/eye/down() - set name = "Move Down" - set category = "IC" - if(zMove(DOWN, z_move_flags = ZMOVE_FEEDBACK)) to_chat(src, span_notice("You move down.")) diff --git a/code/modules/mob/living/basic/alien/maid.dm b/code/modules/mob/living/basic/alien/maid.dm index cf6499884e9..7132f2ef4b0 100644 --- a/code/modules/mob/living/basic/alien/maid.dm +++ b/code/modules/mob/living/basic/alien/maid.dm @@ -19,15 +19,15 @@ ///Handles the maid attacking other players, cancelling the attack to clean up instead. /mob/living/basic/alien/maid/early_melee_attack(atom/target, list/modifiers, ignore_cooldown) . = ..() - if(!.) - return FALSE + if(.) + return target.wash(CLEAN_SCRUB) if(istype(target, /obj/effect/decal/cleanable)) visible_message(span_notice("[src] cleans up \the [target].")) else visible_message(span_notice("[src] polishes \the [target].")) - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN /** * Barmaid special type diff --git a/code/modules/mob/living/basic/basic.dm b/code/modules/mob/living/basic/basic.dm index 0392cfcc6bc..99735029110 100644 --- a/code/modules/mob/living/basic/basic.dm +++ b/code/modules/mob/living/basic/basic.dm @@ -232,21 +232,22 @@ . += span_deadsay("Upon closer examination, [p_they()] appear[p_s()] to be [HAS_MIND_TRAIT(user, TRAIT_NAIVE) ? "asleep" : "dead"].") /mob/living/basic/proc/melee_attack(atom/target, list/modifiers, ignore_cooldown = FALSE) - if(!early_melee_attack(target, modifiers, ignore_cooldown)) + var/early_melee_result = early_melee_attack(target, modifiers, ignore_cooldown) + if(early_melee_result) //Truthy value means we want to end the chain + if(!ignore_cooldown && early_melee_result == BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN) + changeNext_move(melee_attack_cooldown) return FALSE var/result = target.attack_basic_mob(src, modifiers) SEND_SIGNAL(src, COMSIG_HOSTILE_POST_ATTACKINGTARGET, target, result) - if(!ignore_cooldown) - changeNext_move(melee_attack_cooldown) // Set it again because objects like to fuck with it in attack_basic_mob + if(result && !ignore_cooldown) //Only set cooldown if the attack achieved something, which is the case when the value is true-ey. This could definitely be done better but is probably easier once living/simple is gone and we no longer use attack_animal. + changeNext_move(melee_attack_cooldown) return result /mob/living/basic/proc/early_melee_attack(atom/target, list/modifiers, ignore_cooldown = FALSE) face_atom(target) - if(!ignore_cooldown) - changeNext_move(melee_attack_cooldown) // Set cooldown early in case it is cancelled if(SEND_SIGNAL(src, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, target, Adjacent(target), modifiers) & COMPONENT_HOSTILE_NO_ATTACK) - return FALSE //but more importantly return before attack_animal called - return TRUE + return BASIC_MOB_END_ATTACK_CHAIN //but more importantly return before attack_animal called + return BASIC_MOB_CONTINUE_ATTACK_CHAIN /mob/living/basic/resolve_unarmed_attack(atom/attack_target, list/modifiers) melee_attack(attack_target, modifiers) @@ -307,17 +308,6 @@ if (.) update_held_items() -/mob/living/basic/update_held_items() - . = ..() - if(isnull(client) || isnull(hud_used) || hud_used.hud_version == HUD_STYLE_NOHUD) - return - var/turf/our_turf = get_turf(src) - for(var/obj/item/held in held_items) - var/index = get_held_index_of_item(held) - SET_PLANE(held, ABOVE_HUD_PLANE, our_turf) - held.screen_loc = ui_hand_position(index) - client.screen |= held - /mob/living/basic/get_body_temp_heat_damage_limit() return maximum_survivable_temperature diff --git a/code/modules/mob/living/basic/blob_minions/blob_mob.dm b/code/modules/mob/living/basic/blob_minions/blob_mob.dm index 8d24dccd7df..ef7184d09ac 100644 --- a/code/modules/mob/living/basic/blob_minions/blob_mob.dm +++ b/code/modules/mob/living/basic/blob_minions/blob_mob.dm @@ -21,6 +21,7 @@ initial_language_holder = /datum/language_holder/empty can_buckle_to = FALSE damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, STAMINA = 0, OXY = 1) + pull_force = 0 /// Size of cloud produced from a dying spore var/death_cloud_size = BLOBMOB_CLOUD_NONE var/loot = /obj/item/food/spore_sack diff --git a/code/modules/mob/living/basic/boss/boss.dm b/code/modules/mob/living/basic/boss/boss.dm index 4ffd7961de3..8f4a4924800 100644 --- a/code/modules/mob/living/basic/boss/boss.dm +++ b/code/modules/mob/living/basic/boss/boss.dm @@ -77,10 +77,11 @@ /mob/living/basic/boss/early_melee_attack(mob/living/target, list/modifiers, ignore_cooldown) . = ..() - if(!. || !istype(target)) + if(. || !istype(target)) return if(should_devour(target)) devour(target) + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN /// Determines if this mob is worth devouring /mob/living/basic/boss/proc/should_devour(mob/living/victim) diff --git a/code/modules/mob/living/basic/bots/bot_ai.dm b/code/modules/mob/living/basic/bots/bot_ai.dm index 6f726c9586c..a5f8202e66e 100644 --- a/code/modules/mob/living/basic/bots/bot_ai.dm +++ b/code/modules/mob/living/basic/bots/bot_ai.dm @@ -63,6 +63,8 @@ source.clear_path_hud(remove_hud = FALSE) /datum/ai_controller/basic_controller/bot/proc/add_to_blacklist(atom/target, duration) + if(QDELETED(target)) + return var/final_duration = duration || blackboard[BB_UNREACHABLE_LIST_COOLDOWN] set_blackboard_key_assoc_lazylist(BB_TEMPORARY_IGNORE_LIST, target, TRUE) addtimer(CALLBACK(src, PROC_REF(remove_from_blacklist), target), final_duration) @@ -107,11 +109,15 @@ ///set the target if we can reach them /datum/ai_controller/basic_controller/bot/proc/set_if_can_reach(key, target, duration, distance = 10, bypass_add_to_blacklist = FALSE) if(can_reach_target(target, distance)) + EVLOG_MAPTEXT(src, EVLOG_CATEGORY_AI_TARGETING, "[pawn] has selected [target] as a target for blackboard key [key]!", get_turf(target), "Target: [target]") + EVLOG_LINES(src, EVLOG_CATEGORY_AI_TARGETING, "Line to target", get_turf(pawn), get_turf(target)) set_blackboard_key(key, target) return TRUE if(bypass_add_to_blacklist) return FALSE var/final_duration = duration || blackboard[BB_UNREACHABLE_LIST_COOLDOWN] + EVLOG_MAPTEXT(src, EVLOG_CATEGORY_AI_TARGETING, "[pawn] has added [target] to its targetting blacklist!", get_turf(target), "Target: [target]") + EVLOG_LINES(src, EVLOG_CATEGORY_AI_TARGETING, "Line to target", get_turf(pawn), get_turf(target)) add_to_blacklist(target, final_duration) return FALSE diff --git a/code/modules/mob/living/basic/bots/ed209/ed209.dm b/code/modules/mob/living/basic/bots/ed209/ed209.dm new file mode 100644 index 00000000000..83373e25a82 --- /dev/null +++ b/code/modules/mob/living/basic/bots/ed209/ed209.dm @@ -0,0 +1,176 @@ +/mob/living/basic/bot/secbot/ed209 + name = "\improper ED-209 Security Robot" + desc = "A security robot. He looks less than thrilled." + icon_state = "ed209" + base_icon_state = "ed209" + light_color = "#f84e4e" + density = TRUE + health = 100 + maxHealth = 100 + obj_damage = 60 + environment_smash = ENVIRONMENT_SMASH_WALLS //Walls can't stop THE LAW + mob_size = MOB_SIZE_LARGE + ai_controller = /datum/ai_controller/basic_controller/bot/ed209 + bot_type = ADVANCED_SEC_BOT + hackables = "combat inhibitors" + + custom_materials = list( + /datum/material/iron = SHEET_MATERIAL_AMOUNT * 2.8, + /datum/material/glass = SMALL_MATERIAL_AMOUNT * 2.1, + ) + + ///sound of the projectiles we shoot + var/projectile_sound = 'sound/items/weapons/laser.ogg' + ///what projectiles we shoot + var/projectile_type = /obj/projectile/beam/disabler + ///what projectiles we shoot when emagged + var/emagged_projectile_type = /obj/projectile/beam + ///sound of emagged projectile + var/emagged_projectile_sound = 'sound/items/weapons/laser.ogg' + ///special hats that change our personality :mistake: + var/static/list/sherrif_hats = typecacheof(list( + /obj/item/clothing/head/cowboy, + )) + var/datum/action/cooldown/mob_cooldown/ed209_charge/bot_charge + ///our riding component + var/ride_component = /datum/component/riding/creature/ed_bot + ///have we become a sheriff + var/sheriffized = FALSE + ///timer till we yell out our war cry again + COOLDOWN_DECLARE(shoot_cry) + + +/mob/living/basic/bot/secbot/ed209/Initialize(mapload) + . = ..() + set_weapon() + bot_charge = new(src) + var/static/list/hat_offset = list(2, 0) + AddElement(/datum/element/hat_wearer,\ + offsets = hat_offset,\ + ) + + AddComponent(/datum/component/defaceable, \ + icon = 'icons/mob/silicon/aibot_faces.dmi', \ + icon_states = list("ed209" = FALSE, "ed209_highlight" = TRUE), \ + drawing_of = "a face", \ + ) + AddComponent(/datum/component/stun_n_cuff,\ + stun_sound = 'sound/items/weapons/egloves.ogg',\ + handcuff_type = /obj/item/restraints/handcuffs/cable/zipties,\ + ) + AddElement(/datum/element/ridable, ride_component) + RegisterSignal(src, COMSIG_BASICMOB_POST_ATTACK_RANGED, PROC_REF(post_ranged_attack)) + +/mob/living/basic/bot/secbot/ed209/Entered(atom/movable/arrived, atom/old_loc, list/atom/old_locs) + . = ..() + sheriffized = (is_type_in_typecache(arrived, sherrif_hats)) //yeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeehawwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww + +/mob/living/basic/bot/secbot/ed209/proc/post_ranged_attack() + SIGNAL_HANDLER + if(!sheriffized || !COOLDOWN_FINISHED(src, shoot_cry)) + return + COOLDOWN_START(src, shoot_cry, 30 SECONDS) + INVOKE_ASYNC(src, TYPE_PROC_REF(/atom/movable, say), "YIPPIE-KI-YAY!") + +/mob/living/basic/bot/secbot/ed209/Exited(atom/movable/gone, direction) + . = ..() + sheriffized = (is_type_in_typecache(gone, sherrif_hats)) + +/mob/living/basic/bot/secbot/ed209/examine(mob/user) + . = ..() + if(sheriffized) + . += span_notice("Fastest hand in the west.") + +/mob/living/basic/bot/secbot/ed209/bot_reset(bypass_ai_reset = FALSE) + . = ..() + if(bot_access_flags & BOT_COVER_EMAGGED && isnull(bot_charge.owner)) + bot_charge.Grant(src) + if(!(bot_access_flags & BOT_COVER_EMAGGED) && !isnull(bot_charge.owner)) + bot_charge.Remove(src) + set_weapon() + +/mob/living/basic/bot/secbot/ed209/emag_act(mob/user, obj/item/card/emag/emag_card) + . = ..() + icon_state = "ed209[bot_mode_flags & BOT_MODE_ON]" + set_weapon() + balloon_alert(user, "safeties disabled") + audible_message(span_bolddanger("[src] buzzes menacingly!")) + return TRUE + +/mob/living/basic/bot/secbot/ed209/proc/set_weapon() + qdel(GetComponent(/datum/component/ranged_attacks)) + var/projectile = (bot_access_flags & BOT_COVER_EMAGGED) ? emagged_projectile_type : projectile_type + var/final_projectile_sound = (bot_access_flags & BOT_COVER_EMAGGED) ? emagged_projectile_sound : projectile_sound + AddComponent(\ + /datum/component/ranged_attacks,\ + projectile_type = projectile,\ + projectile_sound = final_projectile_sound,\ + ) + +/mob/living/basic/bot/secbot/ed209/ui_data(mob/user) + var/list/data = ..() + if(!(bot_access_flags & BOT_COVER_LOCKED) || HAS_SILICON_ACCESS(user)) + data["custom_controls"]["handcuff"] = security_mode_flags & SECBOT_HANDCUFF_TARGET + data["custom_controls"]["check_ids"] = security_mode_flags & SECBOT_CHECK_IDS + data["custom_controls"]["check_records"] = security_mode_flags & SECBOT_CHECK_RECORDS + return data + +/mob/living/basic/bot/secbot/ed209/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + var/mob/user = ui.user + if(. || !isliving(user) || (bot_access_flags & BOT_COVER_LOCKED) && !HAS_SILICON_ACCESS(user)) + return + switch(action) + if("handcuff") + security_mode_flags ^= SECBOT_HANDCUFF_TARGET + if("check_ids") + security_mode_flags ^= SECBOT_CHECK_IDS + if("check_records") + security_mode_flags ^= SECBOT_CHECK_RECORDS + +/mob/living/basic/bot/secbot/ed209/retrieve_secbot_drops(atom/drop_location) + var/obj/item/bot_assembly/ed209/ed_assembly = new(drop_location) + ed_assembly.build_step = ASSEMBLY_FIRST_STEP + ed_assembly.add_overlay("hs_hole") + ed_assembly.created_name = name + new /obj/item/assembly/prox_sensor(drop_location) + var/obj/item/gun/energy/disabler/disabler_gun = new(drop_location) + disabler_gun.cell.charge = 0 + disabler_gun.update_appearance() + if(prob(50)) + new /obj/item/bodypart/leg/left/robot(drop_location) + if(prob(25)) + new /obj/item/bodypart/leg/right/robot(drop_location) + if(prob(75)) + return + if(prob(50)) // either helmet or vest + new /obj/item/clothing/head/helmet(drop_location) + else + new /obj/item/clothing/suit/armor/vest(drop_location) + +/mob/living/basic/bot/secbot/ed209/Destroy() + . = ..() + QDEL_NULL(bot_charge) + +/mob/living/basic/bot/secbot/ed209/nukie + name = "\improper ED-209(+1) Syndicate Robot" + desc = "Wait this one's red? This cannot be good... right??" + icon_state = "red209" + light_color = "#5c0909" + faction = list(ROLE_SYNDICATE) + health = 250 + maxHealth = 250 + obj_damage = 60 + req_one_access = list(ACCESS_SYNDICATE) + bot_mode_flags = parent_type::bot_mode_flags & ~BOT_MODE_REMOTE_ENABLED + radio_key = /obj/item/encryptionkey/syndicate + additional_access = /datum/id_trim/syndicom/crew + radio_channel = RADIO_CHANNEL_SYNDICATE + ai_controller = /datum/ai_controller/basic_controller/bot/ed209/syndicate + bot_type = ADVANCED_SEC_BOT + hackables = "combat inhibitors" + projectile_sound = 'sound/items/weapons/gun/l6/shot.ogg' + projectile_type = /obj/projectile/bullet/a7mm + emagged_projectile_sound = 'sound/items/weapons/minebot_rocket.ogg' + emagged_projectile_type = /obj/projectile/bullet/rocket/weak //lord have mercy + ride_component = /datum/component/riding/creature/ed_bot/nukie //ride at ur own risk. especially if its emagged. warranty void diff --git a/code/modules/mob/living/basic/bots/ed209/ed209_ability.dm b/code/modules/mob/living/basic/bots/ed209/ed209_ability.dm new file mode 100644 index 00000000000..57d3143e133 --- /dev/null +++ b/code/modules/mob/living/basic/bots/ed209/ed209_ability.dm @@ -0,0 +1,40 @@ +/datum/action/cooldown/mob_cooldown/ed209_charge + name = "Bot Tackle" + desc = "Not even God's mightiest Quarterback can withstand this." + cooldown_time = 10 SECONDS + background_icon_state = "bg_revenant" + overlay_icon_state = "bg_revenant_border" + shared_cooldown = NONE + ///duration of telegraph + var/telegraph_duration = 1.25 SECONDS + ///damage we apply on tackle + var/tackle_damage = 25 + +/datum/action/cooldown/mob_cooldown/ed209_charge/Activate(atom/target) + var/turf/target_turf = get_turf(target) + if(isclosedturf(target_turf) || isspaceturf(target_turf)) + owner.balloon_alert(owner, "base not suitable!") + return FALSE + addtimer(CALLBACK(src, PROC_REF(commence_launch), target), telegraph_duration) + owner.Shake(duration = telegraph_duration) + StartCooldown() + return TRUE + +/datum/action/cooldown/mob_cooldown/ed209_charge/proc/commence_launch(atom/target) + var/turf/target_turf = get_turf(target) + owner.throw_at(target = target_turf, range = 7, speed = 1, spin = FALSE, callback = CALLBACK(src, PROC_REF(on_tackle), target_turf)) + new /obj/effect/temp_visual/mook_dust(owner.loc) + +/datum/action/cooldown/mob_cooldown/ed209_charge/proc/on_tackle(turf/target, original_pixel_y) + playsound(get_turf(owner), 'sound/effects/meteorimpact.ogg', 100, TRUE) + new /obj/effect/temp_visual/mook_dust(owner.loc) + for(var/mob/living/victim in oview(1, owner)) + if(victim in owner.buckled_mobs) + continue + victim.apply_damage(tackle_damage) + if(QDELETED(victim)) + continue + var/throw_dir = victim.loc == owner.loc ? get_dir(owner, victim) : pick(GLOB.alldirs) + var/throwtarget = get_edge_target_turf(victim, throw_dir) + victim.throw_at(target = throwtarget, range = 3, speed = 1) + victim.visible_message(span_warning("[victim] eats steel!")) diff --git a/code/modules/mob/living/basic/bots/ed209/ed209_ai.dm b/code/modules/mob/living/basic/bots/ed209/ed209_ai.dm new file mode 100644 index 00000000000..d699a153bb2 --- /dev/null +++ b/code/modules/mob/living/basic/bots/ed209/ed209_ai.dm @@ -0,0 +1,65 @@ +#define DEFAULT_LINES "default_lines" +#define SPECIAL_LINES "special_lines" + +/datum/ai_controller/basic_controller/bot/ed209 + blackboard = list( + BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic/secbot, + BB_UNREACHABLE_LIST_COOLDOWN = 1 MINUTES, + BB_ALWAYS_IGNORE_FACTION = TRUE, + ) + planning_subtrees = list( + /datum/ai_planning_subtree/escape_captivity/pacifist, + /datum/ai_planning_subtree/respond_to_summon, + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/ranged_skirmish, + /datum/ai_planning_subtree/arrest_target/ed209, + /datum/ai_planning_subtree/find_patrol_beacon, + ) + reset_keys = list( + BB_BEACON_TARGET, + BB_PREVIOUS_BEACON_TARGET, + BB_BOT_SUMMON_TARGET, + ) + + +/datum/ai_controller/basic_controller/bot/ed209/TryPossessPawn(atom/new_pawn) + . = ..() + if(. & AI_CONTROLLER_INCOMPATIBLE) + return + RegisterSignal(new_pawn, COMSIG_AI_BLACKBOARD_KEY_SET(BB_BASIC_MOB_CURRENT_TARGET), PROC_REF(on_target_set)) + + +/datum/ai_controller/basic_controller/bot/ed209/proc/on_target_set() + SIGNAL_HANDLER + var/datum/action/cooldown/bot_announcement/announcement = blackboard[BB_ANNOUNCE_ABILITY] + var/static/list/lines_to_pick = list( + DEFAULT_LINES = list( + "Scumbag alert!", + "Threat detected!" + ), + SPECIAL_LINES = list( + "Why y'all causin trouble in my town?", + "Fill your hands, you son of a bitch.", + "Aint nobody causin trouble in MY jurisdiction." + ) + + ) + var/mob/living/basic/bot/secbot/ed209/my_bot = pawn + var/list/final_list = my_bot.sheriffized ? lines_to_pick[SPECIAL_LINES] : lines_to_pick[DEFAULT_LINES] + INVOKE_ASYNC(announcement, TYPE_PROC_REF(/datum/action/cooldown/bot_announcement, announce), pick(final_list)) + +/datum/ai_planning_subtree/arrest_target/ed209 + arrest_behavior = /datum/ai_behavior/basic_melee_attack/interact_once/bot/ed209 + + +/datum/ai_behavior/basic_melee_attack/interact_once/bot/ed209 + action_cooldown = 0.5 SECONDS + +/datum/ai_behavior/basic_melee_attack/interact_once/bot/ed209/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key) + . = ..() + if(!(. & AI_BEHAVIOR_DELAY)) + return AI_BEHAVIOR_DELAY //this kinda sucks but we have to do this cause we need to shoot while moving to stun + + +#undef DEFAULT_LINES +#undef SPECIAL_LINES diff --git a/code/modules/mob/living/basic/bots/ed209/ed209_nukie_ai.dm b/code/modules/mob/living/basic/bots/ed209/ed209_nukie_ai.dm new file mode 100644 index 00000000000..24bf9a20367 --- /dev/null +++ b/code/modules/mob/living/basic/bots/ed209/ed209_nukie_ai.dm @@ -0,0 +1,16 @@ +/datum/ai_controller/basic_controller/bot/ed209/syndicate + blackboard = list( + BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic, + BB_UNREACHABLE_LIST_COOLDOWN = 1 MINUTES, + ) + planning_subtrees = list( + /datum/ai_planning_subtree/escape_captivity/pacifist, + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/basic_ranged_attack_subtree, + /datum/ai_planning_subtree/find_patrol_beacon, + ) + reset_keys = list( + BB_BEACON_TARGET, + BB_PREVIOUS_BEACON_TARGET, + BB_BOT_SUMMON_TARGET, + ) diff --git a/code/modules/mob/living/basic/bots/ed209/ed209_nukie_spawner.dm b/code/modules/mob/living/basic/bots/ed209/ed209_nukie_spawner.dm new file mode 100644 index 00000000000..95c5b18ea24 --- /dev/null +++ b/code/modules/mob/living/basic/bots/ed209/ed209_nukie_spawner.dm @@ -0,0 +1,19 @@ +/obj/item/antag_spawner/nuke_ops/ed209_nukie + name = "Syndicate ED209 Robot" + desc = "A single-use beacon designed to quickly launch reinforcement operatives into the field." + + +/obj/item/antag_spawner/nuke_ops/ed209_nukie/attack_self(mob/user) + if(!(check_usability(user))) + return + + to_chat(user, span_notice("You activate [src] and wait for confirmation.")) + drop_bot() + do_sparks(4, TRUE, src) + qdel(src) + +/obj/item/antag_spawner/nuke_ops/ed209_nukie/proc/drop_bot() + var/mob/living/basic/bot/secbot/ed209/nukie/nuclear_bot = new() + var/obj/structure/closet/supplypod/pod = setup_pod() + nuclear_bot.forceMove(pod) + new /obj/effect/pod_landingzone(spawn_location ? spawn_location : get_turf(src), pod) diff --git a/code/modules/mob/living/basic/bots/honkbots/honkbot.dm b/code/modules/mob/living/basic/bots/honkbots/honkbot.dm index eb57581ae16..5daa8e5b25b 100644 --- a/code/modules/mob/living/basic/bots/honkbots/honkbot.dm +++ b/code/modules/mob/living/basic/bots/honkbots/honkbot.dm @@ -1,4 +1,4 @@ -/mob/living/basic/bot/honkbot +/mob/living/basic/bot/secbot/honkbot name = "\improper Honkbot" desc = "A little robot. It looks happy with its bike horn." icon_state = "honkbot" @@ -16,15 +16,17 @@ data_hud_type = TRAIT_SECURITY_HUD_ID_ONLY additional_access = /datum/id_trim/job/clown possessed_message = "You are a honkbot! Make sure the crew are having a great time!" + security_mode_flags = parent_type::security_mode_flags | HONKBOT_MODE_SLIP ///our voicelines var/static/list/honkbot_sounds = list( HONKBOT_VOICED_HONK_HAPPY = 'sound/items/bikehorn.ogg', HONKBOT_VOICED_HONK_SAD = 'sound/misc/sadtrombone.ogg', ) - ///Honkbot's flags - var/honkbot_flags = HONKBOT_CHECK_RECORDS | HONKBOT_HANDCUFF_TARGET | HONKBOT_MODE_SLIP + stun_sound = 'sound/items/airhorn/AirHorn.ogg' + baton_type = /obj/item/bikehorn/airhorn + cuff_type = /obj/item/restraints/handcuffs/cable/zipties/fake -/mob/living/basic/bot/honkbot/Initialize(mapload) +/mob/living/basic/bot/secbot/honkbot/Initialize(mapload) . = ..() var/static/list/clown_friends = typecacheof(list( /mob/living/carbon/human, @@ -48,33 +50,34 @@ on_slip_callback = CALLBACK(src, PROC_REF(post_slip)),\ can_slip_callback = CALLBACK(src, PROC_REF(pre_slip)),\ ) - AddComponent(/datum/component/stun_n_cuff,\ - stun_sound = 'sound/items/airhorn/AirHorn.ogg',\ - post_stun_callback = CALLBACK(src, PROC_REF(post_stun)),\ - post_arrest_callback = CALLBACK(src, PROC_REF(post_arrest)),\ - handcuff_type = /obj/item/restraints/handcuffs/cable/zipties/fake,\ - ) -/mob/living/basic/bot/honkbot/generate_speak_list() +/mob/living/basic/bot/secbot/honkbot/generate_speak_list() return honkbot_sounds -/mob/living/basic/bot/honkbot/proc/pre_slip() +/mob/living/basic/bot/secbot/honkbot/proc/pre_slip() return (prob(70) && ai_controller?.blackboard_key_exists(BB_BASIC_MOB_CURRENT_TARGET)) -/mob/living/basic/bot/honkbot/proc/post_slip() +/mob/living/basic/bot/secbot/honkbot/proc/post_slip() INVOKE_ASYNC(src, TYPE_PROC_REF(/mob/living/basic/bot, speak), HONKBOT_VOICED_HONK_SAD) set_attacking_state() -/mob/living/basic/bot/honkbot/proc/set_attacking_state() +/mob/living/basic/bot/secbot/honkbot/proc/set_attacking_state() icon_state = "[base_icon_state]-c" addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_appearance)), 0.2 SECONDS) -/mob/living/basic/bot/honkbot/proc/post_arrest(mob/living/carbon/current_target) +/mob/living/basic/bot/secbot/honkbot/post_arrest(mob/living/carbon/current_target) playsound(src, (bot_access_flags & BOT_COVER_EMAGGED ? SFX_HONKBOT_E : 'sound/items/bikehorn.ogg'), 50, FALSE) icon_state = bot_access_flags & BOT_COVER_EMAGGED ? "[base_icon_state]-e" : "[base_icon_state]-c" addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_appearance)), 3 SECONDS, TIMER_OVERRIDE|TIMER_UNIQUE) -/mob/living/basic/bot/honkbot/proc/post_stun(mob/living/carbon/current_target) + audible_message(span_danger("[src] gives out an evil laugh!")) + playsound(src, 'sound/mobs/non-humanoids/honkbot/honkbot_evil_laugh.ogg', 75, TRUE, -1) // evil laughter + +/mob/living/basic/bot/secbot/honkbot/retrieve_emag_message() + audible_message(span_danger("[src] gives out an evil laugh!")) + playsound(src, 'sound/mobs/non-humanoids/honkbot/honkbot_evil_laugh.ogg', 75, TRUE, -1) // evil laughter + +/mob/living/basic/bot/secbot/honkbot/post_stun(mob/living/carbon/current_target) if(!istype(current_target)) return @@ -86,26 +89,36 @@ sound_damage(deafen = 10 SECONDS) -/mob/living/basic/bot/honkbot/ui_data(mob/user) +/mob/living/basic/bot/secbot/honkbot/ui_data(mob/user) var/list/data = ..() if(!(bot_access_flags & BOT_COVER_LOCKED) || HAS_SILICON_ACCESS(user)) - data["custom_controls"]["slip_people"] = honkbot_flags & HONKBOT_MODE_SLIP - data["custom_controls"]["fake_cuff"] = honkbot_flags & HONKBOT_HANDCUFF_TARGET - data["custom_controls"]["check_ids"] = honkbot_flags & HONKBOT_CHECK_IDS - data["custom_controls"]["check_records"] = honkbot_flags & HONKBOT_CHECK_RECORDS + data["custom_controls"]["slip_people"] = security_mode_flags & HONKBOT_MODE_SLIP + data["custom_controls"]["fake_cuff"] = security_mode_flags & SECBOT_HANDCUFF_TARGET + data["custom_controls"]["check_ids"] = security_mode_flags & SECBOT_CHECK_IDS + data["custom_controls"]["check_records"] = security_mode_flags & SECBOT_CHECK_RECORDS return data -/mob/living/basic/bot/honkbot/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) +/mob/living/basic/bot/secbot/honkbot/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) . = ..() var/mob/user = ui.user if(. || !isliving(user) || (bot_access_flags & BOT_COVER_LOCKED) && !HAS_SILICON_ACCESS(user)) return switch(action) if("slip_people") - honkbot_flags ^= HONKBOT_MODE_SLIP + security_mode_flags ^= HONKBOT_MODE_SLIP if("fake_cuff") - honkbot_flags ^= HONKBOT_HANDCUFF_TARGET + security_mode_flags ^= SECBOT_HANDCUFF_TARGET if("check_ids") - honkbot_flags ^= HONKBOT_CHECK_IDS + security_mode_flags ^= SECBOT_CHECK_IDS if("check_records") - honkbot_flags ^= HONKBOT_CHECK_RECORDS + security_mode_flags ^= SECBOT_CHECK_RECORDS + +/mob/living/basic/bot/secbot/honkbot/retrieve_secbot_drops(atom/drop_location) + var/obj/item/bot_assembly/honkbot/honkbot_assembly = new(drop_location) + honkbot_assembly.build_step = ASSEMBLY_FIRST_STEP + honkbot_assembly.created_name = name + new /obj/item/assembly/prox_sensor(drop_location) + drop_part(baton_type, drop_location) + +/mob/living/basic/bot/secbot/honkbot/nopatrol + bot_mode_flags = parent_type::bot_mode_flags & ~BOT_MODE_AUTOPATROL diff --git a/code/modules/mob/living/basic/bots/honkbots/honkbot_ai.dm b/code/modules/mob/living/basic/bots/honkbots/honkbot_ai.dm index 620a6fc6d97..3a4d022087d 100644 --- a/code/modules/mob/living/basic/bots/honkbots/honkbot_ai.dm +++ b/code/modules/mob/living/basic/bots/honkbots/honkbot_ai.dm @@ -1,6 +1,6 @@ /datum/ai_controller/basic_controller/bot/honkbot blackboard = list( - BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic, + BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic/secbot, BB_UNREACHABLE_LIST_COOLDOWN = 1 MINUTES, BB_ALWAYS_IGNORE_FACTION = TRUE, ) @@ -8,8 +8,8 @@ /datum/ai_planning_subtree/escape_captivity/pacifist, /datum/ai_planning_subtree/respond_to_summon, /datum/ai_planning_subtree/use_mob_ability/random_honk, - /datum/ai_planning_subtree/find_wanted_targets, - /datum/ai_planning_subtree/troll_target, + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/arrest_target, /datum/ai_planning_subtree/slip_victims, /datum/ai_planning_subtree/play_with_clowns, /datum/ai_planning_subtree/find_patrol_beacon, @@ -43,60 +43,6 @@ add_to_blacklist(slip_target) clear_blackboard_key(BB_SLIP_TARGET) -/datum/ai_planning_subtree/find_wanted_targets - -/datum/ai_planning_subtree/find_wanted_targets/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) - var/static/list/can_arrest = typecacheof(list(/mob/living/carbon/human)) - if(!controller.blackboard_key_exists(BB_BASIC_MOB_CURRENT_TARGET)) - controller.queue_behavior(/datum/ai_behavior/bot_search/wanted_targets, BB_BASIC_MOB_CURRENT_TARGET, can_arrest) - -/datum/ai_behavior/bot_search/wanted_targets - -/datum/ai_behavior/bot_search/wanted_targets/valid_target(datum/ai_controller/basic_controller/bot/controller, mob/living/my_target) - if(!ishuman(my_target)) - return FALSE - var/mob/living/carbon/human/human_target = my_target - if(human_target.handcuffed || human_target.stat != CONSCIOUS) - return FALSE - if(locate(human_target) in controller.blackboard[BB_BASIC_MOB_RETALIATE_LIST]) - return TRUE - var/mob/living/basic/bot/honkbot/my_bot = controller.pawn - var/honkbot_flags = my_bot.honkbot_flags - var/assess_flags = NONE - if(human_target.IsParalyzed() && !(honkbot_flags & HONKBOT_HANDCUFF_TARGET)) - return FALSE - if(my_bot.bot_access_flags & BOT_COVER_EMAGGED) - assess_flags |= JUDGE_EMAGGED - if(honkbot_flags & HONKBOT_CHECK_IDS) - assess_flags |= JUDGE_IDCHECK - if(honkbot_flags & HONKBOT_CHECK_RECORDS) - assess_flags |= JUDGE_RECORDCHECK - return (human_target.assess_threat(assess_flags) > 0) - -/datum/ai_planning_subtree/troll_target - -/datum/ai_planning_subtree/troll_target/SelectBehaviors(datum/ai_controller/basic_controller/bot/controller, seconds_per_tick) - var/mob/living/carbon/my_target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET] - if(QDELETED(my_target) || !istype(my_target) || my_target.handcuffed) - controller.clear_blackboard_key(BB_BASIC_MOB_CURRENT_TARGET) - return - - var/mob/living/basic/bot/honkbot/my_bot = controller.pawn - if(my_target.IsParalyzed() && !(my_bot.honkbot_flags & HONKBOT_HANDCUFF_TARGET)) - controller.clear_blackboard_key(BB_BASIC_MOB_CURRENT_TARGET) - return - - controller.queue_behavior(/datum/ai_behavior/basic_melee_attack/interact_once/honkbot, BB_BASIC_MOB_CURRENT_TARGET, BB_TARGETING_STRATEGY) - return SUBTREE_RETURN_FINISH_PLANNING - -/datum/ai_behavior/basic_melee_attack/interact_once/honkbot - -/datum/ai_behavior/basic_melee_attack/interact_once/honkbot/finish_action(datum/ai_controller/controller, succeeded, target_key, targeting_strategy_key, hiding_location_key) - var/mob/living/carbon/human/human_target = controller.blackboard[target_key] - if(!isnull(human_target)) - controller.remove_from_blackboard_lazylist_key(BB_BASIC_MOB_RETALIATE_LIST, human_target) - return ..() - /datum/ai_planning_subtree/play_with_clowns/SelectBehaviors(datum/ai_controller/basic_controller/bot/controller, seconds_per_tick) var/mob/living/clown_target = controller.blackboard[BB_CLOWN_FRIEND] if(QDELETED(clown_target)) diff --git a/code/modules/mob/living/basic/bots/secbot/secbot.dm b/code/modules/mob/living/basic/bots/secbot/secbot.dm new file mode 100644 index 00000000000..df71f848a94 --- /dev/null +++ b/code/modules/mob/living/basic/bots/secbot/secbot.dm @@ -0,0 +1,263 @@ +/mob/living/basic/bot/secbot + name = "\improper Securitron" + desc = "A little security robot. He looks less than thrilled." + icon = 'icons/mob/silicon/aibots.dmi' + icon_state = "secbot" + base_icon_state = "secbot" + light_color = "#f56275" + light_power = 0.8 + gender = MALE + density = FALSE + anchored = FALSE + health = 25 + maxHealth = 25 + damage_coeff = list(BRUTE = 0.5, BURN = 0.7, TOX = 0, STAMINA = 0, OXY = 0) + pass_flags = PASSMOB | PASSFLAPS + combat_mode = TRUE + can_buckle_to = FALSE + + req_one_access = list(ACCESS_SECURITY) + radio_key = /obj/item/encryptionkey/secbot //AI Priv + Security + radio_channel = RADIO_CHANNEL_SECURITY //Security channel + bot_type = SEC_BOT + bot_mode_flags = ~BOT_MODE_CAN_BE_SAPIENT + data_hud_type = TRAIT_SECURITY_HUD + hackables = "target identification systems" + path_image_color = COLOR_RED + possessed_message = "You are a securitron! Guard the station to the best of your ability!" + additional_access = /datum/id_trim/job/detective + + custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 1.2, /datum/material/glass = SMALL_MATERIAL_AMOUNT * 3.2) + ai_controller = /datum/ai_controller/basic_controller/bot/secbot + ///Whether this secbot is considered 'commissioned' and given the trait on Initialize. + var/commissioned = FALSE + ///The type of baton this Secbot will use + var/baton_type = /obj/item/melee/baton/security + ///The weapon (from baton_type) that will be used to make arrests. + var/obj/item/weapon + ///The threat level of the BOT, will arrest anyone at threatlevel 4 or above + var/threatlevel = 0 + + ///Flags SecBOTs use on what to check on targets when arresting, and whether they should announce it to security/handcuff their target + /// Look at the security_mode_flags bitfield for more information on what's togglable here. + var/security_mode_flags = SECBOT_DECLARE_ARRESTS | SECBOT_CHECK_RECORDS | SECBOT_HANDCUFF_TARGET + + /// On arrest, charges the violator this much. + /// If they don't have that much in their account, they will get beaten instead + var/price_arrest = 0 + /// Charged each time the violator is stunned on detain + var/price_detain = 0 + ///The department the secbot will deposit collected money into + var/payment_department = ACCOUNT_SEC + ///what sound we play when stunning + var/stun_sound = 'sound/items/weapons/egloves.ogg' + ///The type of cuffs we use on criminals after making arrests + var/cuff_type = /obj/item/restraints/handcuffs/cable/zipties/used + +/mob/living/basic/bot/secbot/Initialize(mapload) + . = ..() + weapon = new baton_type(src) + update_appearance(UPDATE_ICON) + if(commissioned) + ADD_TRAIT(src, TRAIT_COMMISSIONED, INNATE_TRAIT) + + var/static/list/loc_connections = list( + COMSIG_ATOM_ENTERED = PROC_REF(on_entered), + ) + + AddElement(/datum/element/connect_loc, loc_connections) + AddComponent(/datum/component/security_vision, judgement_criteria = NONE, update_judgement_criteria = CALLBACK(src, PROC_REF(judgement_criteria))) + add_arrest_component() + +/mob/living/basic/bot/secbot/Destroy() + QDEL_NULL(weapon) + return ..() + +/mob/living/basic/bot/secbot/update_icon_state() + if(mode == BOT_HUNT) + icon_state = "[base_icon_state]-c" + return ..() + +/mob/living/basic/bot/secbot/turn_off() + ..() + update_bot_mode(new_mode = BOT_IDLE) + +/mob/living/basic/bot/secbot/on_saboteur(datum/source, disrupt_duration) + . = ..() + if(!(security_mode_flags & SECBOT_SABOTEUR_AFFECTED)) + security_mode_flags |= SECBOT_SABOTEUR_AFFECTED + addtimer(CALLBACK(src, PROC_REF(remove_saboteur_effect)), disrupt_duration) + return TRUE + +/mob/living/basic/bot/secbot/proc/remove_saboteur_effect() + security_mode_flags &= ~SECBOT_SABOTEUR_AFFECTED + +/mob/living/basic/bot/secbot/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)//shocks only make him angry + if(speed >= initial(speed) + 3) + return + speed += 3 + addtimer(VARSET_CALLBACK(src, speed, speed - 3), 6 SECONDS) + playsound(src, 'sound/machines/defib/defib_zap.ogg', 50) + visible_message(span_warning("[src] shakes and speeds up!")) + +/mob/living/basic/bot/secbot/Exited(atom/movable/gone, direction) + . = ..() + if(gone == weapon) + weapon = null + update_appearance() + +// Variables sent to TGUI +/mob/living/basic/bot/secbot/ui_data(mob/user) + var/list/data = ..() + if(!(bot_access_flags & BOT_COVER_LOCKED) || HAS_SILICON_ACCESS(user)) + data["custom_controls"]["check_id"] = security_mode_flags & SECBOT_CHECK_IDS + data["custom_controls"]["check_weapons"] = security_mode_flags & SECBOT_CHECK_WEAPONS + data["custom_controls"]["check_warrants"] = security_mode_flags & SECBOT_CHECK_RECORDS + data["custom_controls"]["handcuff_targets"] = security_mode_flags & SECBOT_HANDCUFF_TARGET + data["custom_controls"]["arrest_alert"] = security_mode_flags & SECBOT_DECLARE_ARRESTS + return data + +// Actions received from TGUI +/mob/living/basic/bot/secbot/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + var/mob/user = ui.user + if(. || (bot_access_flags & BOT_COVER_LOCKED && !HAS_SILICON_ACCESS(user))) + return + + switch(action) + if("check_id") + security_mode_flags ^= SECBOT_CHECK_IDS + return TRUE + if("check_weapons") + security_mode_flags ^= SECBOT_CHECK_WEAPONS + return TRUE + if("check_warrants") + security_mode_flags ^= SECBOT_CHECK_RECORDS + return TRUE + if("handcuff_targets") + security_mode_flags ^= SECBOT_HANDCUFF_TARGET + return TRUE + if("arrest_alert") + security_mode_flags ^= SECBOT_DECLARE_ARRESTS + return TRUE + + +/mob/living/basic/bot/secbot/attack_hand(mob/living/carbon/human/user, list/modifiers) + + // Turns an oversight into a feature. Beepsky will now announce when pacifists taunt him over sec comms. + if(HAS_TRAIT(user, TRAIT_PACIFISM)) + user.visible_message(span_notice("[user] taunts [src], daring [p_them()] to give chase!"), \ + span_notice("You taunt [src], daring [p_them()] to chase you!"), span_hear("You hear someone shout a daring taunt!"), DEFAULT_MESSAGE_RANGE, user) + speak("Taunted by pacifist scumbag [RUNECHAT_BOLD("[user]")] in [get_area(src)].", radio_channel) + + // Interrupt the attack chain. We've already handled this scenario for pacifists. + return + + return ..() + +/mob/living/basic/bot/secbot/proc/retrieve_emag_message() + audible_message(span_danger("[src] buzzes oddly!")) + +/mob/living/basic/bot/secbot/emag_act(mob/user, obj/item/card/emag/emag_card) + . = ..() + if(!(bot_access_flags & BOT_COVER_EMAGGED)) + return + if(user) + balloon_alert(user, "target assessment circuits shorted") + + retrieve_emag_message() + security_mode_flags &= ~SECBOT_DECLARE_ARRESTS + update_appearance() + return TRUE + +/mob/living/basic/bot/secbot/proc/post_arrest(mob/living/carbon/current_target) + playsound(src, SFX_LAW, 50, FALSE) + +/mob/living/basic/bot/secbot/proc/post_stun(mob/living/carbon/current_target, harm = FALSE) + flick("[base_icon_state]-c", src) + var/threat = 5 || ai_controller.blackboard[BB_CURRENT_CRIMINAL_ASSESSMENT] + if(security_mode_flags & SECBOT_DECLARE_ARRESTS) + var/area/location = get_area(src) + speak("[security_mode_flags & SECBOT_HANDCUFF_TARGET ? "Arresting" : "Detaining"] level [threat] scumbag [RUNECHAT_BOLD("[current_target]")] in [location].", radio_channel) + payment_check(current_target) + update_bot_mode(new_mode = BOT_PREP_ARREST) + +/mob/living/basic/bot/secbot/explode() + var/atom/drop_location = drop_location() + retrieve_secbot_drops(drop_location) + new /obj/effect/decal/cleanable/blood/oil(loc) + return ..() + +/mob/living/basic/bot/secbot/proc/retrieve_secbot_drops(atom/drop_location) + var/obj/item/bot_assembly/secbot/secbot_assembly = new(drop_location) + secbot_assembly.build_step = ASSEMBLY_FIRST_STEP + secbot_assembly.add_overlay("hs_hole") + secbot_assembly.created_name = name + new /obj/item/assembly/prox_sensor(drop_location) + drop_part(weapon, drop_location) + +/mob/living/basic/bot/secbot/proc/on_entered(datum/source, atom/movable/to_be_tripped) + SIGNAL_HANDLER + var/mob/living/possible_target = ai_controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET] + if(!has_gravity() || !ismob(to_be_tripped) || !possible_target) + return + var/mob/living/carbon/tripped_mob = to_be_tripped + if(istype(tripped_mob) && !in_range(src, possible_target)) + knockOver(tripped_mob) + +/// Returns true if the current target is unable to pay to be detained/arrested +/mob/living/basic/bot/secbot/proc/payment_check(mob/living/carbon/human/human_target) + var/fair_market_price = (security_mode_flags & SECBOT_HANDCUFF_TARGET) ? price_arrest : price_detain + if(fair_market_price <= 0) + return FALSE + if(!ishuman(human_target)) + return FALSE + var/obj/item/card/id/target_id = human_target.get_idcard() + if(!target_id) + say("Unable to pay fine: No ID card found.") + return TRUE + var/datum/bank_account/insurance = target_id.registered_account + if(!insurance) + say("Unable to pay fine: No bank account found.") + return TRUE + if(!insurance.adjust_money(-fair_market_price, "Securitron fine")) + say("Unable to pay fine: Not enough funds in account.") + return TRUE + + SSeconomy.get_dep_account(payment_department)?.adjust_money(fair_market_price) + say("Fine paid: Thank you for your compliance. Your account been charged [fair_market_price] [MONEY_NAME].") + return FALSE + +/mob/living/basic/bot/secbot/generate_speak_list() + var/static/list/secbot_lines = list( + BEEPSKY_VOICED_CRIMINAL_DETECTED = 'sound/mobs/non-humanoids/beepsky/criminal.ogg', + BEEPSKY_VOICED_FREEZE = 'sound/mobs/non-humanoids/beepsky/freeze.ogg', + BEEPSKY_VOICED_JUSTICE = 'sound/mobs/non-humanoids/beepsky/justice.ogg', + BEEPSKY_VOICED_YOUR_MOVE = 'sound/mobs/non-humanoids/beepsky/creep.ogg', + BEEPSKY_VOICED_I_AM_THE_LAW = 'sound/mobs/non-humanoids/beepsky/iamthelaw.ogg', + BEEPSKY_VOICED_SECURE_DAY = 'sound/mobs/non-humanoids/beepsky/secureday.ogg', + ) + return secbot_lines + + +/mob/living/basic/bot/secbot/proc/judgement_criteria() + var/final = FALSE + if(bot_access_flags & BOT_COVER_EMAGGED) + final |= JUDGE_EMAGGED + if(security_mode_flags & SECBOT_CHECK_IDS) + final |= JUDGE_IDCHECK + if(security_mode_flags & SECBOT_CHECK_RECORDS) + final |= JUDGE_RECORDCHECK + if(security_mode_flags & SECBOT_CHECK_WEAPONS) + final |= JUDGE_WEAPONCHECK + if(security_mode_flags & SECBOT_SABOTEUR_AFFECTED) + final |= JUDGE_CHILLOUT + return final + +/mob/living/basic/bot/secbot/proc/add_arrest_component() + AddComponent(/datum/component/stun_n_cuff,\ + stun_sound = stun_sound,\ + post_stun_callback = CALLBACK(src, PROC_REF(post_stun)),\ + post_arrest_callback = CALLBACK(src, PROC_REF(post_arrest)),\ + handcuff_type = cuff_type,\ + ) diff --git a/code/modules/mob/living/basic/bots/secbot/secbot_abilities.dm b/code/modules/mob/living/basic/bots/secbot/secbot_abilities.dm new file mode 100644 index 00000000000..23340fe22a0 --- /dev/null +++ b/code/modules/mob/living/basic/bots/secbot/secbot_abilities.dm @@ -0,0 +1,12 @@ +/datum/action/cooldown/mob_cooldown/bot/sword + name = "Energy Sword" + desc = "Turn your sword off/on!" + button_icon = 'icons/obj/weapons/transforming_energy.dmi' + button_icon_state = "e_sword_on" + cooldown_time = 0 SECONDS + click_to_activate = FALSE + +/datum/action/cooldown/mob_cooldown/bot/sword/Activate(mob/living/firer, atom/target) + var/obj/item/melee/energy/sword/saber/my_sword = locate() in owner + INVOKE_ASYNC(my_sword, TYPE_PROC_REF(/obj/item, attack_self), owner) + return TRUE diff --git a/code/modules/mob/living/basic/bots/secbot/secbot_ai.dm b/code/modules/mob/living/basic/bots/secbot/secbot_ai.dm new file mode 100644 index 00000000000..6aadd73fd21 --- /dev/null +++ b/code/modules/mob/living/basic/bots/secbot/secbot_ai.dm @@ -0,0 +1,91 @@ +/datum/ai_controller/basic_controller/bot/secbot + blackboard = list( + BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic/secbot, + BB_UNREACHABLE_LIST_COOLDOWN = 1 MINUTES, + BB_ALWAYS_IGNORE_FACTION = TRUE, + ) + planning_subtrees = list( + /datum/ai_planning_subtree/escape_captivity/pacifist, + /datum/ai_planning_subtree/respond_to_summon, + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/arrest_target, + /datum/ai_planning_subtree/find_patrol_beacon, + ) + reset_keys = list( + BB_BEACON_TARGET, + BB_PREVIOUS_BEACON_TARGET, + BB_BOT_SUMMON_TARGET, + ) + +/datum/targeting_strategy/basic/secbot/can_attack(mob/living/living_mob, atom/the_target, vision_range) + var/datum/ai_controller/basic_controller/bot/my_controller = living_mob.ai_controller + if(isnull(my_controller)) + return FALSE + if(!ishuman(the_target) || LAZYACCESS(my_controller.blackboard[BB_TEMPORARY_IGNORE_LIST], the_target)) + return FALSE + var/mob/living/carbon/human/human_target = the_target + if(human_target.handcuffed || human_target.stat != CONSCIOUS) + return FALSE + if(locate(human_target) in my_controller.blackboard[BB_BASIC_MOB_RETALIATE_LIST]) + return TRUE + var/mob/living/basic/bot/secbot/my_bot = living_mob + if(human_target.IsParalyzed() && !(my_bot.security_mode_flags & SECBOT_HANDCUFF_TARGET)) + return FALSE + var/assess_flags = my_bot.judgement_criteria() + var/assessed_threat = human_target.assess_threat(assess_flags) + if(assessed_threat > THREAT_ASSESS_DANGEROUS) + my_controller.set_blackboard_key(BB_CURRENT_CRIMINAL_ASSESSMENT, assessed_threat) + return (assessed_threat > THREAT_ASSESS_DANGEROUS) + + +/datum/ai_controller/basic_controller/bot/secbot/TryPossessPawn(atom/new_pawn) + . = ..() + if(. & AI_CONTROLLER_INCOMPATIBLE) + return + RegisterSignal(new_pawn, COMSIG_AI_BLACKBOARD_KEY_SET(BB_BASIC_MOB_CURRENT_TARGET), PROC_REF(on_target_set)) + RegisterSignal(new_pawn, COMSIG_AI_BLACKBOARD_KEY_CLEARED(BB_BASIC_MOB_CURRENT_TARGET), PROC_REF(on_clear_target)) + +/datum/ai_controller/basic_controller/bot/secbot/proc/on_target_set() + SIGNAL_HANDLER + var/datum/action/cooldown/bot_announcement/announcement = blackboard[BB_ANNOUNCE_ABILITY] + var/threat_level = 5 || blackboard[BB_CURRENT_CRIMINAL_ASSESSMENT] + INVOKE_ASYNC(announcement, TYPE_PROC_REF(/datum/action/cooldown/bot_announcement, announce), "Level [threat_level] infraction alert!") + playsound(pawn, pick( + 'sound/mobs/non-humanoids/beepsky/criminal.ogg', + 'sound/mobs/non-humanoids/beepsky/justice.ogg', + 'sound/mobs/non-humanoids/beepsky/freeze.ogg', + ), 50, FALSE) + var/mob/living/basic/bot/secbot/my_bot = pawn + my_bot.update_bot_mode(new_mode = BOT_HUNT) + +/datum/ai_controller/basic_controller/bot/secbot/proc/on_clear_target() + SIGNAL_HANDLER + clear_blackboard_key(BB_CURRENT_CRIMINAL_ASSESSMENT) + +/datum/ai_planning_subtree/arrest_target + ///what behavior do we use when arresting? + var/datum/ai_behavior/arrest_behavior = /datum/ai_behavior/basic_melee_attack/interact_once/bot + +/datum/ai_planning_subtree/arrest_target/SelectBehaviors(datum/ai_controller/basic_controller/bot/controller, seconds_per_tick) + var/mob/living/carbon/my_target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET] + if(QDELETED(my_target) || !istype(my_target) || my_target.handcuffed) + controller.clear_blackboard_key(BB_BASIC_MOB_CURRENT_TARGET) + return + + var/mob/living/basic/bot/secbot/my_bot = controller.pawn + var/bot_flags = my_bot.security_mode_flags + if(my_target.IsParalyzed() && !(bot_flags & SECBOT_HANDCUFF_TARGET)) + controller.clear_blackboard_key(BB_BASIC_MOB_CURRENT_TARGET) + return + + controller.queue_behavior(arrest_behavior, BB_BASIC_MOB_CURRENT_TARGET, BB_TARGETING_STRATEGY) + return SUBTREE_RETURN_FINISH_PLANNING + +/datum/ai_behavior/basic_melee_attack/interact_once/bot + movement_behavior = /datum/ai_movement/basic_avoidance + +/datum/ai_behavior/basic_melee_attack/interact_once/bot/finish_action(datum/ai_controller/controller, succeeded, target_key, targeting_strategy_key, hiding_location_key) + var/mob/living/carbon/human/human_target = controller.blackboard[target_key] + if(!isnull(human_target) && human_target.handcuffed) + controller.remove_from_blackboard_lazylist_key(BB_BASIC_MOB_RETALIATE_LIST, human_target) + return ..() diff --git a/code/modules/mob/living/basic/bots/secbot/secbot_subtypes.dm b/code/modules/mob/living/basic/bots/secbot/secbot_subtypes.dm new file mode 100644 index 00000000000..c34dca95156 --- /dev/null +++ b/code/modules/mob/living/basic/bots/secbot/secbot_subtypes.dm @@ -0,0 +1,65 @@ +/mob/living/basic/bot/secbot/beepsky + name = "Commander Beep O'sky" + desc = "It's Commander Beep O'sky! Officially the superior officer of all bots on station, Beepsky remains as humble and dedicated to the law as the day he was first fabricated." + bot_mode_flags = BOT_MODE_ON | BOT_MODE_AUTOPATROL | BOT_MODE_REMOTE_ENABLED + commissioned = TRUE + + +/mob/living/basic/bot/secbot/beepsky/officer + name = "Officer Beepsky" + desc = "It's Officer Beepsky! Powered by a potato and a shot of whiskey, and with a sturdier reinforced chassis, too." + health = 45 + +/mob/living/basic/bot/secbot/beepsky/officer/Initialize(mapload) + . = ..() + // Beepsky hates people scanning them + RegisterSignal(src, COMSIG_MOVABLE_SPY_STEALING, PROC_REF(on_spy_scan)) + +/mob/living/basic/bot/secbot/beepsky/officer/proc/on_spy_scan(datum/source, mob/user) + SIGNAL_HANDLER + + ai_controller?.insert_blackboard_key_lazylist(BB_BASIC_MOB_RETALIATE_LIST, user) + +/mob/living/basic/bot/secbot/beepsky/ofitser + name = "Prison Ofitser" + desc = "Powered by the tears and sweat of laborers." + bot_mode_flags = ~(BOT_MODE_CAN_BE_SAPIENT|BOT_MODE_AUTOPATROL) + +/mob/living/basic/bot/secbot/beepsky/armsky + name = "Sergeant-At-Armsky" + desc = "It's Sergeant-At-Armsky! He's a disgruntled assistant to the warden that would probably shoot you if he had hands." + health = 45 + bot_mode_flags = ~(BOT_MODE_CAN_BE_SAPIENT|BOT_MODE_AUTOPATROL) + security_mode_flags = SECBOT_DECLARE_ARRESTS | SECBOT_CHECK_IDS | SECBOT_CHECK_RECORDS | SECBOT_CHECK_WEAPONS + +/mob/living/basic/bot/secbot/beepsky/jr + name = "Officer Pipsqueak" + desc = "It's Commander Beep O'sky's smaller, just-as aggressive cousin, Pipsqueak." + commissioned = FALSE + +/mob/living/basic/bot/secbot/beepsky/jr/Initialize(mapload) + . = ..() + update_transform(0.8) + +/mob/living/basic/bot/secbot/pingsky + name = "Officer Pingsky" + desc = "It's Officer Pingsky! Delegated to satellite guard duty for harbouring anti-human sentiment." + light_color = "#62baf5" + radio_channel = RADIO_CHANNEL_AI_PRIVATE + bot_mode_flags = ~(BOT_MODE_CAN_BE_SAPIENT|BOT_MODE_AUTOPATROL) + security_mode_flags = SECBOT_DECLARE_ARRESTS | SECBOT_CHECK_IDS | SECBOT_CHECK_RECORDS + +/mob/living/basic/bot/secbot/genesky + name = "Officer Genesky" + desc = "A beefy variant of the standard securitron model." + health = 50 + faction = list(FACTION_NANOTRASEN_PRIVATE) + bot_mode_flags = BOT_MODE_ON + bot_access_flags = BOT_COVER_LOCKED | BOT_COVER_EMAGGED + +/mob/living/basic/bot/secbot/beepsky/explode() + var/atom/current_location = drop_location() + new /obj/item/stock_parts/power_store/cell/potato(current_location) + var/obj/item/reagent_containers/cup/glass/drinkingglass/shotglass/drinking_oil = new(current_location) + drinking_oil.reagents.add_reagent(/datum/reagent/consumable/ethanol/whiskey, 15) + return ..() diff --git a/code/modules/mob/living/basic/bots/secbot/super_beepsky.dm b/code/modules/mob/living/basic/bots/secbot/super_beepsky.dm new file mode 100644 index 00000000000..1f82db49c7a --- /dev/null +++ b/code/modules/mob/living/basic/bots/secbot/super_beepsky.dm @@ -0,0 +1,99 @@ +/mob/living/basic/bot/secbot/grievous //This bot is powerful. If you managed to get 4 eswords somehow, you deserve this horror. Emag him for best results. + name = "General Beepsky" + desc = "Is that a secbot with four eswords in its arms...?" + icon = 'icons/mob/silicon/aibots.dmi' + icon_state = "grievous" + base_icon_state = "grievous" + health = 150 + maxHealth = 150 + ai_controller = /datum/ai_controller/basic_controller/bot/secbot/super_beepsky + baton_type = /obj/item/melee/energy/sword/saber + speed = 4 //he's a fast fucker + ///chance we block bullets + var/block_chance = 50 + ///is our sword currently active? + var/sword_active = FALSE + +/mob/living/basic/bot/secbot/grievous/Initialize(mapload) + . = ..() + RegisterSignal(weapon, COMSIG_TRANSFORMING_ON_TRANSFORM, PROC_REF(on_weapon_transform)) + var/static/list/abilities = list( + /datum/action/cooldown/mob_cooldown/bot/sword = null, + ) + grant_actions_by_list(abilities) + INVOKE_ASYNC(weapon, TYPE_PROC_REF(/obj/item, attack_self), src) + RegisterSignal(src, COMSIG_ATOM_PRE_BULLET_ACT, PROC_REF(block_bullets)) + + +/mob/living/basic/bot/secbot/grievous/check_block(atom/hit_by, damage, attack_text = "the attack", attack_type = MELEE_ATTACK, armour_penetration = 0, damage_type = BRUTE) + . = ..() + if(. & FAILED_BLOCK) + return . + + return (sword_active && prob(block_chance) ? SUCCESSFUL_BLOCK : FAILED_BLOCK) + +/mob/living/basic/bot/secbot/grievous/proc/on_weapon_transform(obj/item/source, mob/user, active) + SIGNAL_HANDLER + if(active) + visible_message(span_warning("[src] ignites his energy swords!")) + sword_active = active + update_icon_state() + +/mob/living/basic/bot/secbot/grievous/add_arrest_component() //i dont think we'll be arresting people... + return + +/mob/living/basic/bot/secbot/grievous/proc/block_bullets(datum/source, obj/projectile/hitting_projectile) + SIGNAL_HANDLER + + if(stat != CONSCIOUS ) + return NONE + + if(!sword_active || !prob(block_chance)) + return NONE + + visible_message(span_warning("[source] deflects [hitting_projectile] with its energy swords!")) + playsound(source, 'sound/items/weapons/blade1.ogg', 50, TRUE) + return COMPONENT_BULLET_BLOCKED + +/mob/living/basic/bot/secbot/grievous/on_entered(datum/source, atom/movable/movable_target) + . = ..() + if(!ismob(movable_target) || !ai_controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET] == movable_target) + return + visible_message(span_warning("[src] flails his swords and cuts [movable_target]!")) + playsound(src, 'sound/mobs/non-humanoids/beepsky/beepskyspinsabre.ogg' , 100, TRUE, -1) + INVOKE_ASYNC(src, TYPE_PROC_REF(/mob, ClickOn), movable_target) + + +/mob/living/basic/bot/secbot/grievous/update_icon_state() + . = ..() + + icon_state = "[base_icon_state][ sword_active ? "-c" : ""]" + +/mob/living/basic/bot/secbot/grievous/Destroy() + QDEL_NULL(weapon) + return ..() + +/mob/living/basic/bot/secbot/grievous/early_melee_attack(atom/target, list/modifiers, ignore_cooldown) + . = ..() + if(.) + return + INVOKE_ASYNC(weapon, TYPE_PROC_REF(/obj/item, melee_attack_chain), src, target) + playsound(src, 'sound/items/weapons/blade1.ogg', 50, TRUE, -1) + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN + +/mob/living/basic/bot/secbot/grievous/explode() + var/atom/drop_location = drop_location() + //Parent is dropping the weapon, so let's drop 3 more to make up for it. + for(var/i in 0 to 3) + drop_part(baton_type, drop_location) + + return ..() + + +/mob/living/basic/bot/secbot/grievous/toy //A toy version of general beepsky! + name = "Genewul Bweepskee" + desc = "An adorable looking secbot with four toy swords taped to its arms" + health = 50 + maxHealth = 50 + block_chance = 0 + baton_type = /obj/item/toy/sword diff --git a/code/modules/mob/living/basic/bots/secbot/super_beepsky_ai.dm b/code/modules/mob/living/basic/bots/secbot/super_beepsky_ai.dm new file mode 100644 index 00000000000..effd9a98cab --- /dev/null +++ b/code/modules/mob/living/basic/bots/secbot/super_beepsky_ai.dm @@ -0,0 +1,16 @@ +/datum/ai_controller/basic_controller/bot/secbot/super_beepsky + + planning_subtrees = list( + /datum/ai_planning_subtree/escape_captivity/pacifist, + /datum/ai_planning_subtree/respond_to_summon, + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/basic_melee_attack_subtree, + /datum/ai_planning_subtree/find_patrol_beacon, + ) + +/datum/ai_controller/basic_controller/bot/secbot/super_beepsky/on_target_set() + . = ..() + var/mob/living/basic/bot/secbot/grievous/super_beeps = pawn + if(!super_beeps.sword_active) + INVOKE_ASYNC(super_beeps.weapon, TYPE_PROC_REF(/obj/item, attack_self), super_beeps) + super_beeps.visible_message("[super_beeps] points at [blackboard[BB_BASIC_MOB_CURRENT_TARGET]]!") diff --git a/code/modules/mob/living/basic/clown/clown.dm b/code/modules/mob/living/basic/clown/clown.dm index ce3dab5ccf8..8a8fce3c1e7 100644 --- a/code/modules/mob/living/basic/clown/clown.dm +++ b/code/modules/mob/living/basic/clown/clown.dm @@ -57,7 +57,7 @@ if (!istype(attacker)) return for (var/mob/living/basic/clown/harbringer in oview(src, 7)) - harbringer.ai_controller.insert_blackboard_key_lazylist(BB_BASIC_MOB_RETALIATE_LIST, attacker) + harbringer.ai_controller.set_blackboard_key_assoc_lazylist(BB_BASIC_MOB_RETALIATE_LIST, attacker, world.time) /mob/living/basic/clown/melee_attack(atom/target, list/modifiers, ignore_cooldown = FALSE) if(!istype(target, /obj/item/food/grown/banana/bunch)) diff --git a/code/modules/mob/living/basic/drone/inventory.dm b/code/modules/mob/living/basic/drone/inventory.dm index acacdb0e265..8253fafb98a 100644 --- a/code/modules/mob/living/basic/drone/inventory.dm +++ b/code/modules/mob/living/basic/drone/inventory.dm @@ -58,7 +58,7 @@ if(equipping.pulledby) equipping.pulledby.stop_pulling() - equipping.screen_loc = null // will get moved if inventory is visible + hud_used?.update_inventory_slot(slot) equipping.forceMove(src) //This has to come before has_equipped is called. SET_PLANE_EXPLICIT(equipping, ABOVE_HUD_PLANE, src) diff --git a/code/modules/mob/living/basic/drone/visuals_icons.dm b/code/modules/mob/living/basic/drone/visuals_icons.dm index 59952d8d249..3714c27deca 100644 --- a/code/modules/mob/living/basic/drone/visuals_icons.dm +++ b/code/modules/mob/living/basic/drone/visuals_icons.dm @@ -22,18 +22,13 @@ update_inv_internal_storage() /mob/living/basic/drone/proc/update_inv_internal_storage() - if(internal_storage && client && hud_used?.hud_shown) - internal_storage.screen_loc = ui_drone_storage - client.screen += internal_storage - + hud_used?.update_inventory_slot(ITEM_SLOT_DEX_STORAGE) /mob/living/basic/drone/update_worn_head() remove_overlay(DRONE_HEAD_LAYER) + hud_used?.update_inventory_slot(ITEM_SLOT_HEAD) if(head) - if(client && hud_used?.hud_shown) - head.screen_loc = ui_drone_head - client.screen += head var/used_head_icon = 'icons/mob/clothing/head/utility.dmi' if(istype(head, /obj/item/clothing/mask)) used_head_icon = 'icons/mob/clothing/mask.dmi' 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 a90b4e0dd4f..66cd498ccd6 100644 --- a/code/modules/mob/living/basic/farm_animals/bee/_bee.dm +++ b/code/modules/mob/living/basic/farm_animals/bee/_bee.dm @@ -111,18 +111,18 @@ /mob/living/basic/bee/early_melee_attack(atom/target, list/modifiers) . = ..() - if(!.) - return FALSE + if(.) + return if(istype(target, /obj/machinery/hydroponics)) var/obj/machinery/hydroponics/hydro = target pollinate(hydro) - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN if(istype(target, /obj/structure/beebox)) var/obj/structure/beebox/hive = target handle_habitation(hive) - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN /mob/living/basic/bee/proc/handle_habitation(obj/structure/beebox/hive) if(hive == beehome) //if its our home, we enter or exit it diff --git a/code/modules/mob/living/basic/farm_animals/pony.dm b/code/modules/mob/living/basic/farm_animals/pony.dm index a44d042809c..3e9ad63ad39 100644 --- a/code/modules/mob/living/basic/farm_animals/pony.dm +++ b/code/modules/mob/living/basic/farm_animals/pony.dm @@ -119,6 +119,10 @@ whinny_angrily() +/mob/living/basic/pony/get_shove_flags(mob/living/shover, obj/item/weapon) + . = ..() + . |= SHOVE_CAN_STAGGER + /datum/ai_controller/basic_controller/pony blackboard = list( BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic, diff --git a/code/modules/mob/living/basic/guardian/guardian_creator.dm b/code/modules/mob/living/basic/guardian/guardian_creator.dm index ff83c69a75e..b95b424af9e 100644 --- a/code/modules/mob/living/basic/guardian/guardian_creator.dm +++ b/code/modules/mob/living/basic/guardian/guardian_creator.dm @@ -25,6 +25,10 @@ GLOBAL_LIST_INIT(guardian_radial_images, setup_guardian_radial()) var/use_message = span_holoparasite("You shuffle the deck...") /// Message sent when it's already used. var/used_message = span_holoparasite("All the cards seem to be blank now.") + /// Examine description if the creator is unused + var/unused_description = span_holoparasite("You feel beckoned to draw one...") + /// Examine description if the creator is used. + var/used_description = span_holoparasite("They seem rather uninteresting.") /// Failure message if no ghost picks the holopara. var/failure_message = span_boldholoparasite("..And draw a card! It's... blank? Maybe you should try again later.") /// Failure message if we don't allow lings. @@ -113,6 +117,13 @@ GLOBAL_LIST_INIT(guardian_radial_images, setup_guardian_radial()) to_chat(user, failure_message) used = FALSE +/obj/item/guardian_creator/examine(mob/user) + . = ..() + if(used) + . += span_holoparasite(used_description) + else + . += span_holoparasite(unused_description) + /obj/item/guardian_creator/proc/on_reimbursed(datum/source) SIGNAL_HANDLER was_refunded = TRUE @@ -185,6 +196,8 @@ GLOBAL_LIST_INIT(guardian_radial_images, setup_guardian_radial()) allow_changeling = FALSE use_message = span_holoparasite("You start to power on the injector...") used_message = span_holoparasite("The injector has already been used.") + unused_description = span_holoparasite("Its vial is filled with a violent storm of color.") + used_description = span_holoparasite("Nothing seems to be loaded in the injector.") failure_message = span_boldholoparasite("...ERROR. BOOT SEQUENCE ABORTED. AI FAILED TO INTIALIZE. PLEASE CONTACT SUPPORT OR TRY AGAIN LATER.") ling_failure = span_boldholoparasite("The holoparasites recoil in horror. They want nothing to do with a creature like you.") success_message = span_holoparasite("%GUARDIAN is now online!") @@ -198,6 +211,8 @@ GLOBAL_LIST_INIT(guardian_radial_images, setup_guardian_radial()) theme = GUARDIAN_THEME_CARP use_message = span_holoparasite("You put the fishsticks in your mouth...") used_message = span_holoparasite("Someone's already taken a bite out of these fishsticks! Ew.") + unused_description = span_holoparasite("They look hot and ready to eat!") + used_description = span_holoparasite("They look soggy and old...") failure_message = span_boldholoparasite("You couldn't catch any carp spirits from the seas of Lake Carp. Maybe there are none, maybe you fucked up.") ling_failure = span_boldholoparasite("Carp'sie seems to not have taken you as the chosen one. Maybe it's because of your horrifying origin.") success_message = span_holoparasite("%GUARDIAN has been caught!") @@ -212,6 +227,8 @@ GLOBAL_LIST_INIT(guardian_radial_images, setup_guardian_radial()) theme = GUARDIAN_THEME_MINER use_message = span_holoparasite("You pierce your skin with the shard...") used_message = span_holoparasite("This shard seems to have lost all its power...") + unused_description = span_holoparasite("It glows with an otherwordly power...") + used_description = span_holoparasite("It looks dull, with dried blood on the tip.") failure_message = span_boldholoparasite("The shard hasn't reacted at all. Maybe try again later...") ling_failure = span_boldholoparasite("The power of the shard seems to not react with your horrifying, mutated body.") success_message = span_holoparasite("%GUARDIAN has appeared!") diff --git a/code/modules/mob/living/basic/guardian/guardian_types/dextrous.dm b/code/modules/mob/living/basic/guardian/guardian_types/dextrous.dm index fc4ec678837..b3d37a28e9e 100644 --- a/code/modules/mob/living/basic/guardian/guardian_types/dextrous.dm +++ b/code/modules/mob/living/basic/guardian/guardian_types/dextrous.dm @@ -92,7 +92,7 @@ if(equipping.pulledby) equipping.pulledby.stop_pulling() - equipping.screen_loc = null // will get moved if inventory is visible + hud_used?.update_inventory_slot(slot) equipping.forceMove(src) SET_PLANE_EXPLICIT(equipping, ABOVE_HUD_PLANE, src) @@ -106,10 +106,7 @@ return ITEM_SLOT_DEX_STORAGE /mob/living/basic/guardian/dextrous/proc/update_inv_internal_storage() - if(isnull(internal_storage) || isnull(client) || !hud_used?.hud_shown) - return - internal_storage.screen_loc = ui_back - client.screen += internal_storage + hud_used?.update_inventory_slot(ITEM_SLOT_DEX_STORAGE) /mob/living/basic/guardian/dextrous/regenerate_icons() update_inv_internal_storage() diff --git a/code/modules/mob/living/basic/guardian/guardian_types/gaseous.dm b/code/modules/mob/living/basic/guardian/guardian_types/gaseous.dm index a70bd01f43b..7db7107e109 100644 --- a/code/modules/mob/living/basic/guardian/guardian_types/gaseous.dm +++ b/code/modules/mob/living/basic/guardian/guardian_types/gaseous.dm @@ -33,20 +33,15 @@ . = ..() if (QDELETED(src)) return - RegisterSignal(summoner, COMSIG_LIVING_IGNITED, PROC_REF(on_summoner_ignited)) + ADD_TRAIT(summoner, TRAIT_NOFIRE, REF(src)) RegisterSignal(summoner, COMSIG_LIVING_LIFE, PROC_REF(on_summoner_life)) /mob/living/basic/guardian/gaseous/cut_summoner(different_person) if (!isnull(summoner)) - UnregisterSignal(summoner, list(COMSIG_LIVING_IGNITED, COMSIG_LIVING_LIFE)) + REMOVE_TRAIT(summoner, TRAIT_NOFIRE, REF(src)) + UnregisterSignal(summoner, COMSIG_LIVING_LIFE) return ..() -/// Prevent our summoner from being on fire -/mob/living/basic/guardian/gaseous/proc/on_summoner_ignited(mob/living/source) - SIGNAL_HANDLER - source.extinguish_mob() - source.set_fire_stacks(0, remove_wet_stacks = FALSE) - /// Maintain our summoner at a stable body temperature /mob/living/basic/guardian/gaseous/proc/on_summoner_life(mob/living/source, seconds_per_tick) SIGNAL_HANDLER diff --git a/code/modules/mob/living/basic/guardian/guardian_types/support.dm b/code/modules/mob/living/basic/guardian/guardian_types/support.dm index 5ddc07e809b..503dc93b778 100644 --- a/code/modules/mob/living/basic/guardian/guardian_types/support.dm +++ b/code/modules/mob/living/basic/guardian/guardian_types/support.dm @@ -112,6 +112,8 @@ /// Validate whether we can teleport this object /datum/action/cooldown/mob_cooldown/guardian_bluespace_beacon/proc/can_teleport(mob/living/source, atom/movable/target) + if(!istype(target)) // Turfs + return FALSE if (isnull(beacon)) source.balloon_alert(source, "no beacon!") return FALSE @@ -126,7 +128,7 @@ if (target.anchored) target.balloon_alert(source, "it won't budge!") return FALSE - if(beacon.z != target.z) + if((beacon.z != target.z) && !(target.z in SSmapping.get_connected_levels(beacon.z))) target.balloon_alert(source, "too far from beacon!") return FALSE return TRUE diff --git a/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp.dm b/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp.dm index 1000c919b11..7d4c74747a3 100644 --- a/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp.dm +++ b/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp.dm @@ -51,22 +51,22 @@ /mob/living/basic/mining/ice_whelp/early_melee_attack(atom/target, list/modifiers, ignore_cooldown) . = ..() - if(!.) - return FALSE + if(.) + return if(istype(target, /obj/structure/flora/rock/icy)) create_sculpture(target) - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN if(!istype(target, type)) - return TRUE + return BASIC_MOB_CONTINUE_ATTACK_CHAIN var/mob/living/victim = target if(victim.stat != DEAD) - return TRUE + return BASIC_MOB_CONTINUE_ATTACK_CHAIN cannibalize_victim(victim) - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN /// Carve a stone into a beautiful self-portrait /mob/living/basic/mining/ice_whelp/proc/create_sculpture(atom/target) diff --git a/code/modules/mob/living/basic/illusion/illusion.dm b/code/modules/mob/living/basic/illusion/illusion.dm index 0a1a5fa3195..97a61e653f0 100644 --- a/code/modules/mob/living/basic/illusion/illusion.dm +++ b/code/modules/mob/living/basic/illusion/illusion.dm @@ -72,12 +72,16 @@ appearance = original.appearance setDir(original.dir) - maxHealth = hp - updatehealth() // re-cap health to new value + if (isnull(hp)) + maxHealth = hp + updatehealth() // re-cap health to new value - melee_damage_lower = damage - melee_damage_upper = damage - multiply_chance = replicate + if (isnull(damage)) + melee_damage_lower = damage + melee_damage_upper = damage + + if (isnull(replicate)) + multiply_chance = replicate remove_faction(FACTION_NEUTRAL) transform = initial(transform) diff --git a/code/modules/mob/living/basic/jungle/seedling/seedling.dm b/code/modules/mob/living/basic/jungle/seedling/seedling.dm index 129e7d7b2f3..49acc32e5ee 100644 --- a/code/modules/mob/living/basic/jungle/seedling/seedling.dm +++ b/code/modules/mob/living/basic/jungle/seedling/seedling.dm @@ -85,19 +85,19 @@ /mob/living/basic/seedling/early_melee_attack(atom/target, list/modifiers, ignore_cooldown) . = ..() - if(!.) - return FALSE + if(.) + return if(istype(target, /obj/machinery/hydroponics)) treat_hydro_tray(target) - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN if(isnull(held_can)) - return TRUE + return BASIC_MOB_CONTINUE_ATTACK_CHAIN if(istype(target, /obj/structure/sink) || istype(target, /obj/structure/reagent_dispensers)) held_can.melee_attack_chain(src, target) - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN ///seedlings can water trays, remove weeds, or remove dead plants diff --git a/code/modules/mob/living/basic/lavaland/bileworm/_bileworm.dm b/code/modules/mob/living/basic/lavaland/bileworm/_bileworm.dm index 0ed4359bf23..19d1fd20c6a 100644 --- a/code/modules/mob/living/basic/lavaland/bileworm/_bileworm.dm +++ b/code/modules/mob/living/basic/lavaland/bileworm/_bileworm.dm @@ -6,8 +6,8 @@ icon_living = "bileworm" icon_dead = "bileworm_dead" mob_biotypes = MOB_ORGANIC|MOB_BUG|MOB_MINING - maxHealth = 100 - health = 100 + maxHealth = 110 + health = 110 verb_say = "spittles" verb_ask = "spittles questioningly" verb_exclaim = "splutters and gurgles" @@ -30,10 +30,16 @@ ai_controller = /datum/ai_controller/basic_controller/bileworm - ///which action this mob will be given, subtypes have different attacks - var/attack_action_path = /datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/bileworm - ///which, if at all, mob this evolves into at the 30 min mark + /// Which action this mob will be given, subtypes have different attacks + var/attack_action_path = /datum/action/cooldown/mob_cooldown/bileworm_spew + /// Which, if at all, mob this evolves into at the 30 min mark var/evolve_path = /mob/living/basic/mining/bileworm/vileworm + /// Emissive icon_state + var/emissive_state = "bileworm_e" + /// Icon file used for the jumping animation + var/icon_jump = 'icons/mob/simple/lavaland/bileworm_jump.dmi' + /// Are we currently in the middle of a jump? + var/jumping = FALSE /mob/living/basic/mining/bileworm/Initialize(mapload) . = ..() @@ -42,11 +48,7 @@ if(ispath(evolve_path)) AddComponent(/datum/component/evolutionary_leap, 30 MINUTES, evolve_path) AddElement(/datum/element/content_barfer) - - //setup mob abilities - - //well, one of them has to start on infinite cooldown - var/datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/bileworm/spew_bile = new(src) + var/datum/action/cooldown/mob_cooldown/spew_bile = new attack_action_path(src) spew_bile.Grant(src) spew_bile.StartCooldownSelf(INFINITY) ai_controller?.set_blackboard_key(BB_BILEWORM_SPEW_BILE, spew_bile) @@ -61,5 +63,10 @@ /mob/living/basic/mining/bileworm/update_overlays() . = ..() - if (stat != DEAD) - . += emissive_appearance(icon, "[icon_living]_e", src) + if (stat != DEAD && !jumping) + . += emissive_appearance(icon, emissive_state, src) + +/mob/living/basic/mining/bileworm/on_attacked(datum/source, atom/attacker, attack_flags) + . = ..() + if (!(attack_flags & (ATTACKER_STAMINA_ATTACK | ATTACKER_SHOVING))) + ai_controller?.set_blackboard_key(BB_BILEWORM_SCARED, TRUE) diff --git a/code/modules/mob/living/basic/lavaland/bileworm/bileworm_actions.dm b/code/modules/mob/living/basic/lavaland/bileworm/bileworm_actions.dm index bd480cc6972..d3a45a89a76 100644 --- a/code/modules/mob/living/basic/lavaland/bileworm/bileworm_actions.dm +++ b/code/modules/mob/living/basic/lavaland/bileworm/bileworm_actions.dm @@ -2,21 +2,70 @@ name = "Resurface" desc = "Burrow underground, and then move to a new location near your target. Must spew bile to refresh." shared_cooldown = MOB_SHARED_COOLDOWN_1 | MOB_SHARED_COOLDOWN_2 + /// Damage tracker var for bileworms + var/jump_damaged = FALSE + /// How long does the jump take to perform? + var/jump_length = 1 SECONDS + /// How long do we get stunned for if we fail a jump? + var/jump_stun = 2.4 SECONDS + +/datum/action/cooldown/mob_cooldown/resurface/Grant(mob/granted_to) + . = ..() + owner?.AddElement(/datum/element/relay_attackers) /datum/action/cooldown/mob_cooldown/resurface/Activate(atom/target_atom) StartCooldownSelf(INFINITY) + StartCooldownOthers(INFINITY) burrow(owner, target_atom) //spew now off cooldown shortly StartCooldownOthers(1.5 SECONDS) -/datum/action/cooldown/mob_cooldown/resurface/proc/burrow(mob/living/burrower, atom/target) +/// Amount of frames in the jump animation +#define BILEWORM_JUMP_FRAMES 14 + +/datum/action/cooldown/mob_cooldown/resurface/proc/burrow(mob/living/burrower, atom/target, force = FALSE) var/turf/unburrow_turf = get_unburrow_turf(burrower, target) - if(!unburrow_turf) // means all the turfs nearby are station turfs or something, not lavaland + if (!unburrow_turf) // means all the turfs nearby are station turfs or something, not lavaland to_chat(burrower, span_warning("Couldn't burrow anywhere near the target!")) if(burrower.ai_controller?.ai_status == AI_STATUS_ON) //this is a valid reason to give up on a target burrower.ai_controller.clear_blackboard_key(BB_BASIC_MOB_CURRENT_TARGET) return + + if (istype(burrower, /mob/living/basic/mining/bileworm) && !force) + var/mob/living/basic/mining/bileworm/worm = burrower + new /obj/effect/temp_visual/mook_dust(get_turf(worm)) + var/old_icon_state = worm.icon_state + worm.icon_state = null + // Get rid of the base emissive + worm.jumping = TRUE + worm.update_appearance(UPDATE_OVERLAYS) + var/atom/movable/visual = worm.flick_overlay_view(mutable_appearance(worm.icon_jump, "[worm.icon_living]_jump_1"), jump_length) + visual.vis_flags |= VIS_INHERIT_ID // So you can attack it + var/atom/movable/emissive_visual = worm.flick_overlay_view(emissive_appearance(worm.icon_jump, "[worm.emissive_state]_jump_1", worm), jump_length) + // We have to manually animate these to get around BYOND icon_state animations happening in world time and not per-object + for (var/i in 2 to BILEWORM_JUMP_FRAMES) + animate(visual, time = jump_length / BILEWORM_JUMP_FRAMES, icon_state = "[worm.icon_living]_jump_[i]", flags = ANIMATION_CONTINUE) + animate(emissive_visual, time = jump_length / BILEWORM_JUMP_FRAMES, icon_state = "[worm.emissive_state]_jump_[i]", flags = ANIMATION_CONTINUE) + jump_damaged = FALSE + RegisterSignal(worm, COMSIG_ATOM_WAS_ATTACKED, PROC_REF(on_attacked)) + // Not in an if check direclty to reduce duplicate code + var/jump_result = do_after(worm, jump_length, worm, hidden = TRUE, extra_checks = CALLBACK(src, PROC_REF(damage_check))) + UnregisterSignal(worm, COMSIG_ATOM_WAS_ATTACKED) + if (worm.icon_state == null) + worm.icon_state = old_icon_state + worm.jumping = FALSE + worm.update_appearance(UPDATE_OVERLAYS) + if (!jump_result && jump_stun) + if (!QDELETED(visual)) + QDEL_NULL(visual) + QDEL_NULL(emissive_visual) + worm.flick_overlay_view(mutable_appearance('icons/effects/effects.dmi', "dazed"), jump_stun) + worm.Stun(jump_stun) + addtimer(CALLBACK(src, PROC_REF(burrow_again), burrower, target), jump_stun) + return + + burrower.ai_controller?.set_blackboard_key(BB_BILEWORM_SCARED, FALSE) playsound(burrower, 'sound/effects/break_stone.ogg', 50, TRUE) new /obj/effect/temp_visual/mook_dust(get_turf(burrower)) ADD_TRAIT(burrower, TRAIT_GODMODE, REF(src)) @@ -29,59 +78,189 @@ REMOVE_TRAIT(burrower, TRAIT_GODMODE, REF(src)) burrower.RemoveInvisibility(type) +#undef BILEWORM_JUMP_FRAMES + +/datum/action/cooldown/mob_cooldown/resurface/proc/burrow_again(mob/living/burrower, atom/target) + if (!QDELETED(burrower) && !burrower.stat) + // Burrow immediatelly after being stunned out of the first jump to avoid chainstuns + burrow(burrower, target, force = TRUE) + +/datum/action/cooldown/mob_cooldown/resurface/proc/on_attacked(datum/source, atom/attacker, attack_flags) + SIGNAL_HANDLER + if (!(attack_flags & (ATTACKER_STAMINA_ATTACK | ATTACKER_SHOVING)) && jump_stun) + jump_damaged = TRUE + +/datum/action/cooldown/mob_cooldown/resurface/proc/damage_check() + return !jump_damaged + /datum/action/cooldown/mob_cooldown/resurface/proc/get_unburrow_turf(mob/living/burrower, atom/target) - //we want the worm to try guaranteeing a hit on a living target if it thinks it can - var/cardinal_only = FALSE - - if(isliving(target)) - var/mob/living/living_target = target - if(living_target.stat >= UNCONSCIOUS) - cardinal_only = TRUE - - var/list/potential_turfs = shuffle(oview(5, target))//get in view, shuffle - var/list/fallback_turfs = list() - for(var/turf/open/misc/chosen_one in potential_turfs)//first turf that counts as ground - if(cardinal_only && !(get_dir(chosen_one, target) in GLOB.cardinals)) - fallback_turfs.Add(chosen_one) - continue + var/list/potential_turfs = shuffle(oview(5, target)) // get in view, shuffle + for(var/turf/open/misc/chosen_one in potential_turfs) // first turf that counts as ground return chosen_one - //even if a worm can't execute someone in crit, it should not fail if it has SOMETHING to move to. - if(fallback_turfs.len) - return pick(fallback_turfs) -/datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/bileworm +/datum/action/cooldown/mob_cooldown/bileworm_spew name = "Spew Bile" - desc = "Spews bile everywhere. Must resurface after use to refresh." - projectile_type = /obj/projectile/bileworm_acid - projectile_sound = 'sound/mobs/non-humanoids/bileworm/bileworm_spit.ogg' + desc = "Spew a barrage of bile globs." shared_cooldown = MOB_SHARED_COOLDOWN_1 | MOB_SHARED_COOLDOWN_2 + cooldown_time = 3 SECONDS + /// Sound played when firing a projectile + var/projectile_sound = 'sound/mobs/non-humanoids/bileworm/bileworm_spit.ogg' + /// How many additional projectiles to shoot around the target? + var/additional_shots = 4 + /// Delay between each shot + var/shot_delay = 0.15 SECONDS + /// Effect to spawn + var/obj/effect/bileworm_acid/acid_type = /obj/effect/bileworm_acid -/datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/bileworm/Activate(atom/target_atom) +/datum/action/cooldown/mob_cooldown/bileworm_spew/Activate(atom/target_atom) StartCooldownSelf(INFINITY) attack_sequence(owner, target_atom) - //resurface now off cooldown shortly - StartCooldownOthers(2.5 SECONDS) + StartCooldownSelf() + // Resurface now off cooldown shortly + StartCooldownOthers(2 SECONDS) // Enough time for a mark + detonation combo, or 3 shots with a PKA -/datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/bileworm/attack_sequence(mob/living/firer, atom/target) - fire_in_directions(firer, target, GLOB.cardinals) - SLEEP_CHECK_DEATH(0.5 SECONDS, firer) - fire_in_directions(firer, target, GLOB.diagonals) +/datum/action/cooldown/mob_cooldown/bileworm_spew/proc/attack_sequence(mob/living/firer, atom/target) + new acid_type(firer, target) + playsound(firer, projectile_sound, 70) + var/list/all_dirs = GLOB.alldirs.Copy() + var/turf/hit_turf = get_turf(target) + // One guaranteed to hit target's turf, the rest hit randomly around them + for (var/i in 1 to additional_shots) + if (!length(all_dirs)) + return -/obj/projectile/bileworm_acid + SLEEP_CHECK_DEATH(shot_delay, firer) + if (hit_turf != target.loc) + all_dirs = list(NONE) + GLOB.alldirs // Refresh potential target turfs if they've moved + + var/turf/target_turf = null + // NODE drones get a much more focused barrage sent at them + if (istype(target, /mob/living/basic/node_drone) && prob(30)) + target_turf = get_turf(target) + else + var/target_dir = pick_n_take(all_dirs) + target_turf = target_dir ? get_step(target, target_dir) : get_turf(target) + + if (target_turf == firer.loc) // Don't hit ourselves + var/target_dir = pick_n_take(all_dirs) + target_turf = target_dir ? get_step(target, target_dir) : get_turf(target) + + new acid_type(firer, target_turf) + if (i % 2 == 0) + playsound(firer, projectile_sound, 70) + +/obj/effect/bileworm_acid name = "acidic bile" - icon_state = "neurotoxin" - hitsound = 'sound/items/weapons/sear.ogg' - damage = 20 - speed = 0.5 - range = 20 - jitter = 3 SECONDS - stutter = 3 SECONDS - damage_type = BURN - pass_flags = PASSTABLE + icon = 'icons/obj/weapons/guns/projectiles.dmi' + icon_state = "bile_glob" + layer = ABOVE_ALL_MOB_LAYER + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + /// Damage dealt to all mobs in the impact turf + var/damage = 20 + /// Tiles travelled per second at maximum range + var/speed = 5 + /// Maximum range for our speed calculations + var/max_range = 10 + /// Warning sign on the turf we're about to hit + var/obj/effect/bileworm_target/target_sign = null -/obj/projectile/bileworm_acid/Initialize(mapload) +/obj/effect/bileworm_acid/Initialize(mapload, atom/new_target) . = ..() - AddComponent(/datum/component/parriable_projectile) + update_appearance(UPDATE_OVERLAYS) + if (new_target) + fire_at(get_turf(new_target)) + +/obj/effect/bileworm_acid/Destroy(force) + QDEL_NULL(target_sign) + return ..() + +/obj/effect/bileworm_acid/update_overlays() + . = ..() + . += emissive_appearance(icon, icon_state, src, alpha = 20, effect_type = EMISSIVE_BLOOM) + +/obj/effect/bileworm_acid/proc/fire_at(turf/target) + if (!istype(target)) + target = get_turf(target) + var/turf/start = get_turf(src) + forceMove(target) // Immediately move to the target turf so we can guarantee they can see us + pixel_x = (start.x - target.x) * ICON_SIZE_X + pixel_y = (start.y - target.y) * ICON_SIZE_Y + // Because BYOND's get_dist is taxicab distance + var/travel_dist = sqrt((start.x - target.x) ** 2 + (start.y - target.y) ** 2) + // Slightly scale the speed with distance for fairer gameplay + if (travel_dist < max_range) + speed *= 0.5 + travel_dist / max_range * 0.5 + var/travel_time = travel_dist / speed * 1 SECONDS + animate(src, pixel_x = 0, time = travel_time, flags = ANIMATION_PARALLEL, easing = SINE_EASING | EASE_OUT) // Not a perfect arc but looks better + animate(src, pixel_y = 160, time = travel_time / 2, flags = ANIMATION_PARALLEL, easing = QUAD_EASING | EASE_OUT) + animate(pixel_y = 0, time = travel_time / 2, easing = QUAD_EASING | EASE_IN) + animate(src, transform = matrix().Turn(start.x > target.x ? -91 : 91), time = travel_time / 2, flags = ANIMATION_PARALLEL, easing = SINE_EASING | EASE_IN) + animate(transform = matrix().Turn(start.x > target.x ? -180 : 180), time = travel_time / 2, easing = SINE_EASING | EASE_OUT) + target_sign = new(target) + addtimer(CALLBACK(src, PROC_REF(impact), target), travel_time) + +/obj/effect/bileworm_acid/proc/impact(turf/target) + var/obj/effect/abstract/particle_holder/impact_particles = new(target, /particles/bile) + QDEL_IN(impact_particles, /particles/bile::lifespan) + + var/hit_something = FALSE + for (var/mob/living/victim in target) + if(HAS_TRAIT(target, TRAIT_UNHITTABLE_BY_PROJECTILES)) + if(!HAS_TRAIT(target, TRAIT_BLOCKING_PROJECTILES) && isliving(target)) + var/mob/living/living_target = target + living_target.block_projectile_effects() + continue + + // Doesn't make much sense to use melee for mobs, but its a mining mob so eeeeeh + // Can't use acid either as its mostly for atom armor only + var/blocked = victim.run_armor_check(null, MELEE, armour_penetration = 40, silent = TRUE) + if (blocked >= 100) + continue + + hit_something = TRUE + victim.apply_damage(damage, BURN, null, blocked, wound_bonus = CANT_WOUND) + to_chat(victim, span_userdanger("You're hit by [src]!")) + + for (var/obj/thing in target) + if (!thing.uses_integrity || !thing.density) + continue + hit_something = TRUE + thing.take_damage(damage, BURN, ACID, sound_effect = FALSE) + + if (hit_something) + playsound(target, 'sound/items/weapons/sear.ogg', 50, -1) + + qdel(src) + +/obj/effect/bileworm_target + icon = 'icons/mob/telegraphing/telegraph.dmi' + icon_state = "projectile_circle" + layer = BELOW_MOB_LAYER + plane = GAME_PLANE + +/obj/effect/bileworm_target/Initialize(mapload) + . = ..() + update_appearance(UPDATE_OVERLAYS) + +/obj/effect/bileworm_target/update_overlays() + . = ..() + . += emissive_appearance(icon, icon_state, src, alpha = 90, effect_type = EMISSIVE_BLOOM) + +/particles/bile + icon = 'icons/effects/particles/goop.dmi' + icon_state = list("goop_1" = 6, "goop_2" = 2, "goop_3" = 1) + width = 100 + height = 100 + count = 10 + spawning = 10 + color = "#00ea2b80" //to get 96 alpha + lifespan = 1.5 SECONDS + fade = 1 SECONDS + grow = -0.025 + gravity = list(0, 0.15) + position = generator(GEN_SPHERE, 0, 8, NORMAL_RAND) + spin = generator(GEN_NUM, -15, 15, NORMAL_RAND) + velocity = generator(GEN_BOX, list(-2, 2), list(2, 4), NORMAL_RAND) /datum/action/cooldown/mob_cooldown/devour name = "Devour" diff --git a/code/modules/mob/living/basic/lavaland/bileworm/bileworm_ai.dm b/code/modules/mob/living/basic/lavaland/bileworm/bileworm_ai.dm index e18af7ed2ce..cd2450018cf 100644 --- a/code/modules/mob/living/basic/lavaland/bileworm/bileworm_ai.dm +++ b/code/modules/mob/living/basic/lavaland/bileworm/bileworm_ai.dm @@ -1,10 +1,13 @@ /datum/ai_controller/basic_controller/bileworm blackboard = list( BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic/bileworm, + BB_TARGET_PRIORITY_STRATEGY = /datum/target_priority_strategy/mining, + BB_BILEWORM_FLEE_DISTANCE = 3, ) planning_subtrees = list( /datum/ai_planning_subtree/escape_captivity, + /datum/ai_planning_subtree/call_reinforcements/mining, /datum/ai_planning_subtree/simple_find_target, /datum/ai_planning_subtree/bileworm_attack, /datum/ai_planning_subtree/bileworm_execute, @@ -20,16 +23,12 @@ return var/datum/action/cooldown/mob_cooldown/resurface = controller.blackboard[BB_BILEWORM_RESURFACE] + var/datum/action/cooldown/mob_cooldown/bile = controller.blackboard[BB_BILEWORM_SPEW_BILE] - //because one ability is always INFINITY cooldown, this actually works to check which ability should be used - //sometimes it will try to spew bile on infinity cooldown, but that's okay because as soon as resurface is ready it will attempt that - - if(resurface?.IsAvailable()) + if(resurface?.IsAvailable() && (controller.blackboard[BB_BILEWORM_SCARED] || get_dist(controller.pawn, controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]) <= controller.blackboard[BB_BILEWORM_FLEE_DISTANCE])) controller.queue_behavior(/datum/ai_behavior/targeted_mob_ability/and_plan_execute, BB_BILEWORM_RESURFACE, BB_BASIC_MOB_CURRENT_TARGET) return SUBTREE_RETURN_FINISH_PLANNING - var/datum/action/cooldown/mob_cooldown/bile = controller.blackboard[BB_BILEWORM_SPEW_BILE] - if(bile?.IsAvailable()) controller.queue_behavior(/datum/ai_behavior/targeted_mob_ability/and_plan_execute, BB_BILEWORM_SPEW_BILE, BB_BASIC_MOB_CURRENT_TARGET) return SUBTREE_RETURN_FINISH_PLANNING //focus on the fight diff --git a/code/modules/mob/living/basic/lavaland/bileworm/bileworm_instrument.dm b/code/modules/mob/living/basic/lavaland/bileworm/bileworm_instrument.dm index 508728ffa73..74d20946737 100644 --- a/code/modules/mob/living/basic/lavaland/bileworm/bileworm_instrument.dm +++ b/code/modules/mob/living/basic/lavaland/bileworm/bileworm_instrument.dm @@ -2,7 +2,7 @@ name = "bilehorn" desc = "Bits of bileworm anatomy rearranged to produce wonderful music, not bile. Keeps the name though, because for an instrument, it is quite vile." force = 5 - icon = 'icons/mob/simple/lavaland/bileworm.dmi' + icon = 'icons/obj/mining_zones/artefacts.dmi' icon_state = "bilehorn" allowed_instrument_ids = "bilehorn" inhand_icon_state = null diff --git a/code/modules/mob/living/basic/lavaland/bileworm/bileworm_loot.dm b/code/modules/mob/living/basic/lavaland/bileworm/bileworm_loot.dm index 55f960e736a..a8bedef666b 100644 --- a/code/modules/mob/living/basic/lavaland/bileworm/bileworm_loot.dm +++ b/code/modules/mob/living/basic/lavaland/bileworm/bileworm_loot.dm @@ -5,7 +5,7 @@ name = "bileworm skin" desc = "The slushy, squishy and slightly shiny skin of a postmortem bileworm." singular_name = "bileworm skin piece" - icon = 'icons/mob/simple/lavaland/bileworm.dmi' + icon = 'icons/obj/stack_objects.dmi' icon_state = "sheet-bileworm" inhand_icon_state = null merge_type = /obj/item/stack/sheet/animalhide/bileworm diff --git a/code/modules/mob/living/basic/lavaland/bileworm/bileworm_vileworm.dm b/code/modules/mob/living/basic/lavaland/bileworm/bileworm_vileworm.dm index d03ff00f85a..73918285b41 100644 --- a/code/modules/mob/living/basic/lavaland/bileworm/bileworm_vileworm.dm +++ b/code/modules/mob/living/basic/lavaland/bileworm/bileworm_vileworm.dm @@ -4,34 +4,20 @@ icon_state = "vileworm" icon_living = "vileworm" icon_dead = "vileworm_dead" - maxHealth = 150 - health = 150 + maxHealth = 175 + health = 175 - attack_action_path = /datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/bileworm/vileworm + attack_action_path = /datum/action/cooldown/mob_cooldown/bileworm_spew/corrupt evolve_path = null -/datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/bileworm/vileworm +/datum/action/cooldown/mob_cooldown/bileworm_spew/corrupt name = "Spew Corrupted Bile" - desc = "Spews corrupted bile everywhere. Must resurface after use to refresh." - projectile_type = /obj/projectile/bileworm_acid/vile + desc = "Spew a barrage of corrupted bile globs." + cooldown_time = 2.5 SECONDS + acid_type = /obj/effect/bileworm_acid/corrupt + additional_shots = 6 + shot_delay = 0.1 SECONDS -/datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/bileworm/vileworm/Activate(atom/target_atom) - StartCooldownSelf(INFINITY) - attack_sequence(owner, target_atom) - //faster than unevolved - StartCooldownOthers(1.5 SECONDS) - -/datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/bileworm/vileworm/attack_sequence(mob/living/firer, atom/target) - fire_in_directions(firer, target, GLOB.cardinals) - SLEEP_CHECK_DEATH(0.25 SECONDS, firer) - fire_in_directions(firer, target, GLOB.diagonals) - SLEEP_CHECK_DEATH(0.25 SECONDS, firer) - fire_in_directions(firer, target, GLOB.cardinals) - // surprise! - if(prob(25)) - SLEEP_CHECK_DEATH(0.25 SECONDS, firer) - fire_in_directions(firer, target, GLOB.diagonals) - -/obj/projectile/bileworm_acid/vile - name = "corrupted bile" - icon_state = "vileworm" +/obj/effect/bileworm_acid/corrupt + icon_state = "corrupt_bile_glob" + damage = 27 diff --git a/code/modules/mob/living/basic/lavaland/brimdemon/brimbeam.dm b/code/modules/mob/living/basic/lavaland/brimdemon/brimbeam.dm index e558939f8e3..41a1a0f228a 100644 --- a/code/modules/mob/living/basic/lavaland/brimdemon/brimbeam.dm +++ b/code/modules/mob/living/basic/lavaland/brimdemon/brimbeam.dm @@ -15,9 +15,16 @@ var/beam_duration = 2 SECONDS /// How long do we wind up before firing? var/charge_duration = 1 SECONDS + /// Have we been hit and have to abort the blast? + var/abort_blast = FALSE /// A list of all the beam parts. var/list/beam_parts = list() +/datum/action/cooldown/mob_cooldown/brimbeam/Grant(mob/granted_to) + . = ..() + if(owner) + owner.AddElement(/datum/element/relay_attackers) + /datum/action/cooldown/mob_cooldown/brimbeam/Destroy() extinguish_laser() return ..() @@ -25,6 +32,7 @@ /datum/action/cooldown/mob_cooldown/brimbeam/Activate(atom/target) StartCooldown(360 SECONDS) + abort_blast = FALSE owner.face_atom(target) owner.move_resist = MOVE_FORCE_VERY_STRONG owner.balloon_alert_to_viewers("charging...") @@ -32,17 +40,20 @@ var/mutable_appearance/direction_emissive = emissive_appearance('icons/mob/simple/lavaland/lavaland_monsters.dmi', "brimdemon_telegraph_dir", owner, alpha = 150, effect_type = EMISSIVE_NO_BLOOM) owner.add_overlay(direction_overlay) owner.add_overlay(direction_emissive) + RegisterSignal(owner, COMSIG_ATOM_WAS_ATTACKED, PROC_REF(on_owner_attacked)) - var/fully_charged = do_after(owner, delay = charge_duration, target = owner) + var/fully_charged = do_after(owner, delay = charge_duration, target = owner, extra_checks = CALLBACK(src, PROC_REF(beam_charge_check))) owner.cut_overlay(direction_overlay) owner.cut_overlay(direction_emissive) if (!fully_charged) + UnregisterSignal(owner, COMSIG_ATOM_WAS_ATTACKED) StartCooldown() return TRUE if (!fire_laser()) var/static/list/fail_emotes = list("coughs.", "wheezes.", "belches out a puff of black smoke.") owner.manual_emote(pick(fail_emotes)) + UnregisterSignal(owner, COMSIG_ATOM_WAS_ATTACKED) StartCooldown() return TRUE @@ -51,11 +62,20 @@ demon.icon_state = demon.firing_icon_state demon.update_appearance(UPDATE_OVERLAYS) - do_after(owner, delay = beam_duration, target = owner, hidden = TRUE) + do_after(owner, delay = beam_duration, target = owner, hidden = TRUE, extra_checks = CALLBACK(src, PROC_REF(beam_charge_check))) + UnregisterSignal(owner, COMSIG_ATOM_WAS_ATTACKED) extinguish_laser() StartCooldown() return TRUE +/datum/action/cooldown/mob_cooldown/brimbeam/proc/on_owner_attacked(datum/source, atom/attacker, attack_flags, direction) + SIGNAL_HANDLER + if (!(attack_flags & ATTACK_RANGED) && !(direction & owner.dir)) + abort_blast = TRUE + +/datum/action/cooldown/mob_cooldown/brimbeam/proc/beam_charge_check() + return !abort_blast + /// Create a laser in the direction we are facing /datum/action/cooldown/mob_cooldown/brimbeam/proc/fire_laser() owner.visible_message(span_danger("[owner] fires a brimbeam!")) @@ -67,7 +87,7 @@ if(affected_turf.opacity) break var/blocked = FALSE - for(var/obj/potential_block in affected_turf.contents) + for(var/obj/potential_block in affected_turf) if(potential_block.opacity) blocked = TRUE break @@ -77,8 +97,8 @@ new_brimbeam.dir = owner.dir beam_parts += new_brimbeam new_brimbeam.assign_creator(owner) - for(var/mob/living/hit_mob in affected_turf.contents) - hit_mob.apply_damage(damage = 25, damagetype = BURN) + for(var/mob/living/hit_mob in affected_turf) + hit_mob.apply_damage(25, BURN, blocked = hit_mob.run_armor_check(null, LASER, silent = TRUE), wound_bonus = CANT_WOUND) to_chat(hit_mob, span_userdanger("You're blasted by [owner]'s brimbeam!")) RegisterSignal(new_brimbeam, COMSIG_QDELETING, PROC_REF(extinguish_laser)) // In case idk a singularity eats it or something if(!length(beam_parts)) @@ -126,16 +146,10 @@ return ..() /obj/effect/brimbeam/process() - var/atom/ignore = creator?.resolve() + var/ignore = creator?.resolve() for(var/mob/living/hit_mob in get_turf(src)) - if(hit_mob == ignore) - continue - damage(hit_mob) - -/// Hurt the passed mob -/obj/effect/brimbeam/proc/damage(mob/living/hit_mob) - hit_mob.apply_damage(damage = 5, damagetype = BURN) - to_chat(hit_mob, span_danger("You're damaged by [src]!")) + if(hit_mob != ignore) + hit_mob.apply_damage(7, BURN, blocked = hit_mob.run_armor_check(null, LASER, silent = TRUE), wound_bonus = CANT_WOUND) /// Ignore damage dealt to this mob /obj/effect/brimbeam/proc/assign_creator(mob/living/maker) diff --git a/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon_ai.dm b/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon_ai.dm index eb6f6f671ed..b60d7ab4a90 100644 --- a/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon_ai.dm +++ b/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon_ai.dm @@ -4,6 +4,7 @@ /datum/ai_controller/basic_controller/brimdemon blackboard = list( BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic, + BB_TARGET_PRIORITY_STRATEGY = /datum/target_priority_strategy/mining/low_node_priority, BB_TARGET_MINIMUM_STAT = HARD_CRIT, ) @@ -11,6 +12,7 @@ idle_behavior = /datum/idle_behavior/idle_random_walk/no_target planning_subtrees = list( /datum/ai_planning_subtree/escape_captivity, + /datum/ai_planning_subtree/call_reinforcements/mining, /datum/ai_planning_subtree/simple_find_target, /datum/ai_planning_subtree/basic_melee_attack_subtree/opportunistic, /datum/ai_planning_subtree/move_to_cardinal/brimdemon, diff --git a/code/modules/mob/living/basic/lavaland/goldgrub/goldgrub.dm b/code/modules/mob/living/basic/lavaland/goldgrub/goldgrub.dm index b20f29364bd..b43f2149893 100644 --- a/code/modules/mob/living/basic/lavaland/goldgrub/goldgrub.dm +++ b/code/modules/mob/living/basic/lavaland/goldgrub/goldgrub.dm @@ -13,8 +13,8 @@ mob_biotypes = MOB_ORGANIC|MOB_BUG|MOB_MINING friendly_verb_continuous = "harmlessly rolls into" friendly_verb_simple = "harmlessly roll into" - maxHealth = 45 - health = 45 + maxHealth = 175 + health = 175 melee_damage_lower = 0 melee_damage_upper = 0 attack_verb_continuous = "barrels into" @@ -49,16 +49,26 @@ else can_lay_eggs = FALSE - var/list/food_types = string_list(list(/obj/item/stack/ore)) + // Rarer ores heal us a bit depending on the rarity + var/static/list/food_types = list( + /obj/item/stack/ore = 0, + /obj/item/stack/ore/gold = 5, + /obj/item/stack/ore/uranium = 5, + /obj/item/stack/ore/diamond = 15, + /obj/item/stack/ore/bluespace_crystal = 20, + /obj/item/stack/ore/bananium = 30, + ) + var/static/list/innate_actions = list( /datum/action/cooldown/mob_cooldown/spit_ore = BB_SPIT_ABILITY, /datum/action/cooldown/mob_cooldown/burrow = BB_BURROW_ABILITY, ) + grant_actions_by_list(innate_actions) AddElement(/datum/element/ore_collecting) AddElement(/datum/element/basic_eating, food_types = food_types, add_to_contents = TRUE) - AddElement(/datum/element/wall_tearer, allow_reinforced = FALSE) + AddComponent(/datum/component/proficient_miner, 0.05, TRUE) // Speedy boi AddComponent(/datum/component/ai_listen_to_weather) AddComponent(\ /datum/component/appearance_on_aggro,\ @@ -81,10 +91,10 @@ SIGNAL_HANDLER if(stat != CONSCIOUS) - return COMPONENT_BULLET_PIERCED + return NONE - /// High penetration bullets should still go through. No goldgrub can save you from the colossus' death bolts. - if(prob(hitting_projectile.armour_penetration)) + /// Reflects PKA/PKC shots and plasma cutter beams, unless they have high armor penetration + if(prob(hitting_projectile.armour_penetration) || (hitting_projectile.armor_flag != BOMB && hitting_projectile.armor_flag != ENERGY)) return NONE visible_message(span_danger("[hitting_projectile] is repelled by [source]'s girth!")) diff --git a/code/modules/mob/living/basic/lavaland/goldgrub/goldgrub_abilities.dm b/code/modules/mob/living/basic/lavaland/goldgrub/goldgrub_abilities.dm index fe8c8096e2c..f1fcd44ddd4 100644 --- a/code/modules/mob/living/basic/lavaland/goldgrub/goldgrub_abilities.dm +++ b/code/modules/mob/living/basic/lavaland/goldgrub/goldgrub_abilities.dm @@ -44,9 +44,9 @@ /datum/action/cooldown/mob_cooldown/burrow/Activate() var/obj/effect/dummy/phased_mob/grub_burrow/holder = null var/turf/current_loc = get_turf(owner) + var/mob/living/grub = owner - if(!do_after(owner, 3 SECONDS, target = current_loc)) - owner.balloon_alert(owner, "need to stay still!") + if(!do_after(owner, 2.5 SECONDS, target = current_loc, extra_checks = CALLBACK(src, PROC_REF(health_check), grub.health))) return if(get_turf(owner) != current_loc) @@ -72,6 +72,10 @@ StartCooldown() return TRUE +/datum/action/cooldown/mob_cooldown/burrow/proc/health_check(health) + var/mob/living/grub = owner + return grub.health >= health + /obj/effect/dummy/phased_mob/grub_burrow /obj/effect/dummy/phased_mob/grub_burrow/phased_check(mob/living/user, direction) diff --git a/code/modules/mob/living/basic/lavaland/goliath/goliath.dm b/code/modules/mob/living/basic/lavaland/goliath/goliath.dm index 6aef2570060..7b982ddf5be 100644 --- a/code/modules/mob/living/basic/lavaland/goliath/goliath.dm +++ b/code/modules/mob/living/basic/lavaland/goliath/goliath.dm @@ -9,7 +9,7 @@ pixel_x = -12 base_pixel_x = -12 gender = MALE // Female ones are the bipedal elites - speed = 30 + speed = 12 basic_mob_flags = IMMUNE_TO_FISTS maxHealth = 300 health = 300 @@ -197,7 +197,7 @@ This one is clearly ancient, and its tentacles constantly churn the earth around it." maxHealth = 400 health = 400 - crusher_drop_chance = 30 // Wow a whole 5% more likely, how generous + crusher_drop_chance = 100 /// Don't re-check nearby turfs for this long COOLDOWN_DECLARE(retarget_turfs_cooldown) /// List of places we might spawn a tentacle, if we're alive @@ -214,7 +214,7 @@ tentacle_target_turfs -= target_turf continue if (prob(10)) - new /obj/effect/goliath_tentacle(target_turf) + new /obj/effect/goliath_tentacle(target_turf, src) /mob/living/basic/mining/goliath/ancient/immortal/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change) . = ..() @@ -224,7 +224,7 @@ /// Store nearby turfs in our list so we can pop them out later /mob/living/basic/mining/goliath/ancient/immortal/proc/cache_nearby_turfs() - COOLDOWN_START(src, retarget_turfs_cooldown, 10 SECONDS) + COOLDOWN_START(src, retarget_turfs_cooldown, 5 SECONDS) LAZYCLEARLIST(tentacle_target_turfs) for(var/turf/open/floor in orange(4, loc)) LAZYADD(tentacle_target_turfs, floor) diff --git a/code/modules/mob/living/basic/lavaland/goliath/goliath_actions.dm b/code/modules/mob/living/basic/lavaland/goliath/goliath_actions.dm index 31eecc03629..d1336aa9094 100644 --- a/code/modules/mob/living/basic/lavaland/goliath/goliath_actions.dm +++ b/code/modules/mob/living/basic/lavaland/goliath/goliath_actions.dm @@ -20,12 +20,12 @@ return ..() /datum/action/cooldown/mob_cooldown/goliath_tentacles/Activate(atom/target) - new /obj/effect/goliath_tentacle(target) - var/list/directions = GLOB.cardinals.Copy() - for(var/i in 1 to 3) - var/spawndir = pick_n_take(directions) + new /obj/effect/goliath_tentacle(target, owner) + for(var/spawndir in GLOB.cardinals) var/turf/adjacent_target = get_step(target, spawndir) - if(adjacent_target) + if(isgroundlessturf(adjacent_target) && !islava(adjacent_target)) + continue + if(isopenturf(adjacent_target) || ismineralturf(adjacent_target)) new /obj/effect/goliath_tentacle(adjacent_target) if (isliving(target)) @@ -51,7 +51,7 @@ for (var/dir in directions) var/turf/adjacent_target = get_step(target, dir) if(adjacent_target) - new /obj/effect/goliath_tentacle(adjacent_target) + new /obj/effect/goliath_tentacle/drag(adjacent_target, owner) owner.visible_message(span_warning("[owner] unleashes tentacles from the ground around it!")) StartCooldown() return TRUE @@ -70,7 +70,7 @@ shared_cooldown = NONE /datum/action/cooldown/mob_cooldown/tentacle_grasp/Activate(atom/target) - new /obj/effect/temp_visual/effect_trail/burrowed_tentacle(owner.loc, target) + new /obj/effect/temp_visual/effect_trail/burrowed_tentacle(owner.loc, target, owner) if (isliving(target)) owner.visible_message(span_warning("[owner] reaches for [target] with its tentacles!")) StartCooldown() @@ -83,4 +83,20 @@ move_speed = 2 homing = FALSE spawn_interval = 0.1 SECONDS - spawned_effect = /obj/effect/goliath_tentacle + spawned_effect = /obj/effect/goliath_tentacle/drag + /// Mob who fired us + var/mob/living/owner = null + +/obj/effect/temp_visual/effect_trail/burrowed_tentacle/Initialize(mapload, atom/target, mob/living/owner) + . = ..() + src.owner = owner + +/obj/effect/temp_visual/effect_trail/burrowed_tentacle/Destroy() + . = ..() + owner = null + +/obj/effect/temp_visual/effect_trail/burrowed_tentacle/add_spawner() + AddComponent(/datum/component/spawner, spawn_types = list(spawned_effect), max_spawned = max_spawned, spawn_time = spawn_interval, spawn_callback = CALLBACK(src, PROC_REF(on_tentacle_spawned))) + +/obj/effect/temp_visual/effect_trail/burrowed_tentacle/proc/on_tentacle_spawned(obj/effect/goliath_tentacle/tentacle) + tentacle.set_owner(owner) diff --git a/code/modules/mob/living/basic/lavaland/goliath/goliath_ai.dm b/code/modules/mob/living/basic/lavaland/goliath/goliath_ai.dm index 63842f05ef5..60dfd7a15d0 100644 --- a/code/modules/mob/living/basic/lavaland/goliath/goliath_ai.dm +++ b/code/modules/mob/living/basic/lavaland/goliath/goliath_ai.dm @@ -4,6 +4,7 @@ /datum/ai_controller/basic_controller/goliath blackboard = list( BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic, + BB_TARGET_PRIORITY_STRATEGY = /datum/target_priority_strategy/mining, BB_TARGET_MINIMUM_STAT = HARD_CRIT, ) @@ -11,6 +12,7 @@ idle_behavior = /datum/idle_behavior/idle_random_walk planning_subtrees = list( /datum/ai_planning_subtree/escape_captivity, + /datum/ai_planning_subtree/call_reinforcements/mining, /datum/ai_planning_subtree/target_retaliate/check_faction, /datum/ai_planning_subtree/simple_find_target, /datum/ai_planning_subtree/find_food, @@ -34,7 +36,7 @@ return ..() var/mob/living/target = controller.blackboard[target_key] // Interrupt attack chain to use tentacles, unless the target is already tentacled - if (ismecha(target) || (isliving(target) && !target.has_status_effect(/datum/status_effect/incapacitating/stun/goliath_tentacled))) + if (ismecha(target) || (isliving(target) && !target.get_item_by_slot(ITEM_SLOT_LEGCUFFED))) var/datum/action/cooldown/using_action = controller.blackboard[BB_GOLIATH_TENTACLES] if (using_action?.IsAvailable()) return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED @@ -46,7 +48,7 @@ /datum/ai_planning_subtree/targeted_mob_ability/goliath_tentacles/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) var/mob/living/target = controller.blackboard[target_key] - if (!(isliving(target) || ismecha(target)) || (isliving(target) && target.has_status_effect(/datum/status_effect/incapacitating/stun/goliath_tentacled))) + if (!(isliving(target) || ismecha(target)) || (isliving(target) && target.get_item_by_slot(ITEM_SLOT_LEGCUFFED))) return // Target can be an item or already grabbed, we don't want to tentacle those var/time_on_target = controller.blackboard[BB_BASIC_MOB_HAS_TARGET_TIME] || 0 if (time_on_target < MIN_TIME_TO_TENTACLE) diff --git a/code/modules/mob/living/basic/lavaland/goliath/tentacle.dm b/code/modules/mob/living/basic/lavaland/goliath/tentacle.dm index cc9546474ec..b5af54e4da0 100644 --- a/code/modules/mob/living/basic/lavaland/goliath/tentacle.dm +++ b/code/modules/mob/living/basic/lavaland/goliath/tentacle.dm @@ -13,9 +13,13 @@ /// Lower bound of damage to inflict var/min_damage = 10 /// Upper bound of damage to inflict - var/max_damage = 15 + var/max_damage = 15 + /// Type of legcuff we spawn + var/trap_type = /obj/item/restraints/legcuffs/goliath_tentacle + /// Mob who fired the tentacle + var/mob/living/owner = null -/obj/effect/goliath_tentacle/Initialize(mapload) +/obj/effect/goliath_tentacle/Initialize(mapload, mob/living/goliath) . = ..() if (ismineralturf(loc)) var/turf/closed/mineral/floor = loc @@ -28,11 +32,24 @@ deltimer(action_timer) action_timer = addtimer(CALLBACK(src, PROC_REF(animate_grab)), 0.7 SECONDS, TIMER_STOPPABLE) update_appearance(UPDATE_OVERLAYS) + set_owner(goliath) /obj/effect/goliath_tentacle/Destroy() deltimer(action_timer) return ..() +/obj/effect/goliath_tentacle/proc/set_owner(mob/living/goliath) + if (owner) + UnregisterSignal(owner, COMSIG_QDELETING) + owner = goliath + if (owner) + RegisterSignal(owner, COMSIG_QDELETING, PROC_REF(on_owner_del)) + +/obj/effect/goliath_tentacle/proc/on_owner_del(datum/source) + SIGNAL_HANDLER + owner = null + retract() + /// Change to next icon state and set up grapple /obj/effect/goliath_tentacle/proc/animate_grab() icon_state = "goliath_tentacle_wiggle" @@ -42,20 +59,31 @@ /// Grab everyone we share space with. If it's nobody, go home. /obj/effect/goliath_tentacle/proc/grab() + var/trapped_mobs = FALSE for (var/mob/living/victim in loc) - if (victim.stat == DEAD || HAS_TRAIT(victim, TRAIT_TENTACLE_IMMUNE)) + if (victim.stat == DEAD || owner && victim.faction_check_atom(owner)) + continue + if (HAS_TRAIT(victim, TRAIT_TENTACLE_IMMUNE) || SEND_SIGNAL(victim, COMSIG_GOLIATH_TENTACLED_GRABBED) & COMPONENT_GOLIATH_CANCEL_TENTACLE_GRAB) + continue + var/obj/item/restraints/legcuffs/goliath_tentacle/trap = new trap_type(loc, victim, src) + if (QDELETED(trap)) continue balloon_alert(victim, "grabbed") visible_message(span_danger("[src] grabs hold of [victim]!")) - victim.adjust_brute_loss(rand(min_damage, max_damage)) - if (victim.apply_status_effect(/datum/status_effect/incapacitating/stun/goliath_tentacled, grapple_time, src)) - buckle_mob(victim, TRUE) - SEND_SIGNAL(victim, COMSIG_GOLIATH_TENTACLED_GRABBED) + victim.apply_damage(rand(min_damage, max_damage), BRUTE, pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG), wound_bonus = CANT_WOUND) + trapped_mobs = TRUE + for (var/obj/vehicle/sealed/mecha/mech in loc) mech.take_damage(rand(min_damage, max_damage), damage_type = BRUTE, damage_flag = MELEE, sound_effect = TRUE) - if (!has_buckled_mobs()) + + // Already retracting + if (icon_state == "goliath_tentacle_retract") + return + + if (!trapped_mobs) retract() return + deltimer(action_timer) action_timer = addtimer(CALLBACK(src, PROC_REF(retract)), grapple_time, TIMER_STOPPABLE) @@ -64,7 +92,6 @@ if (icon_state == "goliath_tentacle_retract") return // Already retracting SEND_SIGNAL(src, COMSIG_GOLIATH_TENTACLE_RETRACTING) - unbuckle_all_mobs(force = TRUE) icon_state = "goliath_tentacle_retract" update_appearance(UPDATE_OVERLAYS) deltimer(action_timer) @@ -77,54 +104,136 @@ /obj/effect/goliath_tentacle/attack_hand(mob/living/user, list/modifiers) . = ..() - if (. || !has_buckled_mobs()) - return - retract() - return TRUE + if(!.) + retract() + return TRUE -/// Goliath tentacle stun with special removal conditions -/datum/status_effect/incapacitating/stun/goliath_tentacled - id = "goliath_tentacled" - duration = 10 SECONDS - /// The tentacle that is tenderly holding us close +/// An alternative variant which drags the mob in towards the goliath +/obj/effect/goliath_tentacle/drag + trap_type = /obj/item/restraints/legcuffs/goliath_tentacle/drag + +/obj/item/restraints/legcuffs/goliath_tentacle + name = "tentacle mass" + desc = "A writhing tentacle constricting one of your limbs." + icon_state = "goliath_tentacle" + slowdown = 4 + breakouttime = 6 SECONDS + resistance_flags = LAVA_PROOF | FIRE_PROOF + obj_flags = CONDUCTS_ELECTRICITY | CAN_BE_HIT + item_flags = DROPDEL + legcuff_state = "goliath_tentacle" + uses_integrity = TRUE + max_integrity = 75 // 3 PKC swings, 5 bayonet swings + /// Tentacle we're attached to var/obj/effect/goliath_tentacle/tentacle + /// Leash component linking the victim to the turf + var/datum/component/leash/leash + /// Beam between the victim and the tentacle tile + var/datum/beam/beam_effect -/datum/status_effect/incapacitating/stun/goliath_tentacled/on_creation(mob/living/new_owner, set_duration, obj/effect/goliath_tentacle/tentacle) +/obj/item/restraints/legcuffs/goliath_tentacle/Initialize(mapload, mob/living/target, obj/effect/goliath_tentacle/tentacle) . = ..() - if (!.) - return + ADD_TRAIT(src, TRAIT_IGNORE_DEMOLITION, INNATE_TRAIT) src.tentacle = tentacle + if (!target?.equip_to_slot_if_possible(src, ITEM_SLOT_LEGCUFFED, disable_warning = TRUE, bypass_equip_delay_self = TRUE)) + return INITIALIZE_HINT_QDEL -/datum/status_effect/incapacitating/stun/goliath_tentacled/on_apply() +/obj/item/restraints/legcuffs/goliath_tentacle/Destroy(force) . = ..() - RegisterSignal(owner, COMSIG_CARBON_PRE_MISC_HELP, PROC_REF(on_helped)) - RegisterSignals(owner, list(SIGNAL_ADDTRAIT(TRAIT_TENTACLE_IMMUNE), COMSIG_BRIMDUST_EXPLOSION), PROC_REF(release)) - RegisterSignals(tentacle, list(COMSIG_QDELETING, COMSIG_GOLIATH_TENTACLE_RETRACTING), PROC_REF(on_tentacle_left)) + if (tentacle) + tentacle.retract() + tentacle = null + if (leash) + UnregisterSignal(leash, COMSIG_QDELETING) + QDEL_NULL(leash) + QDEL_NULL(beam_effect) -/datum/status_effect/incapacitating/stun/goliath_tentacled/on_remove() +/obj/item/restraints/legcuffs/goliath_tentacle/equipped(mob/living/user, slot, initial) . = ..() - UnregisterSignal(owner, list(COMSIG_CARBON_PRE_MISC_HELP, SIGNAL_ADDTRAIT(TRAIT_TENTACLE_IMMUNE), COMSIG_BRIMDUST_EXPLOSION)) - if (isnull(tentacle)) + if (slot != ITEM_SLOT_LEGCUFFED || leash) return - UnregisterSignal(tentacle, list(COMSIG_QDELETING, COMSIG_GOLIATH_TENTACLE_RETRACTING)) + leash_target(user) + +/obj/item/restraints/legcuffs/goliath_tentacle/proc/release(datum/source) + SIGNAL_HANDLER + qdel(src) + +/obj/item/restraints/legcuffs/goliath_tentacle/proc/on_tentacle_left(datum/source) + SIGNAL_HANDLER + if (tentacle) + UnregisterSignal(tentacle, list(COMSIG_QDELETING, COMSIG_GOLIATH_TENTACLE_RETRACTING)) + tentacle = null + release() + +/obj/item/restraints/legcuffs/goliath_tentacle/proc/leash_target(mob/living/user) + leash = user.AddComponent(/datum/component/leash, owner = get_turf(user), distance = 1, silent = TRUE) + beam_effect = user.Beam(get_turf(user), "goliath_tentacle", beam_type = /obj/effect/ebeam/goliath, emissive = FALSE) + RegisterSignal(beam_effect.visuals, COMSIG_CLICK, PROC_REF(on_beam_click)) + RegisterSignals(user, list(SIGNAL_ADDTRAIT(TRAIT_TENTACLE_IMMUNE), COMSIG_BRIMDUST_EXPLOSION), PROC_REF(release)) + RegisterSignals(tentacle, list(COMSIG_QDELETING, COMSIG_GOLIATH_TENTACLE_RETRACTING), PROC_REF(on_tentacle_left)) + RegisterSignal(leash, COMSIG_QDELETING, PROC_REF(release)) + +/obj/item/restraints/legcuffs/goliath_tentacle/proc/on_beam_click(atom/source, atom/location, control, params, mob/user) + SIGNAL_HANDLER + INVOKE_ASYNC(src, PROC_REF(process_beam_click), source, location, params, user) + +/obj/item/restraints/legcuffs/goliath_tentacle/proc/process_beam_click(atom/source, atom/location, params, mob/user) + if(world.time <= user.next_move) + return + + var/obj/item/held_thing = user.get_active_held_item() + if (!istype(held_thing)) + return + + var/turf/nearest_turf = null + for (var/turf/line_turf in get_line(get_turf(src), get_turf(beam_effect.target))) + if (line_turf.IsReachableBy(user)) + nearest_turf = line_turf + break + + if (isnull(nearest_turf)) + return + + if (!user.can_perform_action(nearest_turf)) + nearest_turf.balloon_alert(user, "cannot reach!") + return + + held_thing.melee_attack_chain(user, src, params2list(params)) + user.changeNext_move(held_thing.attack_speed) + playsound(user, held_thing.hitsound || 'sound/effects/blob/attackblob.ogg', held_thing.get_clamped_volume(), TRUE, extrarange = held_thing.stealthy_audio ? SILENCED_SOUND_EXTRARANGE : -1, falloff_distance = 0) + +/obj/item/restraints/legcuffs/goliath_tentacle/play_attack_sound(damage_amount, damage_type, damage_flag) + return + +/obj/item/restraints/legcuffs/goliath_tentacle/drag + +/obj/item/restraints/legcuffs/goliath_tentacle/drag/Initialize(mapload, mob/living/target, obj/effect/goliath_tentacle/tentacle) + . = ..() + QDEL_IN(src, 15 SECONDS) + if (. != INITIALIZE_HINT_QDEL) + START_PROCESSING(SSprocessing, src) + +/obj/item/restraints/legcuffs/goliath_tentacle/drag/Destroy(force) + . = ..() + STOP_PROCESSING(SSprocessing, src) + +/obj/item/restraints/legcuffs/goliath_tentacle/drag/process(seconds_per_tick) + if (leash.distance <= 1) + return PROCESS_KILL + leash.set_distance(leash.distance - 1) + +/obj/item/restraints/legcuffs/goliath_tentacle/drag/leash_target(mob/living/user) + if (!tentacle?.owner) + return ..() + leash = user.AddComponent(/datum/component/leash, owner = tentacle.owner, distance = get_dist(user, tentacle.owner), silent = TRUE) + beam_effect = user.Beam(tentacle.owner, "goliath_tentacle", beam_type = /obj/effect/ebeam/goliath, emissive = FALSE) + RegisterSignal(beam_effect.visuals, COMSIG_CLICK, PROC_REF(on_beam_click)) + RegisterSignals(user, list(SIGNAL_ADDTRAIT(TRAIT_TENTACLE_IMMUNE), COMSIG_BRIMDUST_EXPLOSION), PROC_REF(release)) + RegisterSignals(tentacle.owner, COMSIG_QDELETING, PROC_REF(on_tentacle_left)) + RegisterSignal(leash, COMSIG_QDELETING, PROC_REF(release)) tentacle.retract() tentacle = null -/// Some kind soul has rescued us -/datum/status_effect/incapacitating/stun/goliath_tentacled/proc/on_helped(mob/source, mob/helping) - SIGNAL_HANDLER - release() - source.visible_message(span_notice("[helping] rips [source] from the tentacle's grasp!")) - return COMPONENT_BLOCK_MISC_HELP - -/// Something happened to make the tentacle let go -/datum/status_effect/incapacitating/stun/goliath_tentacled/proc/release() - SIGNAL_HANDLER - owner.remove_status_effect(/datum/status_effect/incapacitating/stun/goliath_tentacled) - -/// Something happened to our associated tentacle -/datum/status_effect/incapacitating/stun/goliath_tentacled/proc/on_tentacle_left() - SIGNAL_HANDLER - UnregisterSignal(tentacle, list(COMSIG_QDELETING, COMSIG_GOLIATH_TENTACLE_RETRACTING)) // No endless loops for us please - tentacle = null - release() +/obj/effect/ebeam/goliath + name = "goliath tentacle" + mouse_opacity = MOUSE_OPACITY_ICON diff --git a/code/modules/mob/living/basic/lavaland/gutlunchers/gutlunchers.dm b/code/modules/mob/living/basic/lavaland/gutlunchers/gutlunchers.dm index 87df7e847b5..9489a119c5c 100644 --- a/code/modules/mob/living/basic/lavaland/gutlunchers/gutlunchers.dm +++ b/code/modules/mob/living/basic/lavaland/gutlunchers/gutlunchers.dm @@ -46,16 +46,16 @@ /mob/living/basic/mining/gutlunch/early_melee_attack(atom/target, list/modifiers, ignore_cooldown) . = ..() - if(!.) + if(.) return if(!istype(target, /obj/structure/ore_container/food_trough/gutlunch_trough)) - return TRUE + return BASIC_MOB_CONTINUE_ATTACK_CHAIN var/obj/ore_food = locate(/obj/item/stack/ore) in target if(isnull(ore_food)) balloon_alert(src, "no food!") else UnarmedAttack(ore_food, TRUE, modifiers) - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN /mob/living/basic/mining/gutlunch/proc/after_birth(mob/living/basic/mining/gutlunch/grub/baby, mob/living/partner) var/our_color = LAZYACCESS(atom_colours, FIXED_COLOUR_PRIORITY) || COLOR_GRAY diff --git a/code/modules/mob/living/basic/lavaland/legion/legion.dm b/code/modules/mob/living/basic/lavaland/legion/legion.dm index 26c90918672..f738e35bf8c 100644 --- a/code/modules/mob/living/basic/lavaland/legion/legion.dm +++ b/code/modules/mob/living/basic/lavaland/legion/legion.dm @@ -75,7 +75,7 @@ /mob/living/basic/mining/legion/update_overlays() . = ..() if (stat != DEAD && has_emissive) // Shouldn't really happen but just in case - . += emissive_appearance(icon, "[icon_living]_e", src, effect_type = EMISSIVE_NO_BLOOM) + . += emissive_appearance(icon, "[icon_living]_e", src, effect_type = EMISSIVE_BLOOM) /// Put a corpse in this guy /mob/living/basic/mining/legion/proc/consume(mob/living/carbon/human/consumed) diff --git a/code/modules/mob/living/basic/lavaland/legion/legion_ai.dm b/code/modules/mob/living/basic/lavaland/legion/legion_ai.dm index 96cde9e5ac5..8d5082d4c08 100644 --- a/code/modules/mob/living/basic/lavaland/legion/legion_ai.dm +++ b/code/modules/mob/living/basic/lavaland/legion/legion_ai.dm @@ -2,25 +2,29 @@ /datum/ai_controller/basic_controller/legion blackboard = list( BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic/legion, + BB_TARGET_PRIORITY_STRATEGY = /datum/target_priority_strategy/mining, BB_TARGET_MINIMUM_STAT = HARD_CRIT, BB_AGGRO_RANGE = 5, // Unobservant - BB_BASIC_MOB_FLEE_DISTANCE = 6, + BB_RANGED_SKIRMISH_MIN_DISTANCE = 4, + BB_RANGED_SKIRMISH_MAX_DISTANCE = 6, ) ai_movement = /datum/ai_movement/basic_avoidance idle_behavior = /datum/idle_behavior/idle_random_walk planning_subtrees = list( /datum/ai_planning_subtree/escape_captivity, + /datum/ai_planning_subtree/call_reinforcements/mining, /datum/ai_planning_subtree/random_speech/legion, /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/maintain_distance, /datum/ai_planning_subtree/targeted_mob_ability, - /datum/ai_planning_subtree/flee_target/legion, ) /// Chase and attack whatever we are targeting, if it's friendly we will heal them /datum/ai_controller/basic_controller/legion_brood blackboard = list( BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic/legion, + BB_TARGET_PRIORITY_STRATEGY = /datum/target_priority_strategy/mining/low_node_priority, BB_TARGET_MINIMUM_STAT = HARD_CRIT, ) diff --git a/code/modules/mob/living/basic/lavaland/legion/legion_brood.dm b/code/modules/mob/living/basic/lavaland/legion/legion_brood.dm index 1fc6a7d02be..dd2bbe18de2 100644 --- a/code/modules/mob/living/basic/lavaland/legion/legion_brood.dm +++ b/code/modules/mob/living/basic/lavaland/legion/legion_brood.dm @@ -103,8 +103,17 @@ else add_ally(creator) created_by = WEAKREF(creator) - ai_controller?.set_blackboard_key(BB_LEGION_BROOD_CREATOR, creator) RegisterSignal(creator, COMSIG_QDELETING, PROC_REF(creator_destroyed)) + if (!ai_controller) + return + + ai_controller.set_blackboard_key(BB_LEGION_BROOD_CREATOR, creator) + if (!creator.ai_controller) + return + + // Inherit our creator's target and reinforcement requests + ai_controller.set_blackboard_key(BB_BASIC_MOB_CURRENT_TARGET, creator.ai_controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]) + ai_controller.set_blackboard_key(BB_MINING_MOB_REINFORCEMENTS_REQUESTS, creator.ai_controller.blackboard[BB_MINING_MOB_REINFORCEMENTS_REQUESTS]) /// Reference handling /mob/living/basic/mining/legion_brood/proc/creator_destroyed() 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 c634f1238d1..bd9b2addff6 100644 --- a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm +++ b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm @@ -8,12 +8,13 @@ /datum/ai_controller/basic_controller/lobstrosity blackboard = list( BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic, + BB_TARGET_PRIORITY_STRATEGY = /datum/target_priority_strategy/mining, BB_PET_TARGETING_STRATEGY = /datum/targeting_strategy/basic/not_friends, BB_TARGET_MINIMUM_STAT = HARD_CRIT, BB_LOBSTROSITY_EXPLOIT_TRAITS = list(TRAIT_INCAPACITATED, TRAIT_FLOORED, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT), BB_LOBSTROSITY_FINGER_LUST = 0, BB_LOBSTROSITY_NAIVE_HUNTER = FALSE, - BB_BASIC_MOB_FLEE_DISTANCE = 8, + BB_BASIC_MOB_FLEE_DISTANCE = 6, BB_EAT_FOOD_COOLDOWN = 3 MINUTES, BB_ONLY_FISH_WHILE_HUNGRY = TRUE, BB_TARGET_PRIORITY_TRAIT = TRAIT_SCARY_FISHERMAN, @@ -24,6 +25,7 @@ idle_behavior = /datum/idle_behavior/idle_random_walk planning_subtrees = list( /datum/ai_planning_subtree/escape_captivity, + /datum/ai_planning_subtree/call_reinforcements/mining, /datum/ai_planning_subtree/random_speech/insect, /datum/ai_planning_subtree/hoard_fingers, /datum/ai_planning_subtree/pet_planning, diff --git a/code/modules/mob/living/basic/lavaland/mining.dm b/code/modules/mob/living/basic/lavaland/mining.dm index 59247792800..b2ba4139559 100644 --- a/code/modules/mob/living/basic/lavaland/mining.dm +++ b/code/modules/mob/living/basic/lavaland/mining.dm @@ -40,7 +40,7 @@ drop_mod = crusher_drop_chance,\ drop_immediately = basic_mob_flags & DEL_ON_DEATH,\ ) - RegisterSignal(src, COMSIG_ATOM_WAS_ATTACKED, PROC_REF(check_ashwalker_peace_violation)) + RegisterSignal(src, COMSIG_ATOM_WAS_ATTACKED, PROC_REF(on_attacked)) // We add this to ensure that mobs will actually receive the above signal, as some will lack AI // handling for retaliation and attack special cases AddElement(/datum/element/relay_attackers) @@ -55,9 +55,9 @@ throw_blocked_message = throw_blocked_message,\ ) -/mob/living/basic/mining/proc/check_ashwalker_peace_violation(datum/source, mob/living/carbon/human/possible_ashwalker) +/mob/living/basic/mining/proc/on_attacked(datum/source, atom/attacker, attack_flags) SIGNAL_HANDLER - if(!isashwalker(possible_ashwalker) || !has_faction(FACTION_ASHWALKER)) + if(!isashwalker(attacker) || !has_faction(FACTION_ASHWALKER)) return remove_faction(FACTION_ASHWALKER) diff --git a/code/modules/mob/living/basic/lavaland/mook/mook.dm b/code/modules/mob/living/basic/lavaland/mook/mook.dm index a9cd028f4b6..966c1bfba18 100644 --- a/code/modules/mob/living/basic/lavaland/mook/mook.dm +++ b/code/modules/mob/living/basic/lavaland/mook/mook.dm @@ -97,26 +97,26 @@ /mob/living/basic/mining/mook/early_melee_attack(atom/target, list/modifiers, ignore_cooldown) . = ..() - if(!.) - return FALSE + if(.) + return return attack_sequence(target) /mob/living/basic/mining/mook/proc/attack_sequence(atom/target) if(istype(target, /obj/item/stack/ore) && isnull(held_ore)) var/obj/item/ore_target = target ore_target.forceMove(src) - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN if(istype(target, /obj/structure/ore_container/material_stand)) if(held_ore) held_ore.forceMove(target) - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN if(istype(target, /obj/structure/bonfire)) var/obj/structure/bonfire/fire_target = target if(!fire_target.burning) fire_target.start_burning() - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN /mob/living/basic/mining/mook/proc/change_combatant_state(state) attack_state = state @@ -187,7 +187,7 @@ if(istype(intruder, /mob/living/basic/mining/mook)) return for(var/mob/living/basic/mining/mook/villager in oview(src, 9)) - villager.ai_controller?.insert_blackboard_key_lazylist(BB_BASIC_MOB_RETALIATE_LIST, intruder) + villager.ai_controller?.set_blackboard_key_assoc(BB_BASIC_MOB_RETALIATE_LIST, intruder, world.time) /mob/living/basic/mining/mook/worker diff --git a/code/modules/mob/living/basic/lavaland/raptor/_raptor.dm b/code/modules/mob/living/basic/lavaland/raptor/_raptor.dm index fdcb0707cd8..610682fd7a3 100644 --- a/code/modules/mob/living/basic/lavaland/raptor/_raptor.dm +++ b/code/modules/mob/living/basic/lavaland/raptor/_raptor.dm @@ -71,7 +71,7 @@ GLOBAL_LIST_EMPTY(raptor_population) /obj/item/food/meat/slab/xeno = -15, /obj/item/food/meat/steak = 50, /obj/item/food/grown/ash_flora = 10, - /obj/item/fish = 15, + /obj/item/fish = 25, /obj/item/organ = 25, ) /// Inheritance datum we store our genetic data in @@ -92,7 +92,7 @@ GLOBAL_LIST_EMPTY(raptor_population) else change_growth_stage(growth_stage, RAPTOR_ADULT) - add_traits(list(TRAIT_ASHSTORM_IMMUNE, TRAIT_SNOWSTORM_IMMUNE, TRAIT_MINING_AOE_IMMUNE), INNATE_TRAIT) + add_traits(list(TRAIT_ASHSTORM_IMMUNE, TRAIT_SNOWSTORM_IMMUNE, TRAIT_MINING_AOE_IMMUNE, TRAIT_NO_SLIP_ICE, TRAIT_NO_SLIP_SLIDE), INNATE_TRAIT) AddElement(\ /datum/element/crusher_loot,\ trophy_type = /obj/item/crusher_trophy/raptor_feather,\ @@ -169,16 +169,16 @@ GLOBAL_LIST_EMPTY(raptor_population) /mob/living/basic/raptor/early_melee_attack(atom/target, list/modifiers, ignore_cooldown) . = ..() - if(!.) - return FALSE + if(.) + return if(!istype(target, /obj/structure/ore_container/food_trough/raptor_trough)) - return TRUE + return BASIC_MOB_CONTINUE_ATTACK_CHAIN var/obj/ore_food = locate(/obj/item/stack/ore) in target if(isnull(ore_food)) balloon_alert(src, "no food!") else UnarmedAttack(ore_food, TRUE, modifiers) - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN /mob/living/basic/raptor/melee_attack(mob/living/target, list/modifiers, ignore_cooldown) if (!combat_mode && istype(target, /mob/living/basic/raptor)) diff --git a/code/modules/mob/living/basic/lavaland/raptor/raptor_color.dm b/code/modules/mob/living/basic/lavaland/raptor/raptor_color.dm index b366a44b7b6..1be8dcb6ad9 100644 --- a/code/modules/mob/living/basic/lavaland/raptor/raptor_color.dm +++ b/code/modules/mob/living/basic/lavaland/raptor/raptor_color.dm @@ -96,6 +96,10 @@ GLOBAL_LIST_INIT(raptor_colors, init_raptor_colors()) // Doesn't care for your excuses for friendly fire ai_controller = /datum/ai_controller/basic_controller/raptor/aggressive +/datum/raptor_color/red/setup_raptor(mob/living/basic/raptor/raptor) + . = ..() + ADD_TRAIT(raptor, TRAIT_MINING_AGGRO, INNATE_TRAIT) + /datum/raptor_color/purple color = "purple" description = "A small, nimble breed, these raptors have been bred as travel companions rather than mounts, capable of storing the owner's possessions and helping them escape from danger unscathed." @@ -440,7 +444,7 @@ GLOBAL_LIST_INIT(raptor_colors, init_raptor_colors()) /datum/raptor_color/black/setup_raptor(mob/living/basic/raptor/raptor) . = ..() - raptor.add_traits(list(TRAIT_LAVA_IMMUNE, TRAIT_NOFIRE_SPREAD), INNATE_TRAIT) + raptor.add_traits(list(TRAIT_LAVA_IMMUNE, TRAIT_NOFIRE_SPREAD, TRAIT_MINING_AGGRO), INNATE_TRAIT) /datum/raptor_color/black/setup_adult(mob/living/basic/raptor/raptor) . = ..() diff --git a/code/modules/mob/living/basic/lavaland/tendril/tendril.dm b/code/modules/mob/living/basic/lavaland/tendril/tendril.dm new file mode 100644 index 00000000000..b31e8a982a7 --- /dev/null +++ b/code/modules/mob/living/basic/lavaland/tendril/tendril.dm @@ -0,0 +1,155 @@ +#define HEARTBEAT_NORMAL (1.8 SECONDS) +#define HEARTBEAT_FAST (1 SECONDS) +#define HEARTBEAT_FRANTIC (0.4 SECONDS) + +GLOBAL_LIST_INIT(tendrils, list()) + +/mob/living/basic/mining/tendril + name = "necropolis tendril" + desc = "A vile tendril of corruption, originating deep underground." + icon = 'icons/mob/simple/lavaland/tendril.dmi' + icon_state = "tendril" + icon_living = "tendril" + pixel_w = -8 + base_pixel_w = -8 + status_flags = NONE + mob_biotypes = MOB_ORGANIC | MOB_SKELETAL | MOB_MINING + basic_mob_flags = DEL_ON_DEATH | IMMUNE_TO_FISTS + mob_size = MOB_SIZE_HUGE + maxHealth = 1200 + health = 1200 + + friendly_verb_continuous = "flails at" + friendly_verb_simple = "flail at" + speak_emote = list("resonates") + obj_damage = 100 + melee_damage_lower = 20 + melee_damage_upper = 20 + sharpness = SHARP_POINTY + wound_bonus = CANT_WOUND + attack_sound = 'sound/items/weapons/pierce.ogg' + attack_verb_continuous = "pierces through" + attack_verb_simple = "pierce through" + throw_blocked_message = "does nothing to the thick shell of" + move_resist = INFINITY + + light_range = 3 + light_power = 2 + light_color = LIGHT_COLOR_LAVA + + ai_controller = /datum/ai_controller/basic_controller/tendril + + /// Looping heartbeat sound + var/datum/looping_sound/heartbeat/soundloop + /// Melee attack ability to used in retaliation to melee strikes and whenever it manages to grab someone + var/datum/action/cooldown/mob_cooldown/projectile_attack/tendril_melee/tendril_melee + +/mob/living/basic/mining/tendril/Initialize(mapload) + . = ..() + GLOB.tendrils += src + AddElement(/datum/element/ai_retaliate) + AddElement(/datum/element/death_drops, /obj/structure/closet/crate/necropolis/tendril) + AddComponent(/datum/component/ai_target_timer) + AddComponent(/datum/component/gps, "Eerie Signal") + AddComponent(/datum/component/basic_mob_attack_telegraph, display_telegraph_overlay = FALSE, telegraph_duration = 0.4 SECONDS) + AddComponent(/datum/component/regenerator, regeneration_delay = 30 SECONDS, brute_per_second = 20) + add_traits(list(TRAIT_BACKSTAB_IMMUNE, TRAIT_IMMOBILIZED), INNATE_TRAIT) + + var/static/list/abilities = list( + /datum/action/cooldown/mob_cooldown/projectile_attack/tendril_lash = BB_TENDRIL_LASH, + /datum/action/cooldown/mob_cooldown/tendril_chaser = BB_TENDRIL_CHASER, + /datum/action/cooldown/mob_cooldown/tendril_cross_spikes = BB_TENDRIL_SPIKES, + ) + grant_actions_by_list(abilities) + + tendril_melee = new(src) + tendril_melee.Grant(src) + AddComponent(/datum/component/revenge_ability, tendril_melee, targeting = GET_TARGETING_STRATEGY(ai_controller.blackboard[BB_TARGETING_STRATEGY]), max_range = 2, target_self = TRUE) + + soundloop = new(src, start_immediately = FALSE) + soundloop.mid_length = HEARTBEAT_NORMAL + soundloop.pressure_affected = FALSE + soundloop.start() + update_appearance(UPDATE_OVERLAYS) + + var/turf/our_turf = get_turf(src) + for (var/turf/rock in range(4, src)) + var/dist = sqrt((rock.x - our_turf.x) ** 2 + (rock.y - our_turf.y) ** 2) + if (dist > 4.5) + continue + + if (ismineralturf(rock)) + rock.ScrapeAway(null, CHANGETURF_IGNORE_AIR) + + if (istype(rock, /turf/open/misc/asteroid) && prob(100 / sqrt(max(1, dist)))) + rock.ChangeTurf(/turf/open/indestructible/necropolis, null, CHANGETURF_IGNORE_AIR) + +/mob/living/basic/mining/tendril/Destroy() + GLOB.tendrils -= src + QDEL_NULL(soundloop) + + if(!SSachievements.achievements_enabled || (flags_1 & ADMIN_SPAWNED_1)) + return ..() + + for(var/mob/living/killer in view(7, src)) + if(killer.stat || !killer.client) + continue + killer.client.give_award(/datum/award/score/tendril_score, killer) + if (!length(GLOB.tendrils)) + killer.client.give_award(/datum/award/achievement/boss/tendril_exterminator, killer) + + return ..() + +/mob/living/basic/mining/tendril/update_overlays() + . = ..() + . += emissive_appearance(icon, "[icon_state]_e", src, effect_type = EMISSIVE_NO_BLOOM) + . += emissive_appearance(icon, "[icon_state]_e_bloom", src, effect_type = EMISSIVE_BLOOM) + +/mob/living/basic/mining/tendril/Life(seconds_per_tick) + . = ..() + update_heartbeat() // Just a single math op unless we need updating so its fine to put it here + +/mob/living/basic/mining/tendril/updatehealth() + . = ..() + update_heartbeat() + +/mob/living/basic/mining/tendril/proc/update_heartbeat() + if (!soundloop) + return + + var/beat_rate = HEARTBEAT_NORMAL + if (ai_controller?.blackboard[BB_BASIC_MOB_CURRENT_TARGET]) + beat_rate = round(HEARTBEAT_FRANTIC + health / maxHealth * (HEARTBEAT_FAST - HEARTBEAT_FRANTIC), 0.05 SECONDS) + + if (beat_rate != soundloop.mid_length) + soundloop.set_mid_length(beat_rate) + +/mob/living/basic/mining/tendril/do_attack_animation(atom/attacked_atom, visual_effect_icon, obj/item/used_item, no_effect, fov_effect = TRUE, item_animation_override = null) + if(!no_effect && (visual_effect_icon || used_item)) + do_item_attack_animation(attacked_atom, visual_effect_icon, used_item, animation_type = item_animation_override) + + // Stabby visuals + var/obj/effect/temp_visual/spike_stab/stab = new(get_turf(src)) + var/target_dir = get_dir(src, attacked_atom) + stab.transform = matrix().Turn(dir2angle(target_dir) + rand(-7, 7)) + if (target_dir & NORTH) + stab.pixel_z = 24 + else if (target_dir & SOUTH) + stab.pixel_z = -24 + if (target_dir & EAST) + stab.pixel_w = 24 + else if (target_dir & WEST) + stab.pixel_w = -24 + +/obj/effect/temp_visual/spike_stab + icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi' + icon_state = "spike_small" + duration = 0.4 SECONDS + +/mob/living/basic/mining/tendril/proc/snatch_react() + if (tendril_melee.IsAvailable()) + tendril_melee.Activate(warning = FALSE) + +#undef HEARTBEAT_NORMAL +#undef HEARTBEAT_FAST +#undef HEARTBEAT_FRANTIC diff --git a/code/modules/mob/living/basic/lavaland/tendril/tendril_actions.dm b/code/modules/mob/living/basic/lavaland/tendril/tendril_actions.dm new file mode 100644 index 00000000000..ba4bb3b219d --- /dev/null +++ b/code/modules/mob/living/basic/lavaland/tendril/tendril_actions.dm @@ -0,0 +1,358 @@ +/// Fires out two cross patterns of damaging tentacles which reel in anything they hit, then causes a followup attack +/datum/action/cooldown/mob_cooldown/projectile_attack/tendril_lash + name = "Tentacle Lash" + desc = "Lash out with your tentacles in 8 directions, reeling in whatever you hit and unleashing a deadly followup attack afterwards." + button_icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi' + button_icon_state = "goliath_tentacle_wiggle" + background_icon_state = "bg_demon" + overlay_icon_state = "bg_demon_border" + click_to_activate = FALSE + cooldown_time = 8 SECONDS + melee_cooldown_time = 0 + shared_cooldown = NONE + projectile_type = /obj/projectile/tentacle_lash + +/datum/action/cooldown/mob_cooldown/projectile_attack/tendril_lash/Activate(atom/target) + disable_cooldown_actions() + + for (var/swipe_dir in GLOB.cardinals) + var/turf/open/line_turf = get_step(owner, swipe_dir) + for (var/i in 1 to projectile_type::range) + if (!istype(line_turf) || line_turf.is_blocked_turf(exclude_mobs = TRUE)) + break + var/obj/effect/temp_visual/telegraphing/line/telegraph = new(line_turf) + telegraph.dir = swipe_dir + line_turf = get_step(line_turf, swipe_dir) + + SLEEP_CHECK_DEATH(0.8 SECONDS, owner) + + for (var/swipe_dir in GLOB.cardinals) + shoot_projectile(get_turf(owner), get_step(owner, swipe_dir), dir2angle(swipe_dir), owner) + + SLEEP_CHECK_DEATH(1.6 SECONDS, owner) + + for (var/swipe_dir in GLOB.diagonals) + var/turf/open/line_turf = get_step(owner, swipe_dir) + for (var/i in 1 to projectile_type::range) + if (!istype(line_turf) || line_turf.is_blocked_turf(exclude_mobs = TRUE)) + break + var/obj/effect/temp_visual/telegraphing/line/telegraph = new(line_turf) + telegraph.dir = swipe_dir + line_turf = get_step(line_turf, swipe_dir) + + SLEEP_CHECK_DEATH(0.8 SECONDS, owner) + + for (var/swipe_dir in GLOB.diagonals) + shoot_projectile(get_turf(owner), get_step(owner, swipe_dir), dir2angle(swipe_dir), owner) + + SLEEP_CHECK_DEATH(1.2 SECONDS, owner) + StartCooldown() + SLEEP_CHECK_DEATH(0.6 SECONDS, owner) + enable_cooldown_actions() + return TRUE + +/obj/projectile/tentacle_lash + name = "tentacle spike" + icon_state = "tentacle_spike" + pass_flags = PASSTABLE + damage = 5 // +10 from the grab + armor_flag = MELEE + range = 7 + hit_prone_targets = TRUE + hitsound = 'sound/effects/wounds/pierce1.ogg' + sharpness = SHARP_POINTY + /// Beam connecting us and the firer + var/datum/beam/tentacle_beam = null + /// Does this projectile persist and reel in targets? + var/reel_in = TRUE + /// How long does the projectile persist? + var/duration = 1.2 SECONDS + /// Damage dealt to targets who get snatched from entering the beam or being hit directly + var/snatch_damage = 10 + +/obj/projectile/tentacle_lash/stab + damage = 15 + range = 2 + duration = 0.2 SECONDS // Just for visual flair + reel_in = FALSE + +/obj/projectile/tentacle_lash/fire(fire_angle, atom/direct_target) + . = ..() + if (!firer) + return + tentacle_beam = Beam(firer, "goliath_tentacle", beam_type = (reel_in ? /obj/effect/ebeam/reacting : /obj/effect/ebeam), emissive = FALSE) + if (reel_in) + RegisterSignal(tentacle_beam, COMSIG_BEAM_ENTERED, PROC_REF(on_beam_entered)) + +/obj/projectile/tentacle_lash/Destroy() + QDEL_NULL(tentacle_beam) + return ..() + +// Don't range out, stop and persist until we're done +/obj/projectile/tentacle_lash/on_range() + STOP_PROCESSING(SSprojectiles, src) + // Reset to tile center + pixel_x = 0 + pixel_y = 0 + QDEL_IN(src, duration) + +/obj/projectile/tentacle_lash/prehit_pierce(atom/target) + // Ye 'ole colossus cheese + if (astype(target, /mob/living)?.stat == DEAD) + return PROJECTILE_PIERCE_PHASE + return ..() + +/obj/projectile/tentacle_lash/on_hit(atom/target, blocked, pierce_hit) + . = ..() + if (!reel_in || !isliving(target) || blocked >= 100 || pierce_hit || . != BULLET_ACT_HIT) + return + snatch_target(target) + +/obj/projectile/tentacle_lash/proc/on_beam_entered(datum/beam/source, obj/effect/ebeam/hit, atom/movable/entered) + SIGNAL_HANDLER + + if (!reel_in || entered == firer || !isliving(entered)) + return + + var/mob/living/victim = entered + if ((!firer || !firer.faction_check_atom(victim)) && victim.stat != DEAD) + INVOKE_ASYNC(src, PROC_REF(snatch_target), entered) + +/obj/projectile/tentacle_lash/proc/snatch_target(mob/living/victim) + if (HAS_TRAIT(victim, TRAIT_TENTACLE_IMMUNE) || SEND_SIGNAL(victim, COMSIG_TENDRIL_TENTACLED_GRABBED) & COMPONENT_TENDRIL_CANCEL_TENTACLE_GRAB) + return + + to_chat(victim, span_userdanger("You're snatched by [firer]'s tentacles!")) + victim.apply_damage(snatch_damage, BRUTE, BODY_ZONE_CHEST, wound_bonus = CANT_WOUND) + if (QDELETED(victim)) + qdel(src) + return + var/snatch_callback = null + if (istype(firer, /mob/living/basic/mining/tendril)) + var/mob/living/basic/mining/tendril/tendril = firer + snatch_callback = CALLBACK(tendril, TYPE_PROC_REF(/mob/living/basic/mining/tendril, snatch_react)) + victim.throw_at(firer, initial(range), 1, firer, FALSE, gentle = TRUE, callback = snatch_callback) + playsound(victim, hitsound, 50, -3, pressure_affected = FALSE) + qdel(src) + +/// An ability which makes spikes come out of the ground towards your target +/datum/action/cooldown/mob_cooldown/tendril_chaser + name = "Impaling Spikes" + desc = "Send a spiked subterranean tendril chasing after your target." + button_icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi' + button_icon_state = "spikes_stabbing" + background_icon_state = "bg_demon" + overlay_icon_state = "bg_demon_border" + cooldown_time = 8 SECONDS + click_to_activate = TRUE + shared_cooldown = NONE + /// Lazy list of references to spike trails + var/list/active_chasers + /// Health percentage threshold at which we send out wide charsers after the main target + var/wide_chaser_threshold = 0.7 + +/datum/action/cooldown/mob_cooldown/tendril_chaser/Grant(mob/granted_to) + . = ..() + RegisterSignal(granted_to, COMSIG_MOB_ABILITY_STARTED, PROC_REF(on_ability_started)) + RegisterSignal(granted_to, COMSIG_MOB_ABILITY_FINISHED, PROC_REF(on_ability_finished)) + +// Clean up after ourselves +/datum/action/cooldown/mob_cooldown/tendril_chaser/Remove(mob/removed_from) + UnregisterSignal(removed_from, list(COMSIG_MOB_ABILITY_STARTED, COMSIG_MOB_ABILITY_FINISHED)) + QDEL_LIST(active_chasers) + return ..() + +/datum/action/cooldown/mob_cooldown/tendril_chaser/proc/on_ability_started(mob/living/owner, datum/action/cooldown/activated) + SIGNAL_HANDLER + + // Delete all of our chasers when our owner triggers cross spikes as to not cause guaranteed damage + if (istype(activated, /datum/action/cooldown/mob_cooldown/tendril_cross_spikes)) + QDEL_LIST(active_chasers) + +/datum/action/cooldown/mob_cooldown/tendril_chaser/proc/on_ability_finished(mob/living/owner, datum/action/cooldown/activated) + SIGNAL_HANDLER + + if (istype(activated, /datum/action/cooldown/mob_cooldown/tendril_cross_spikes)) + ResetCooldown() + +/datum/action/cooldown/mob_cooldown/tendril_chaser/Activate(atom/target) + . = ..() + var/primary_type = /obj/effect/temp_visual/effect_trail/tendril_chaser + if (isliving(owner)) + var/mob/living/as_living = owner + if (as_living.health / as_living.maxHealth <= wide_chaser_threshold) + primary_type = /obj/effect/temp_visual/effect_trail/tendril_chaser/wide_area + + var/obj/effect/temp_visual/effect_trail/tendril_chaser/chaser = new primary_type(get_turf(owner), target) + LAZYADD(active_chasers, WEAKREF(chaser)) + RegisterSignal(chaser, COMSIG_QDELETING, PROC_REF(on_chaser_destroyed)) + playsound(owner, 'sound/effects/magic/demon_attack1.ogg', vol = 100, vary = TRUE, pressure_affected = FALSE) + +/// Remove a spike trail from our list of active trails +/datum/action/cooldown/mob_cooldown/tendril_chaser/proc/on_chaser_destroyed(atom/chaser) + SIGNAL_HANDLER + LAZYREMOVE(active_chasers, WEAKREF(chaser)) + +/obj/effect/temp_visual/effect_trail/tendril_chaser + duration = 10 SECONDS + move_speed = 4 + spawned_effect = /obj/effect/temp_visual/emerging_ground_spike/tendril + /// Do we spawn spikes around ourselves as well or only on our own turf? + var/area_spawn = FALSE + +/obj/effect/temp_visual/effect_trail/tendril_chaser/wide_area + area_spawn = TRUE + +/obj/effect/temp_visual/effect_trail/tendril_chaser/add_spawner() + return + +/obj/effect/temp_visual/effect_trail/tendril_chaser/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change) + . = ..() + if (!area_spawn) + var/turf/spawn_turf = get_turf(src) + if (!(locate(/obj/effect/temp_visual/emerging_ground_spike/tendril) in spawn_turf) && isopenturf(spawn_turf)) + new spawned_effect(spawn_turf) + return + + for (var/spawn_dir in GLOB.cardinals) + if (spawn_dir & REVERSE_DIR(movement_dir)) + continue + var/turf/spawn_loc = get_step(src, spawn_dir) + if (!(locate(/obj/effect/temp_visual/emerging_ground_spike/tendril) in spawn_loc) && isopenturf(spawn_loc)) + new spawned_effect(spawn_loc) + +/obj/effect/temp_visual/emerging_ground_spike/tendril + icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi' + icon_state = "spikes_stabbing" + duration = 0.7 SECONDS + position_variance = 3 + impale_damage = 10 + damage_blacklist_typecache = list( + /mob/living/basic/mining/tendril, + ) + impale_wound_bonus = CANT_WOUND + // Have we hit someone yet? + var/hit_loser = FALSE + +/obj/effect/temp_visual/emerging_ground_spike/tendril/single + icon_state = "spike" + duration = 1 SECONDS + harm_delay = 0.25 SECONDS + position_variance = 5 + +/obj/effect/temp_visual/emerging_ground_spike/tendril/impale() + . = ..() + hit_loser |= . + RegisterSignal(loc, COMSIG_ATOM_ENTERED, PROC_REF(on_entered)) + +/obj/effect/temp_visual/emerging_ground_spike/tendril/proc/on_entered(atom/source, atom/movable/arrived, atom/old_loc, list/atom/old_locs) + SIGNAL_HANDLER + + if (!isliving(arrived)) + return + + if (harm_mob(arrived) && !hit_loser) + playsound(src, 'sound/items/weapons/slice.ogg', vol = 50, vary = TRUE, pressure_affected = FALSE) + hit_loser = TRUE + +/datum/action/cooldown/mob_cooldown/tendril_cross_spikes + name = "Cross Spikes" + desc = "Create a wave of spikes around yourself, impaling anyone caught in it." + button_icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi' + button_icon_state = "spike" + background_icon_state = "bg_demon" + overlay_icon_state = "bg_demon_border" + click_to_activate = FALSE + cooldown_time = 10 SECONDS + melee_cooldown_time = 0 + shared_cooldown = NONE + /// Health threshold at which we reduce the amount of empty spots on the ground + var/health_threshold = 0.3 + +/datum/action/cooldown/mob_cooldown/tendril_cross_spikes/Activate(atom/target) + disable_cooldown_actions() + spawn_spikes() + SLEEP_CHECK_DEATH(0.4 SECONDS, owner) + spawn_spikes(inverse = TRUE) + StartCooldown() + enable_cooldown_actions() + return TRUE + +/datum/action/cooldown/mob_cooldown/tendril_cross_spikes/proc/spawn_spikes(inverse = FALSE) + var/list/turf/spike_turfs = list() + var/turf/owner_turf = get_turf(owner) + + var/reduced_spawns = FALSE + if (isliving(owner)) + var/mob/living/as_living = owner + if (as_living.health / as_living.maxHealth <= health_threshold) + reduced_spawns = TRUE + + for (var/turf/open/target_turf in oview(7, owner_turf)) + if (sqrt((target_turf.x - owner_turf.x) ** 2 + (target_turf.y - owner_turf.y) ** 2) > 9.5) // big circle is a lie + continue + + if (reduced_spawns) + if (abs(target_turf.x - owner_turf.x) % 2 == abs(target_turf.y - owner_turf.y + inverse) % 2) + new /obj/effect/temp_visual/telegraphing/circle/short(target_turf) + spike_turfs += target_turf + continue + + var/row_diff = inverse ? abs(target_turf.x - owner_turf.x) : abs(target_turf.y - owner_turf.y) + var/column_diff = inverse ? abs(target_turf.y - owner_turf.y) : abs(target_turf.x - owner_turf.x) + var/row = floor((row_diff + 1) / 3) + if (row % 2 == 0) + if (row_diff - row * 3 == 0) + if (column_diff % 4 == 2) + continue + else + if (column_diff % 4 != 0) + continue + else + if (row_diff - row * 3 == 0) + if (column_diff % 4 == 0) + continue + else + if (column_diff % 4 != 2) + continue + + new /obj/effect/temp_visual/telegraphing/circle/short(target_turf) + spike_turfs += target_turf + + SLEEP_CHECK_DEATH(1 SECONDS, owner) + + for (var/turf/open/to_spawn in spike_turfs) + new /obj/effect/temp_visual/emerging_ground_spike/tendril/single(to_spawn) + + SLEEP_CHECK_DEATH(0.8 SECONDS, owner) + +/datum/action/cooldown/mob_cooldown/projectile_attack/tendril_melee + name = "Tentacle Stab" + desc = "Stab nearby hostiles with long tentacles." + button_icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi' + button_icon_state = "goliath_tentacle_wiggle" + background_icon_state = "bg_demon" + overlay_icon_state = "bg_demon_border" + click_to_activate = FALSE + cooldown_time = 4 SECONDS + melee_cooldown_time = 0 + shared_cooldown = NONE + projectile_type = /obj/projectile/tentacle_lash/stab + +/datum/action/cooldown/mob_cooldown/projectile_attack/tendril_melee/Activate(atom/target_atom, warning = TRUE) + if (warning) + for (var/stab_dir in GLOB.alldirs) + var/turf/open/stab_turf = get_step(owner, stab_dir) + if (!istype(stab_turf)) + continue + var/obj/effect/temp_visual/telegraphing/line/short/telegraph = new(stab_turf) + telegraph.dir = stab_dir + + SLEEP_CHECK_DEATH(0.5 SECONDS, owner) + + for (var/stab_dir in GLOB.alldirs) + shoot_projectile(get_turf(owner), get_step(owner, stab_dir), firer = owner) + + SLEEP_CHECK_DEATH(0.5 SECONDS, owner) + StartCooldown() + return TRUE diff --git a/code/modules/mob/living/basic/lavaland/tendril/tendril_ai.dm b/code/modules/mob/living/basic/lavaland/tendril/tendril_ai.dm new file mode 100644 index 00000000000..77da7086dfa --- /dev/null +++ b/code/modules/mob/living/basic/lavaland/tendril/tendril_ai.dm @@ -0,0 +1,35 @@ +/datum/ai_controller/basic_controller/tendril + blackboard = list( + BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic, + BB_TARGET_MINIMUM_STAT = HARD_CRIT, + ) + + planning_subtrees = list( + /datum/ai_planning_subtree/call_reinforcements/mining, + /datum/ai_planning_subtree/target_retaliate/check_faction, + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/targeted_mob_ability/tendril_chaser, + /datum/ai_planning_subtree/use_mob_ability/tendril_spikes, + /datum/ai_planning_subtree/use_mob_ability/tendril_lash, + ) + +/datum/ai_planning_subtree/targeted_mob_ability/tendril_chaser + ability_key = BB_TENDRIL_CHASER + operational_datums = list(/datum/component/ai_target_timer) + finish_planning = FALSE + +/datum/ai_planning_subtree/use_mob_ability/tendril_lash + ability_key = BB_TENDRIL_LASH + +/datum/ai_planning_subtree/use_mob_ability/tendril_lash/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + if (!controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]) + return FALSE + return ..() + +/datum/ai_planning_subtree/use_mob_ability/tendril_spikes + ability_key = BB_TENDRIL_SPIKES + +/datum/ai_planning_subtree/use_mob_ability/tendril_spikes/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + if (!controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]) + return FALSE + return ..() diff --git a/code/modules/mob/living/basic/lavaland/watcher/watcher_ai.dm b/code/modules/mob/living/basic/lavaland/watcher/watcher_ai.dm index d31f76eaee6..cd45eb9c6ec 100644 --- a/code/modules/mob/living/basic/lavaland/watcher/watcher_ai.dm +++ b/code/modules/mob/living/basic/lavaland/watcher/watcher_ai.dm @@ -1,12 +1,16 @@ /datum/ai_controller/basic_controller/watcher blackboard = list( BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic, + BB_TARGET_PRIORITY_STRATEGY = /datum/target_priority_strategy/mining, + BB_RANGED_SKIRMISH_MIN_DISTANCE = 3, + BB_RANGED_SKIRMISH_MAX_DISTANCE = 5, ) ai_movement = /datum/ai_movement/basic_avoidance idle_behavior = /datum/idle_behavior/idle_random_walk planning_subtrees = list( /datum/ai_planning_subtree/escape_captivity, + /datum/ai_planning_subtree/call_reinforcements/mining, /datum/ai_planning_subtree/target_retaliate/check_faction, /datum/ai_planning_subtree/simple_find_target, /datum/ai_planning_subtree/maintain_distance, diff --git a/code/modules/mob/living/basic/minebots/minebot.dm b/code/modules/mob/living/basic/minebots/minebot.dm index 0409095f8a8..525f1450141 100644 --- a/code/modules/mob/living/basic/minebots/minebot.dm +++ b/code/modules/mob/living/basic/minebots/minebot.dm @@ -255,13 +255,13 @@ /mob/living/basic/mining_drone/early_melee_attack(atom/target, list/modifiers, ignore_cooldown) . = ..() - if(!.) - return FALSE + if(.) + return if(!istype(target, /mob/living/basic/node_drone)) - return TRUE + return BASIC_MOB_CONTINUE_ATTACK_CHAIN repair_node_drone(target) - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN /mob/living/basic/mining_drone/proc/repair_node_drone(mob/living/my_target) do_sparks(5, FALSE, source = my_target) diff --git a/code/modules/mob/living/basic/pets/cat/cat.dm b/code/modules/mob/living/basic/pets/cat/cat.dm index 88e7b9a5adf..060adddd0fa 100644 --- a/code/modules/mob/living/basic/pets/cat/cat.dm +++ b/code/modules/mob/living/basic/pets/cat/cat.dm @@ -103,21 +103,21 @@ /mob/living/basic/pet/cat/early_melee_attack(atom/target, list/modifiers, ignore_cooldown) . = ..() - if(!.) - return FALSE + if(.) + return if(istype(target, /obj/machinery/oven/range) && can_interact_with_stove) target.attack_hand(src) - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN if(!can_hold_item) - return TRUE + return BASIC_MOB_CONTINUE_ATTACK_CHAIN if(!is_type_in_list(target, huntable_items) || held_food) - return TRUE + return BASIC_MOB_CONTINUE_ATTACK_CHAIN var/atom/movable/movable_target = target movable_target.forceMove(src) - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN /mob/living/basic/pet/cat/Exited(atom/movable/gone, direction) . = ..() diff --git a/code/modules/mob/living/basic/pets/dog/_dog.dm b/code/modules/mob/living/basic/pets/dog/_dog.dm index 0db8b036eee..21f07026140 100644 --- a/code/modules/mob/living/basic/pets/dog/_dog.dm +++ b/code/modules/mob/living/basic/pets/dog/_dog.dm @@ -35,6 +35,8 @@ attack_sound = 'sound/items/weapons/bite.ogg' attack_vis_effect = ATTACK_EFFECT_BITE melee_attack_cooldown = 0.8 SECONDS + melee_damage_lower = 5 + melee_damage_upper = 10 /// Instructions you can give to dogs var/static/list/pet_commands = list( /datum/pet_command/idle, diff --git a/code/modules/mob/living/basic/pets/orbie/orbie.dm b/code/modules/mob/living/basic/pets/orbie/orbie.dm index 40a93f4b882..fbbdfd89d22 100644 --- a/code/modules/mob/living/basic/pets/orbie/orbie.dm +++ b/code/modules/mob/living/basic/pets/orbie/orbie.dm @@ -63,14 +63,14 @@ /mob/living/basic/orbie/early_melee_attack(atom/target, list/modifiers, ignore_cooldown) . = ..() - if(!.) - return FALSE + if(.) + return if(src == target || happy_state || !istype(target)) - return TRUE + return BASIC_MOB_CONTINUE_ATTACK_CHAIN toggle_happy_state() addtimer(CALLBACK(src, PROC_REF(toggle_happy_state)), 30 SECONDS) - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN /mob/living/basic/orbie/proc/on_lights(datum/source) SIGNAL_HANDLER diff --git a/code/modules/mob/living/basic/pets/parrot/_parrot.dm b/code/modules/mob/living/basic/pets/parrot/_parrot.dm index 8e338d7bf60..d40a6af9b3d 100644 --- a/code/modules/mob/living/basic/pets/parrot/_parrot.dm +++ b/code/modules/mob/living/basic/pets/parrot/_parrot.dm @@ -282,14 +282,14 @@ GLOBAL_LIST_INIT(strippable_parrot_items, create_strippable_list(list( /// This is pretty much meant for players, AI will use the task-specific procs instead. /mob/living/basic/parrot/early_melee_attack(atom/target, list/modifiers, ignore_cooldown) . = ..() - if(!.) - return FALSE + if(.) + return if(isitem(target) && steal_from_ground(target)) - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN if(iscarbon(target) && steal_from_mob(target)) - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN /// Picks up an item from the ground and puts it in our claws. Returns TRUE if we picked it up, FALSE otherwise. /mob/living/basic/parrot/proc/steal_from_ground(obj/item/target) diff --git a/code/modules/mob/living/basic/pets/parrot/poly.dm b/code/modules/mob/living/basic/pets/parrot/poly.dm index 88885ad8861..cef0a445acd 100644 --- a/code/modules/mob/living/basic/pets/parrot/poly.dm +++ b/code/modules/mob/living/basic/pets/parrot/poly.dm @@ -7,7 +7,7 @@ /// Poly has only just survived a round, and is doing a consecutive one. #define POLY_CONSECUTIVE_ROUND "consecutive_round" /// haunt filter we apply to who we possess -#define POLY_POSSESS_FILTER +#define POLY_POSSESS_FILTER "poly_possess_filter" /// haunt filter color we apply to who we possess #define POLY_POSSESS_GLOW "#522059" diff --git a/code/modules/mob/living/basic/pets/pet.dm b/code/modules/mob/living/basic/pets/pet.dm index ae32718b658..d2f3ce28348 100644 --- a/code/modules/mob/living/basic/pets/pet.dm +++ b/code/modules/mob/living/basic/pets/pet.dm @@ -5,5 +5,7 @@ mob_biotypes = MOB_ORGANIC|MOB_BEAST default_blood_volume = BLOOD_VOLUME_NORMAL basic_mob_flags = SENDS_DEATH_MOODLETS + melee_damage_lower = 5 + melee_damage_upper = 5 /// if the mob is protected from being renamed by collars. var/unique_pet = FALSE diff --git a/code/modules/mob/living/basic/ruin_defender/mimic/mimic.dm b/code/modules/mob/living/basic/ruin_defender/mimic/mimic.dm index 854c74d30ec..c19af055529 100644 --- a/code/modules/mob/living/basic/ruin_defender/mimic/mimic.dm +++ b/code/modules/mob/living/basic/ruin_defender/mimic/mimic.dm @@ -138,7 +138,7 @@ GLOBAL_LIST_INIT(animatable_blacklist, typecacheof(list( /mob/living/basic/mimic/crate/early_melee_attack(atom/target, list/modifiers, ignore_cooldown) if(target == src) toggle_open() - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN return ..() /mob/living/basic/mimic/crate/CanAllowThrough(atom/movable/mover, border_dir) @@ -411,10 +411,13 @@ GLOBAL_LIST_INIT(animatable_blacklist, typecacheof(list( return TRUE /mob/living/basic/mimic/copy/ranged/CopyObject(obj/item/gun/original, mob/living/creator, destroy_original = 0) - if(..()) - obj_damage = 0 - melee_damage_upper = original.force - melee_damage_lower = original.force - max(0, (original.force / 2)) + . = ..() + if(!.) + return + obj_damage = 0 + melee_damage_upper = original.force + melee_damage_lower = original.force - max(0, (original.force / 2)) + RegisterSignal(original, COMSIG_GUN_REPLENISHED_CHARGE, PROC_REF(on_regained_charge)) /mob/living/basic/mimic/copy/ranged/CopyObjectVisuals(obj/original) name = original.name @@ -424,4 +427,9 @@ GLOBAL_LIST_INIT(animatable_blacklist, typecacheof(list( /mob/living/basic/mimic/copy/ranged/can_use_guns(obj/item/gun) return TRUE +/// If our gun ran out of ammo but then regenerated it then we should go back to shooting +/mob/living/basic/mimic/copy/ranged/proc/on_regained_charge() + SIGNAL_HANDLER + ai_controller?.set_blackboard_key(BB_GUNMIMIC_GUN_EMPTY, FALSE) + #undef CANT_INSERT_FULL diff --git a/code/modules/mob/living/basic/ruin_defender/mimic/mimic_ai.dm b/code/modules/mob/living/basic/ruin_defender/mimic/mimic_ai.dm index e1b664e852a..9e3475b7a6a 100644 --- a/code/modules/mob/living/basic/ruin_defender/mimic/mimic_ai.dm +++ b/code/modules/mob/living/basic/ruin_defender/mimic/mimic_ai.dm @@ -87,3 +87,30 @@ return controller.queue_behavior(/datum/ai_behavior/basic_ranged_attack/avoid_friendly_fire, BB_BASIC_MOB_CURRENT_TARGET, BB_TARGETING_STRATEGY, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION) return SUBTREE_RETURN_FINISH_PLANNING //we are going into battle...no distractions. + +/// Special subtree for living wands/staffs of animation which will focus on animating more things +/datum/ai_controller/basic_controller/mimic_copy/gun/animator + blackboard = list( + BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic, + BB_HUNT_TARGETING_STRATEGY = /datum/targeting_strategy/anything, + BB_GUNMIMIC_GUN_EMPTY = FALSE, + ) + planning_subtrees = list( + /datum/ai_planning_subtree/shoot_animatable_objects, + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/random_speech/when_has_target/mimic/gun, + /datum/ai_planning_subtree/basic_melee_attack_subtree, + ) + +/// Try to find objects and then shoot them +/datum/ai_planning_subtree/shoot_animatable_objects + +/datum/ai_planning_subtree/shoot_animatable_objects/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + if(controller.blackboard[BB_GUNMIMIC_GUN_EMPTY]) + return // No charge in our gun + if(!controller.blackboard_key_exists(BB_CURRENT_HUNTING_TARGET)) + controller.queue_behavior(/datum/ai_behavior/find_and_set/animatable, BB_CURRENT_HUNTING_TARGET) + return + controller.queue_behavior(/datum/ai_behavior/ranged_skirmish, BB_CURRENT_HUNTING_TARGET, BB_HUNT_TARGETING_STRATEGY, null, 9, 0) + controller.queue_behavior(/datum/ai_behavior/clear_key, BB_CURRENT_HUNTING_TARGET) + return SUBTREE_RETURN_FINISH_PLANNING 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 6f1ff9e864f..d114b6d42a1 100644 --- a/code/modules/mob/living/basic/space_fauna/carp/carp.dm +++ b/code/modules/mob/living/basic/space_fauna/carp/carp.dm @@ -320,4 +320,4 @@ /// If someone slaps one of the school, scatter /mob/living/basic/carp/passive/proc/on_attacked(mob/living/attacker) for(var/mob/living/basic/carp/passive/schoolmate in oview(src, 9)) - schoolmate.ai_controller?.insert_blackboard_key_lazylist(BB_BASIC_MOB_RETALIATE_LIST, attacker) + schoolmate.ai_controller?.set_blackboard_key_assoc_lazylist(BB_BASIC_MOB_RETALIATE_LIST, attacker, world.time) diff --git a/code/modules/mob/living/basic/space_fauna/carp/magicarp.dm b/code/modules/mob/living/basic/space_fauna/carp/magicarp.dm index 1eccb697b59..9e2224de1fc 100644 --- a/code/modules/mob/living/basic/space_fauna/carp/magicarp.dm +++ b/code/modules/mob/living/basic/space_fauna/carp/magicarp.dm @@ -2,38 +2,47 @@ GLOBAL_LIST_INIT(magicarp_spell_types, list( /obj/projectile/magic/animate = "dancing", /obj/projectile/magic/arcane_barrage = "arcane", + /obj/projectile/magic/babel = "babbling", /obj/projectile/magic/change = "transforming", /obj/projectile/magic/death = "grim", /obj/projectile/magic/door = "unbarred", /obj/projectile/magic/fireball = "blazing", + /obj/projectile/magic/freeze = "frigid", + /obj/projectile/magic/levitate = "weightless", /obj/projectile/magic/resurrection = "vital", /obj/projectile/magic/spellblade = "vorpal", + /obj/projectile/magic/swap = "quantum", /obj/projectile/magic/teleport = "warping", - /obj/projectile/magic/babel = "babbling", )) /// A reduced list of spells for magicarp spawned in xenobiology, less disruptive GLOBAL_LIST_INIT(xenobiology_magicarp_spell_types, list( /obj/projectile/magic/animate = "dancing", - /obj/projectile/magic/teleport = "warping", + /obj/projectile/magic/arcane_barrage = "arcane", /obj/projectile/magic/door = "unbarred", /obj/projectile/magic/fireball = "blazing", + /obj/projectile/magic/freeze = "frigid", + /obj/projectile/magic/levitate = "weightless", /obj/projectile/magic/spellblade = "vorpal", - /obj/projectile/magic/arcane_barrage = "arcane", + /obj/projectile/magic/swap = "quantum", + /obj/projectile/magic/teleport = "warping", )) /// Associative list of magicarp spells to colours, expand this list if you expand the other lists GLOBAL_LIST_INIT(magicarp_spell_colours, list( /obj/projectile/magic/animate = COLOR_CARP_RUSTY, /obj/projectile/magic/arcane_barrage = COLOR_CARP_PURPLE, + /obj/projectile/magic/babel = COLOR_CARP_BROWN, /obj/projectile/magic/change = COLOR_CARP_PINK, /obj/projectile/magic/death = COLOR_CARP_DARK_BLUE, /obj/projectile/magic/door = COLOR_CARP_GREEN, /obj/projectile/magic/fireball = COLOR_CARP_RED, + /obj/projectile/magic/freeze = COLOR_CARP_TURQUOISE, + /obj/projectile/magic/levitate = COLOR_CARP_DARK_PURPLE, /obj/projectile/magic/resurrection = COLOR_CARP_PALE_GREEN, /obj/projectile/magic/spellblade = COLOR_CARP_SILVER, + /obj/projectile/magic/swap = COLOR_CARP_LIGHT_BLUE, /obj/projectile/magic/teleport = COLOR_CARP_GRAPE, - /obj/projectile/magic/babel = COLOR_CARP_BROWN, )) /** diff --git a/code/modules/mob/living/basic/space_fauna/changeling/flesh_spider.dm b/code/modules/mob/living/basic/space_fauna/changeling/flesh_spider.dm index c6116cd041a..fa3015c011b 100644 --- a/code/modules/mob/living/basic/space_fauna/changeling/flesh_spider.dm +++ b/code/modules/mob/living/basic/space_fauna/changeling/flesh_spider.dm @@ -19,7 +19,7 @@ damage_coeff = list(BRUTE = 1, BURN = 1.25, TOX = 4, STAMINA = 1, OXY = 1) basic_mob_flags = FLAMMABLE_MOB status_flags = NONE - speed = -0.1 + speed = 0.2 maxHealth = 90 health = 90 melee_damage_lower = 15 @@ -61,7 +61,7 @@ ) AddComponent(\ /datum/component/regenerator,\ - regeneration_delay = 4 SECONDS,\ + regeneration_delay = 3 SECONDS,\ brute_per_second = maxHealth / 6,\ outline_colour = COLOR_PINK,\ ) diff --git a/code/modules/mob/living/basic/space_fauna/eyeball/_eyeball.dm b/code/modules/mob/living/basic/space_fauna/eyeball/_eyeball.dm index 26bb5548e80..7b2846d4272 100644 --- a/code/modules/mob/living/basic/space_fauna/eyeball/_eyeball.dm +++ b/code/modules/mob/living/basic/space_fauna/eyeball/_eyeball.dm @@ -96,16 +96,16 @@ /mob/living/basic/eyeball/early_melee_attack(atom/target, list/modifiers, ignore_cooldown) . = ..() - if(!.) - return FALSE + if(.) + return if(!ishuman(target)) - return TRUE + return BASIC_MOB_CONTINUE_ATTACK_CHAIN var/mob/living/carbon/human_target = target var/obj/item/organ/eyes/eyes = human_target.get_organ_slot(ORGAN_SLOT_EYES) if(isnull(eyes) || eyes.damage < 10) - return TRUE + return BASIC_MOB_CONTINUE_ATTACK_CHAIN heal_eye_damage(human_target, eyes) - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN /mob/living/basic/eyeball/proc/heal_eye_damage(mob/living/target, obj/item/organ/eyes/eyes) if(!COOLDOWN_FINISHED(src, eye_healing)) diff --git a/code/modules/mob/living/basic/space_fauna/garden_gnome.dm b/code/modules/mob/living/basic/space_fauna/garden_gnome.dm index d2ab4e691b5..f6926b2ea51 100644 --- a/code/modules/mob/living/basic/space_fauna/garden_gnome.dm +++ b/code/modules/mob/living/basic/space_fauna/garden_gnome.dm @@ -121,7 +121,7 @@ if (!istype(attacker)) return for (var/mob/living/basic/garden_gnome/potential_gnome in oview(src, 7)) - potential_gnome.ai_controller.insert_blackboard_key_lazylist(BB_BASIC_MOB_RETALIATE_LIST, attacker) + potential_gnome.ai_controller.set_blackboard_key_assoc_lazylist(BB_BASIC_MOB_RETALIATE_LIST, attacker, world.time) /datum/ai_controller/basic_controller/garden_gnome blackboard = list( diff --git a/code/modules/mob/living/basic/space_fauna/hivebot/_hivebot.dm b/code/modules/mob/living/basic/space_fauna/hivebot/_hivebot.dm index 925b5eb271e..7b5edab617a 100644 --- a/code/modules/mob/living/basic/space_fauna/hivebot/_hivebot.dm +++ b/code/modules/mob/living/basic/space_fauna/hivebot/_hivebot.dm @@ -99,16 +99,16 @@ /mob/living/basic/hivebot/mechanic/early_melee_attack(atom/target, list/modifiers, ignore_cooldown) . = ..() - if(!.) - return FALSE + if(.) + return if(ismachinery(target)) repair_machine(target) - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN if(istype(target, /mob/living/basic/hivebot)) repair_hivebot(target) - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN /mob/living/basic/hivebot/mechanic/proc/repair_machine(obj/machinery/fixable) if(fixable.get_integrity() >= fixable.max_integrity) diff --git a/code/modules/mob/living/basic/space_fauna/lightgeist.dm b/code/modules/mob/living/basic/space_fauna/lightgeist.dm index 36ae135619c..50d59efbf2a 100644 --- a/code/modules/mob/living/basic/space_fauna/lightgeist.dm +++ b/code/modules/mob/living/basic/space_fauna/lightgeist.dm @@ -41,18 +41,14 @@ minimum_survivable_temperature = 0 maximum_survivable_temperature = 1500 obj_damage = 0 + pull_force = 0 environment_smash = ENVIRONMENT_SMASH_NONE ai_controller = /datum/ai_controller/basic_controller/lightgeist /mob/living/basic/lightgeist/Initialize(mapload) . = ..() - ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT) - ADD_TRAIT(src, TRAIT_MEDICAL_HUD, INNATE_TRAIT) - - remove_verb(src, /mob/living/verb/pulled) - remove_verb(src, /mob/verb/me_verb) - + add_traits(list(TRAIT_VENTCRAWLER_ALWAYS, TRAIT_MEDICAL_HUD, TRAIT_EMOTEMUTE), INNATE_TRAIT) AddElement(/datum/element/simple_flying) AddComponent(\ /datum/component/healing_touch,\ diff --git a/code/modules/mob/living/basic/space_fauna/meteor_heart/chasing_spikes.dm b/code/modules/mob/living/basic/space_fauna/meteor_heart/chasing_spikes.dm index b50b089b0ff..60288e9c5e7 100644 --- a/code/modules/mob/living/basic/space_fauna/meteor_heart/chasing_spikes.dm +++ b/code/modules/mob/living/basic/space_fauna/meteor_heart/chasing_spikes.dm @@ -45,6 +45,8 @@ var/position_variance = 8 /// Damage to deal on impale var/impale_damage = 15 + /// Wound bonus on impale + var/impale_wound_bonus = 0 /// Typecache of types of mobs not to damage var/list/damage_blacklist_typecache = list( /mob/living/basic/meteor_heart, @@ -67,14 +69,22 @@ /obj/effect/temp_visual/emerging_ground_spike/proc/impale() if (!isturf(loc)) return + var/hit_someone = FALSE for(var/mob/living/victim in loc) - if (is_type_in_typecache(victim, damage_blacklist_typecache)) - continue - hit_someone = TRUE - var/target_zone = victim.resting ? BODY_ZONE_CHEST : pick_weight(standing_damage_zones) - victim.apply_damage(impale_damage, damagetype = BRUTE, def_zone = target_zone, sharpness = SHARP_POINTY) + if (harm_mob(victim)) + hit_someone = TRUE + if (hit_someone) playsound(src, 'sound/items/weapons/slice.ogg', vol = 50, vary = TRUE, pressure_affected = FALSE) else playsound(src, 'sound/misc/splort.ogg', vol = 25, vary = TRUE, pressure_affected = FALSE) + return hit_someone + +/obj/effect/temp_visual/emerging_ground_spike/proc/harm_mob(mob/living/victim) + if (is_type_in_typecache(victim, damage_blacklist_typecache)) + return FALSE + + var/target_zone = victim.resting ? BODY_ZONE_CHEST : pick_weight(standing_damage_zones) + victim.apply_damage(impale_damage, damagetype = BRUTE, def_zone = target_zone, wound_bonus = impale_wound_bonus, sharpness = SHARP_POINTY) + return TRUE diff --git a/code/modules/mob/living/basic/space_fauna/morph.dm b/code/modules/mob/living/basic/space_fauna/morph.dm index 3190f3313e9..a76704e40fe 100644 --- a/code/modules/mob/living/basic/space_fauna/morph.dm +++ b/code/modules/mob/living/basic/space_fauna/morph.dm @@ -149,29 +149,29 @@ /// Handles the logic for attacking anything. /mob/living/basic/morph/early_melee_attack(atom/target, list/modifiers, ignore_cooldown) . = ..() - if(!.) - return FALSE + if(.) + return if(HAS_TRAIT(src, TRAIT_DISGUISED) && (melee_damage_disguised <= 0)) balloon_alert(src, "can't attack while disguised!") - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN if(isliving(target)) //Eat Corpses to regen health var/mob/living/living_target = target if(living_target.stat != DEAD) - return TRUE + return BASIC_MOB_CONTINUE_ATTACK_CHAIN eat(eatable = living_target, delay = 3 SECONDS, update_health = -50) - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN if(!isitem(target)) //Eat items just to be annoying - return TRUE + return BASIC_MOB_CONTINUE_ATTACK_CHAIN var/obj/item/item_target = target if(item_target.anchored) - return TRUE + return BASIC_MOB_CONTINUE_ATTACK_CHAIN eat(eatable = item_target, delay = 2 SECONDS) - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN /// Eat stuff. Delicious. Return TRUE if we ate something, FALSE otherwise. /// Required: `eatable` is the thing (item or mob) that we are going to eat. diff --git a/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat.dm b/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat.dm index 42e6e831dd5..f0e370c668e 100644 --- a/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat.dm +++ b/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat.dm @@ -171,22 +171,22 @@ /// Checks if we are able to attack this object, as well as send out the signal to see if we get any special regal rat interactions. /mob/living/basic/regal_rat/early_melee_attack(atom/target, list/modifiers, ignore_cooldown) . = ..() - if(!.) - return FALSE + if(.) + return if(DOING_INTERACTION(src, REGALRAT_INTERACTION) || !allowed_to_attack(target)) - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN if(SEND_SIGNAL(target, COMSIG_RAT_INTERACT, src) & COMPONENT_RAT_INTERACTED) - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN if(isnull(mind) || combat_mode) - return TRUE + return BASIC_MOB_CONTINUE_ATTACK_CHAIN if(poison_target(target)) - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN - return TRUE + return BASIC_MOB_CONTINUE_ATTACK_CHAIN /// Checks if we are allowed to attack this mob. Will return TRUE if we are potentially allowed to attack, but if we end up in a case where we should NOT attack, return FALSE. /mob/living/basic/regal_rat/proc/allowed_to_attack(atom/the_target) 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 e8dac3f3f64..75c723aa358 100644 --- a/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm +++ b/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm @@ -62,6 +62,8 @@ var/draining = FALSE /// Have we already given this revenant abilities? var/generated_objectives_and_spells = FALSE + /// ckey of the player who controlled this mob when it was killed + var/old_ckey = "" /// Lazylist of drained mobs to ensure that we don't steal a soul from someone twice var/list/drained_mobs = null @@ -348,10 +350,7 @@ visible_message(span_danger("[src]'s body breaks apart into a fine pile of blue dust.")) - var/obj/item/ectoplasm/revenant/goop = new(get_turf(src)) // the ectoplasm will handle moving us out of dormancy - goop.old_ckey = client.ckey - goop.revenant = src - forceMove(goop) + new /obj/item/ectoplasm/revenant(get_turf(src), src) // the ectoplasm will handle moving us out of dormancy /mob/living/basic/revenant/proc/on_move(datum/source, atom/entering_loc) SIGNAL_HANDLER @@ -524,4 +523,30 @@ if(!HAS_TRAIT(src, TRAIT_REVENANT_REVEALED) && !istype(reflecting_in, /obj/structure/mirror/magic)) apply_wibbly_filters(reflection) +/mob/living/basic/revenant/proc/get_new_user() + message_admins("A poll for the reforming revenant was created.") + var/mob/chosen_one = SSpolling.poll_ghosts_for_target("Do you want to be [span_notice(name)] (reforming)?", check_jobban = ROLE_REVENANT, role = ROLE_REVENANT, poll_time = 5 SECONDS, checked_target = src, alert_pic = src, role_name_text = "reforming revenant", chat_text_border_icon = src) + if(!chosen_one) + message_admins("No candidates were found for the new revenant.") + visible_message(span_revenwarning("A blue dust appears from thin air and settles down.")) + new /obj/item/ectoplasm/revenant(get_turf(src)) // inert + qdel(src) + return + + PossessByPlayer(chosen_one.key) + message_admins("[chosen_one.key] has been made into the reformed revenant via poll.") + qdel(chosen_one) + +/mob/living/basic/revenant/proc/reform(cause) + if(QDELETED(src)) + return FALSE + + death_reset() + if(isnull(client)) + INVOKE_ASYNC(src, PROC_REF(get_new_user)) + return TRUE + + message_admins("[client.ckey] has been remade into a revenant.") + log_message("was remade as a revenant.", LOG_GAME) + return TRUE #undef REVENANT_STUNNED_TRAIT diff --git a/code/modules/mob/living/basic/space_fauna/revenant/revenant_abilities.dm b/code/modules/mob/living/basic/space_fauna/revenant/revenant_abilities.dm index f4d3ecb5b59..10da02bcdc5 100644 --- a/code/modules/mob/living/basic/space_fauna/revenant/revenant_abilities.dm +++ b/code/modules/mob/living/basic/space_fauna/revenant/revenant_abilities.dm @@ -1,7 +1,7 @@ #define REVENANT_DEFILE_MIN_DAMAGE 30 #define REVENANT_DEFILE_MAX_DAMAGE 50 -//Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob +//Transmit: the revenant's only direct way to communicate. Sends a single message silently to a single mob /datum/action/cooldown/spell/list_target/telepathy/revenant name = "Revenant Transmit" background_icon_state = "bg_revenant" @@ -12,6 +12,14 @@ antimagic_flags = MAGIC_RESISTANCE_HOLY|MAGIC_RESISTANCE_MIND +/datum/action/cooldown/spell/list_target/telepathy/revenant/get_list_targets(atom/center, target_radius = 7) + if(!istype(center, /mob/living/basic/revenant)) + return ..() + var/mob/living/basic/revenant/revenant = center + if(!revenant.dormant) + return ..() + return ..(get_turf(revenant), 2) + /datum/action/cooldown/spell/aoe/revenant background_icon_state = "bg_revenant" overlay_icon_state = "bg_revenant_border" diff --git a/code/modules/mob/living/basic/space_fauna/revenant/revenant_items.dm b/code/modules/mob/living/basic/space_fauna/revenant/revenant_items.dm index f691521b076..b9007a7f722 100644 --- a/code/modules/mob/living/basic/space_fauna/revenant/revenant_items.dm +++ b/code/modules/mob/living/basic/space_fauna/revenant/revenant_items.dm @@ -5,31 +5,36 @@ icon = 'icons/effects/effects.dmi' icon_state = "revenantEctoplasm" w_class = WEIGHT_CLASS_SMALL - /// Are we currently reforming? - var/reforming = TRUE - /// Are we inert (aka distorted such that we can't reform)? + // Can the revenant reform? var/inert = FALSE - /// The key of the revenant that we started the reform as - var/old_ckey - /// The revenant we're currently storing - var/mob/living/basic/revenant/revenant -/obj/item/ectoplasm/revenant/Initialize(mapload) +/obj/item/ectoplasm/revenant/Initialize(mapload, revenant) . = ..() - addtimer(CALLBACK(src, PROC_REF(try_reform)), 1 MINUTES) + inert = !revenant + if(revenant) + AddComponent(/datum/component/revenant_prison, revenant = revenant) + addtimer(CALLBACK(src, PROC_REF(reform)), 1 MINUTES) /obj/item/ectoplasm/revenant/Destroy() - if(!QDELETED(revenant)) - qdel(revenant) return ..() +/obj/item/ectoplasm/revenant/proc/check_for_mirrors(turf/location, radius) + PRIVATE_PROC(TRUE) + for(var/obj/structure/mirror/mirror in view(radius, location)) + if(mirror.cursable && !mirror.GetComponent(/datum/component/revenant_prison)) + return mirror + return null + /obj/item/ectoplasm/revenant/attack_self(mob/user) - if(!reforming || inert) + if(inert) return ..() user.visible_message( span_notice("[user] scatters [src] in all directions."), - span_notice("You scatter [src] across the area. The particles slowly fade away."), + span_notice("You scatter [src] across the area."), ) + var/obj/structure/mirror/nearby_mirror = check_for_mirrors(drop_location(), 5) + if(nearby_mirror) + transfer_to_mirror(nearby_mirror) user.dropItemToGround(src) qdel(src) @@ -37,14 +42,25 @@ . = ..() if(inert) return - visible_message(span_notice("[src] breaks into particles upon impact, which fade away to nothingness.")) + var/obj/structure/mirror/nearby_mirror = check_for_mirrors(get_turf(hit_atom), 3) + if(!nearby_mirror) + visible_message(span_notice("[src] breaks into particles upon impact, which fade away to nothingness.")) + else + transfer_to_mirror(nearby_mirror) qdel(src) +/obj/item/ectoplasm/revenant/proc/transfer_to_mirror(obj/structure/mirror/nearby_mirror) + PRIVATE_PROC(TRUE) + nearby_mirror.TakeComponent(GetComponent(/datum/component/revenant_prison)) + nearby_mirror.visible_message(span_revenwarning("A dismal moan echoes as particles of [src] fall onto [nearby_mirror]!")) + log_game("A revenant was trapped inside [nearby_mirror]") + message_admins("A revenant was trapped inside [nearby_mirror] [ADMIN_JMP(nearby_mirror)]") + /obj/item/ectoplasm/revenant/examine(mob/user) . = ..() if(inert) . += span_revennotice("It seems inert.") - else if(reforming) + else . += span_revenwarning("It is shifting and distorted. It would be wise to destroy this.") /obj/item/ectoplasm/revenant/suicide_act(mob/living/user) @@ -52,45 +68,13 @@ qdel(src) return OXYLOSS -/obj/item/ectoplasm/revenant/proc/try_reform() - if(reforming) - reforming = FALSE - reform() - else - inert = TRUE - visible_message(span_warning("[src] settles down and seems lifeless.")) - /// Actually moves the revenant out of ourself /obj/item/ectoplasm/revenant/proc/reform() - if(QDELETED(src) || QDELETED(revenant) || inert) + if(QDELETED(src) || inert) + return + if(!GetComponent(/datum/component/revenant_prison)) return - message_admins("Revenant ectoplasm was left undestroyed for 1 minute and is reforming into a new revenant.") - forceMove(drop_location()) //In case it's in a backpack or someone's hand - - var/user_name = old_ckey - if(isnull(revenant.client)) - var/mob/potential_user = get_new_user() - revenant.PossessByPlayer(potential_user.key) - user_name = potential_user.ckey - qdel(potential_user) - - message_admins("[user_name] has been [old_ckey == user_name ? "re":""]made into a revenant by reforming ectoplasm.") - revenant.log_message("was [old_ckey == user_name ? "re":""]made as a revenant by reforming ectoplasm.", LOG_GAME) + SEND_SIGNAL(src, COMSIG_REVENANT_RELEASE, cause = "ectoplasm reforming") visible_message(span_revenboldnotice("[src] suddenly rises into the air before fading away.")) - - revenant.death_reset() - revenant = null qdel(src) - -/// Handles giving the revenant a new client to control it -/obj/item/ectoplasm/revenant/proc/get_new_user() - message_admins("The new revenant's old client either could not be found or is in a new, living mob - grabbing a random candidate instead...") - var/mob/chosen_one = SSpolling.poll_ghosts_for_target("Do you want to be [span_notice(revenant.name)] (reforming)?", check_jobban = ROLE_REVENANT, role = ROLE_REVENANT, poll_time = 5 SECONDS, checked_target = revenant, alert_pic = revenant, role_name_text = "reforming revenant", chat_text_border_icon = revenant) - if(isnull(chosen_one)) - message_admins("No candidates were found for the new revenant.") - inert = TRUE - visible_message(span_revenwarning("[src] settles down and seems lifeless.")) - qdel(revenant) - return null - return chosen_one 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 d2fbdaf44ff..10db1405eea 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 @@ -565,7 +565,6 @@ unsuitable_cold_damage = 1 unsuitable_heat_damage = 1 menu_description = "Stronger assassin spider variant with an unmatched speed, high amount of health and very deadly poison, but deals very low amount of damage. It also has ability to ventcrawl." - apply_spider_antag = FALSE innate_actions = list( /datum/action/cooldown/mob_cooldown/lay_web/sticky_web, /datum/action/cooldown/mob_cooldown/lay_web/web_spikes, @@ -591,7 +590,6 @@ melee_damage_lower = 15 melee_damage_upper = 20 ai_controller = /datum/ai_controller/basic_controller/giant_spider/retaliate - apply_spider_antag = FALSE /mob/living/basic/spider/giant/sgt_araneus/Initialize(mapload) . = ..() 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 1399e5e1b0a..ce246e1e0e3 100644 --- a/code/modules/mob/living/basic/space_fauna/spider/spider.dm +++ b/code/modules/mob/living/basic/space_fauna/spider/spider.dm @@ -51,8 +51,6 @@ var/directive = "" /// Short description of what this mob is capable of, for radial menu uses var/menu_description = "Tanky and strong for the defense of the nest and other spiders." - /// 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 /// Commands you can give this spider once it is tamed var/static/list/tamed_commands = list( /datum/pet_command/idle, @@ -221,7 +219,6 @@ response_harm_continuous = "splats" 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, diff --git a/code/modules/mob/living/basic/space_fauna/supermatter_spider.dm b/code/modules/mob/living/basic/space_fauna/supermatter_spider.dm index 02f11dc9426..44d7585faff 100644 --- a/code/modules/mob/living/basic/space_fauna/supermatter_spider.dm +++ b/code/modules/mob/living/basic/space_fauna/supermatter_spider.dm @@ -49,8 +49,8 @@ /// Proc that we call on attacking something to dust 'em. /mob/living/basic/supermatter_spider/early_melee_attack(atom/target, list/modifiers, ignore_cooldown) . = ..() - if(!.) - return FALSE + if(.) + return if(isliving(target)) var/mob/living/victim = target @@ -59,14 +59,14 @@ victim.dust() if(single_use) death() - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN if(!isturf(target)) dust_feedback(target) qdel(target) if(single_use) death() - return FALSE + return BASIC_MOB_END_ATTACK_CHAIN_COOLDOWN /// Simple proc that plays the supermatter dusting sound and sends a visible message. /mob/living/basic/supermatter_spider/proc/dust_feedback(atom/target) diff --git a/code/modules/mob/living/basic/tree.dm b/code/modules/mob/living/basic/tree.dm index bae229fddd8..5d370cf7cfb 100644 --- a/code/modules/mob/living/basic/tree.dm +++ b/code/modules/mob/living/basic/tree.dm @@ -68,11 +68,11 @@ var/turf/open/our_turf = src.loc if(!our_turf.air || !our_turf.air.gases[/datum/gas/carbon_dioxide]) return - - var/co2 = our_turf.air.gases[/datum/gas/carbon_dioxide][MOLES] + var/datum/gas_mixture/our_air = our_turf.air + var/co2 = our_air.gases[/datum/gas/carbon_dioxide][MOLES] if(co2 > 0 && SPT_PROB(13, seconds_per_tick)) var/amt = min(co2, 9) - our_turf.air.gases[/datum/gas/carbon_dioxide][MOLES] -= amt + our_air.adjust_gas(/datum/gas/carbon_dioxide, -amt) our_turf.atmos_spawn_air("[GAS_O2]=[amt]") /mob/living/basic/tree/melee_attack(atom/target, list/modifiers, ignore_cooldown = FALSE) diff --git a/code/modules/mob/living/basic/trooper/nanotrasen.dm b/code/modules/mob/living/basic/trooper/nanotrasen.dm index 80f0f348624..8798467969b 100644 --- a/code/modules/mob/living/basic/trooper/nanotrasen.dm +++ b/code/modules/mob/living/basic/trooper/nanotrasen.dm @@ -98,4 +98,4 @@ if (!istype(attacker)) return for (var/mob/living/basic/trooper/nanotrasen/potential_trooper in oview(src, 7)) - potential_trooper.ai_controller.insert_blackboard_key_lazylist(BB_BASIC_MOB_RETALIATE_LIST, attacker) + potential_trooper.ai_controller.set_blackboard_key_assoc_lazylist(BB_BASIC_MOB_RETALIATE_LIST, attacker, world.time) diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm index c00d90dd056..ce2de93ca43 100644 --- a/code/modules/mob/living/blood.dm +++ b/code/modules/mob/living/blood.dm @@ -91,7 +91,6 @@ /// Updates effects that rely on blood volume or status, like blood HUDs. /mob/living/proc/update_blood_effects() - living_flags &= ~BLOOD_UPDATE_QUEUED blood_hud_set_status() /// Updates effects that rely on whether the mob can have blood. @@ -161,16 +160,16 @@ if((sigreturn & HANDLE_BLOOD_HANDLED) || !CAN_HAVE_BLOOD(src)) return + var/heart_blood_multiplier = get_heart_blood_regeneration_multiplier() //Blood regeneration if there is some space - if(!(sigreturn & HANDLE_BLOOD_NO_NUTRITION_DRAIN) && get_blood_volume() < BLOOD_VOLUME_NORMAL && !HAS_TRAIT(src, TRAIT_NOHUNGER)) + if(heart_blood_multiplier && !(sigreturn & HANDLE_BLOOD_NO_NUTRITION_DRAIN) && get_blood_volume() < BLOOD_VOLUME_NORMAL && !HAS_TRAIT(src, TRAIT_NOHUNGER)) var/nutrition_ratio = round(nutrition / NUTRITION_LEVEL_WELL_FED, 0.2) if(satiety > 80) nutrition_ratio *= 1.25 - var/blood_to_restore = BLOOD_REGEN_FACTOR * physiology.blood_regen_mod * nutrition_ratio * seconds_per_tick + var/blood_to_restore = BLOOD_REGEN_FACTOR * physiology.blood_regen_mod * heart_blood_multiplier * nutrition_ratio * seconds_per_tick var/blood_restored = adjust_blood_volume(blood_to_restore, maximum = BLOOD_VOLUME_NORMAL) - if (blood_restored > 0) adjust_nutrition(-nutrition_ratio * HUNGER_FACTOR * seconds_per_tick * (blood_restored / blood_to_restore)) @@ -192,7 +191,7 @@ var/modified_blood_volume = get_blood_volume(apply_modifiers = TRUE) // Some effects are halved mid-combat. - var/determined_mod = has_status_effect(/datum/status_effect/determined) ? 0.5 : 0 + var/determined_mod = has_status_effect(/datum/status_effect/determined) ? 0.5 : 1 var/word = pick("dizzy","woozy","faint") switch(modified_blood_volume) diff --git a/code/modules/mob/living/blood_types.dm b/code/modules/mob/living/blood_types.dm index dc6b7abd961..8e9e20f4b97 100644 --- a/code/modules/mob/living/blood_types.dm +++ b/code/modules/mob/living/blood_types.dm @@ -359,7 +359,7 @@ dna_string = "Plant DNA" color = /datum/reagent/water::color reagent_type = /datum/reagent/water - restoration_chem = null + restoration_chem = /datum/reagent/plantnutriment/eznutriment blood_flags = BLOOD_ADD_DNA | BLOOD_TRANSFER_VIRAL_DATA // Prevents awkward grey wounds on the mob while keeping bleed overlays looking like water leaking from a balloon diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index 1910b7f6bad..eb10703000a 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -130,9 +130,8 @@ if((!QDELETED(src) || !QDELETED(owner)) && !(movement_flags & NO_ID_TRANSFER)) transfer_identity(organ_owner) if(!special) - if(!(organ_owner.living_flags & STOP_OVERLAY_UPDATE_BODY_PARTS)) - organ_owner.update_body_parts() organ_owner.clear_mood_event("brain_damage") + organ_owner.med_hud_set_status() /obj/item/organ/brain/update_icon_state() icon_state = "[initial(icon_state)][smooth_brain ? "-smooth" : ""]" @@ -242,8 +241,6 @@ . += span_notice("It is a bit on the smaller side...") if(brain_size > 1) . += span_notice("It is bigger than average...") - if(GetComponent(/datum/component/ghostrole_on_revive)) - . += span_notice("Its soul might yet come back...") /// Needed so subtypes can override examine text while still calling parent /obj/item/organ/brain/proc/brain_damage_examine() @@ -349,9 +346,21 @@ owner.investigate_log("has been killed by brain damage.", INVESTIGATE_DEATHS) owner.death() +/obj/item/organ/brain/on_bodypart_insert(obj/item/bodypart/limb) + . = ..() + if(ishuman(limb.owner)) + limb.owner.update_hair() + else + limb.update_icon_dropped() + /obj/item/organ/brain/on_bodypart_remove(obj/item/bodypart/limb, movement_flags) . = ..() - update_brain_color(animate = FALSE) // once it's out in the world we need to make sure it's the right color + if(ishuman(limb.owner)) + limb.owner.update_hair() + else + limb.update_icon_dropped() + // once it's out in the world we need to make sure it's the right color + update_brain_color(animate = FALSE) /obj/item/organ/brain/apply_organ_damage(damage_amount, maximum = maxHealth, required_organ_flag = NONE) . = ..() diff --git a/code/modules/mob/living/carbon/alien/adult/adult_update_icons.dm b/code/modules/mob/living/carbon/alien/adult/adult_update_icons.dm index c4531313769..e85dc79f20c 100644 --- a/code/modules/mob/living/carbon/alien/adult/adult_update_icons.dm +++ b/code/modules/mob/living/carbon/alien/adult/adult_update_icons.dm @@ -77,7 +77,6 @@ . = ..() remove_overlay(HANDS_LAYER) var/list/hands = list() - var/obj/item/l_hand = get_item_for_held_index(1) if(l_hand) var/itm_state = l_hand.inhand_icon_state diff --git a/code/modules/mob/living/carbon/alien/adult/queen.dm b/code/modules/mob/living/carbon/alien/adult/queen.dm index b388bba684d..339ae0ac6ed 100644 --- a/code/modules/mob/living/carbon/alien/adult/queen.dm +++ b/code/modules/mob/living/carbon/alien/adult/queen.dm @@ -83,7 +83,7 @@ /datum/action/cooldown/alien/promote, ) grant_actions_by_list(innate_actions) - + add_movespeed_mod_immunities(type, /datum/movespeed_modifier/tail_dragger) return ..() /mob/living/carbon/alien/adult/royal/queen/set_name() diff --git a/code/modules/mob/living/carbon/alien/organs.dm b/code/modules/mob/living/carbon/alien/organs.dm index ebbacdf2c02..92b6b6c0baf 100644 --- a/code/modules/mob/living/carbon/alien/organs.dm +++ b/code/modules/mob/living/carbon/alien/organs.dm @@ -85,7 +85,6 @@ /obj/item/organ/alien/plasmavessel/on_mob_insert(mob/living/carbon/organ_owner) . = ..() - RegisterSignal(organ_owner, COMSIG_MOB_GET_STATUS_TAB_ITEMS, PROC_REF(get_status_tab_item)) RegisterSignal(organ_owner, COMSIG_MOB_HUD_CREATED, PROC_REF(on_hud_created)) if (organ_owner.hud_used) on_hud_created() @@ -93,13 +92,8 @@ /obj/item/organ/alien/plasmavessel/on_mob_remove(mob/living/carbon/organ_owner) . = ..() UnregisterSignal(organ_owner, COMSIG_MOB_GET_STATUS_TAB_ITEMS) - UnregisterSignal(organ_owner, COMSIG_MOB_HUD_CREATED) organ_owner.hud_used?.remove_screen_object(HUD_ALIEN_PLASMA_DISPLAY) -/obj/item/organ/alien/plasmavessel/proc/get_status_tab_item(mob/living/carbon/source, list/items) - SIGNAL_HANDLER - items += "Plasma Stored: [stored_plasma]/[max_plasma]" - /obj/item/organ/alien/plasmavessel/proc/update_plasma_display() owner.hud_used?.screen_objects[HUD_ALIEN_PLASMA_DISPLAY]?.maptext = MAPTEXT( \ "
    [round(owner.getPlasma())]
    " \ diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 9ecd4c31da4..9affc03edb9 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -195,14 +195,15 @@ * @param {number} breakouttime - The time it takes to break the cuffs. Use SECONDS/MINUTES defines * @param {number} cuff_break - Speed multiplier, 0 is default, see _DEFINES\combat.dm */ -/mob/living/carbon/proc/cuff_resist(obj/item/cuffs, breakouttime = 1 MINUTES, cuff_break = 0) +/mob/living/carbon/proc/cuff_resist(obj/item/cuffs, breakouttime = null, cuff_break = 0) if((cuff_break != INSTANT_CUFFBREAK) && (SEND_SIGNAL(src, COMSIG_MOB_REMOVING_CUFFS, cuffs) & COMSIG_MOB_BLOCK_CUFF_REMOVAL)) return //The blocking object should sent a fluff-appropriate to_chat about cuff removal being blocked if(cuffs.item_flags & BEING_REMOVED) to_chat(src, span_warning("You're already attempting to remove [cuffs]!")) return cuffs.item_flags |= BEING_REMOVED - breakouttime = cuffs.breakouttime + if (isnull(breakouttime)) + breakouttime = cuffs.breakouttime if(!cuff_break) visible_message(span_warning("[src] attempts to remove [cuffs]!")) to_chat(src, span_notice("You attempt to remove [cuffs]... (This will take around [DisplayTimeText(breakouttime)] and you need to stand still.)")) @@ -719,7 +720,6 @@ clear_mood_event("handcuffed") update_mob_action_buttons() //some of our action buttons might be unusable when we're handcuffed. update_worn_handcuffs() - update_hud_handcuffed() /mob/living/carbon/revive(full_heal_flags = NONE, excess_healing = 0, force_grab_ghost = FALSE) if(excess_healing) @@ -957,6 +957,7 @@ var/obj/item/bodypart/stump = new old_bodypart.stump_typepath() stump.bodyshape = old_bodypart.bodyshape stump.bodytype = old_bodypart.bodytype + stump.add_biostate(old_bodypart.biological_state & ~BIO_JOINTED) if(!stump.try_attach_limb(src, special = TRUE)) // the only way this can happen is if the stump is rejected via signal // not much we can do about that besides hope they know what they're doing diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index a9625c82c19..1c368914e07 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -696,6 +696,9 @@ if (HAS_TRAIT(src, TRAIT_GENELESS)) return FALSE + if(flags_1 & HOLOGRAM_1) + return FALSE + if (run_armor_check(attack_flag = BIO, silent = TRUE) >= 100) to_chat(src, span_warning("Your armor shields you from [scramble_source]!")) return FALSE @@ -706,7 +709,7 @@ var/changed_something = FALSE var/obj/item/organ/new_organ = pick(GLOB.bioscrambler_valid_organs) var/obj/item/organ/replaced = get_organ_slot(initial(new_organ.slot)) - if (!replaced || !IS_ROBOTIC_ORGAN(replaced)) + if (!replaced || ORGAN_CAN_BE_BIOSCRAMBLED(replaced)) changed_something = TRUE new_organ = new new_organ() new_organ.replace_into(src) @@ -715,7 +718,7 @@ if (!HAS_TRAIT(src, TRAIT_NODISMEMBER)) var/obj/item/bodypart/new_part = pick(GLOB.bioscrambler_valid_parts) var/obj/item/bodypart/picked_user_part = get_bodypart(initial(new_part.body_zone)) - if (picked_user_part && BODYTYPE_CAN_BE_BIOSCRAMBLED(picked_user_part.bodytype)) + if (picked_user_part && BODYPART_CAN_BE_BIOSCRAMBLED(picked_user_part)) changed_something = TRUE new_part = new new_part() new_part.replace_limb(src) @@ -733,7 +736,7 @@ /mob/living/carbon/proc/init_bioscrambler_lists() var/list/body_parts = typesof(/obj/item/bodypart/chest) + typesof(/obj/item/bodypart/head) + subtypesof(/obj/item/bodypart/arm) + subtypesof(/obj/item/bodypart/leg) for(var/obj/item/bodypart/part as anything in body_parts) - if(!is_type_in_typecache(part, GLOB.bioscrambler_parts_blacklist) && BODYTYPE_CAN_BE_BIOSCRAMBLED(initial(part.bodytype))) + if(!is_type_in_typecache(part, GLOB.bioscrambler_parts_blacklist) && BODYPART_CAN_BE_BIOSCRAMBLED(part)) continue body_parts -= part GLOB.bioscrambler_valid_parts = body_parts diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index bdfea9edb5f..2150a21702f 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -133,3 +133,6 @@ var/covered_slots = NONE var/next_smell = 0 //SKYRAT EDIT ADDITION /// Cooldown for the next smell + + /// Lazylist of all hair masks applied to this mob's hairstyles + var/list/hair_masks diff --git a/code/modules/mob/living/carbon/carbon_update_icons.dm b/code/modules/mob/living/carbon/carbon_update_icons.dm index 83833dadf41..a037c366cff 100644 --- a/code/modules/mob/living/carbon/carbon_update_icons.dm +++ b/code/modules/mob/living/carbon/carbon_update_icons.dm @@ -336,33 +336,23 @@ /* /mob/living/carbon/update_worn_mask() remove_overlay(FACEMASK_LAYER) + hud_used?.update_inventory_slot(ITEM_SLOT_MASK) if(!get_bodypart(BODY_ZONE_HEAD)) //Decapitated return - if(client && hud_used?.inv_slots[TOBITSHIFT(ITEM_SLOT_MASK) + 1]) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_MASK) + 1] - inv.update_appearance() - - if(wear_mask) - if(!(obscured_slots & HIDEMASK)) - overlays_standing[FACEMASK_LAYER] = wear_mask.build_worn_icon(default_layer = FACEMASK_LAYER, default_icon_file = 'icons/mob/clothing/mask.dmi') - update_hud_wear_mask(wear_mask) + if(wear_mask && !(obscured_slots & HIDEMASK)) + overlays_standing[FACEMASK_LAYER] = wear_mask.build_worn_icon(default_layer = FACEMASK_LAYER, default_icon_file = 'icons/mob/clothing/mask.dmi') + overlays_standing[FACEMASK_LAYER] = wear_mask.build_worn_icon(default_layer = FACEMASK_LAYER, default_icon_file = 'icons/mob/clothing/mask.dmi') apply_overlay(FACEMASK_LAYER) /mob/living/carbon/update_worn_neck() remove_overlay(NECK_LAYER) + hud_used?.update_inventory_slot(ITEM_SLOT_NECK) - if(client && hud_used?.inv_slots[TOBITSHIFT(ITEM_SLOT_NECK) + 1]) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_NECK) + 1] - inv.update_appearance() - - if(wear_neck) - if(!(obscured_slots & HIDENECK)) - overlays_standing[NECK_LAYER] = wear_neck.build_worn_icon(default_layer = NECK_LAYER, default_icon_file = 'icons/mob/clothing/neck.dmi') - update_hud_neck(wear_neck) - + if(wear_neck && !(obscured_slots & HIDENECK)) + overlays_standing[NECK_LAYER] = wear_neck.build_worn_icon(default_layer = NECK_LAYER, default_icon_file = 'icons/mob/clothing/neck.dmi') apply_overlay(NECK_LAYER) */ //SKYRAT EDIT REMOVAL END @@ -371,14 +361,10 @@ /* /mob/living/carbon/update_worn_back() remove_overlay(BACK_LAYER) - - if(client && hud_used?.inv_slots[TOBITSHIFT(ITEM_SLOT_BACK) + 1]) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_BACK) + 1] - inv.update_appearance() + hud_used?.update_inventory_slot(ITEM_SLOT_BACK) if(back) - overlays_standing[BACK_LAYER] = back.build_worn_icon(default_layer = BACK_LAYER, default_icon_file = 'icons/mob/clothing/back.dmi') - update_hud_back(back) + overlays_standing[BACK_LAYER] = back.build_worn_icon(default_layer = BACK_LAYER, default_icon_file = 'icons/mob/clothing/back.dmi', bodyshape = bodyshape) apply_overlay(BACK_LAYER) */ @@ -387,28 +373,26 @@ /mob/living/carbon/update_worn_legcuffs() remove_overlay(LEGCUFF_LAYER) clear_alert("legcuffed") - if(legcuffed) - overlays_standing[LEGCUFF_LAYER] = mutable_appearance('icons/mob/simple/mob.dmi', "legcuff1", -LEGCUFF_LAYER) - apply_overlay(LEGCUFF_LAYER) - throw_alert("legcuffed", /atom/movable/screen/alert/restrained/legcuffed, new_master = src.legcuffed) + if(!legcuffed) + return + if(astype(legcuffed, /obj/item/restraints/legcuffs)?.legcuff_state) + var/obj/item/restraints/legcuffs/cuffs = legcuffed + overlays_standing[LEGCUFF_LAYER] = mutable_appearance('icons/mob/simple/mob.dmi', cuffs.legcuff_state, -LEGCUFF_LAYER) + apply_overlay(LEGCUFF_LAYER) + throw_alert("legcuffed", /atom/movable/screen/alert/restrained/legcuffed, new_master = src.legcuffed) //SKYRAT EDIT REMOVAL BEGIN - CUSTOMIZATION (moved to modular) /* /mob/living/carbon/update_worn_head() remove_overlay(HEAD_LAYER) + hud_used?.update_inventory_slot(ITEM_SLOT_HEAD) if(!get_bodypart(BODY_ZONE_HEAD)) //Decapitated return - if(client && hud_used?.inv_slots[TOBITSHIFT(ITEM_SLOT_HEAD) + 1]) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_HEAD) + 1] - inv.update_appearance() - - if(head) - if(!(obscured_slots & HIDEHEADGEAR)) - overlays_standing[HEAD_LAYER] = head.build_worn_icon(default_layer = HEAD_LAYER, default_icon_file = 'icons/mob/clothing/head/default.dmi') - update_hud_head(head) + if(head && !(obscured_slots & HIDEHEADGEAR)) + overlays_standing[HEAD_LAYER] = head.build_worn_icon(default_layer = HEAD_LAYER, default_icon_file = 'icons/mob/clothing/head/default.dmi') apply_overlay(HEAD_LAYER) */ @@ -417,7 +401,8 @@ /mob/living/carbon/update_worn_handcuffs() remove_overlay(HANDCUFF_LAYER) - if(handcuffed && !(handcuffed.item_flags & ABSTRACT)) //SKYRAT EDIT - ADDED !(handcuffed.item_flags & ABSTRACT) + hud_used?.update_inventory_slot(ITEM_SLOT_HANDS) + if(handcuffed) var/mutable_appearance/handcuff_overlay = mutable_appearance('icons/mob/simple/mob.dmi', "handcuff1", -HANDCUFF_LAYER) if(handcuffed.blocks_emissive != EMISSIVE_BLOCK_NONE) handcuff_overlay.overlays += emissive_blocker(handcuff_overlay.icon, handcuff_overlay.icon_state, src, alpha = handcuff_overlay.alpha) @@ -425,33 +410,8 @@ overlays_standing[HANDCUFF_LAYER] = handcuff_overlay apply_overlay(HANDCUFF_LAYER) - //mob HUD updates for items in our inventory -//update whether handcuffs appears on our hud. -/mob/living/carbon/proc/update_hud_handcuffed() - if(!hud_used) - return - - for(var/atom/movable/screen/inventory/hand/hand in hud_used.hand_slots) - hand.update_appearance() - -//update whether our head item appears on our hud. -/mob/living/carbon/proc/update_hud_head(obj/item/I) - return - -//update whether our mask item appears on our hud. -/mob/living/carbon/proc/update_hud_wear_mask(obj/item/I) - return - -//update whether our neck item appears on our hud. -/mob/living/carbon/proc/update_hud_neck(obj/item/I) - return - -//update whether our back item appears on our hud. -/mob/living/carbon/proc/update_hud_back(obj/item/I) - return - /// Overlays for the worn overlay so you can overlay while you overlay /// eg: ammo counters, primed grenade flashing, etc. /// "icon_file" is used automatically for inhands etc. to make sure it gets the right inhand file @@ -480,10 +440,13 @@ update_damage_overlays() update_wound_overlays() var/limb_count_update = 0 + var/head_update = FALSE var/list/new_limbs = list() for(var/body_zone, limb_untyped in get_bodyparts_by_zones()) var/obj/item/bodypart/limb = limb_untyped if(isnull(limb) || IS_STUMP(limb)) + if(body_zone == BODY_ZONE_HEAD) + head_update = TRUE if(icon_render_keys[body_zone]) icon_render_keys -= body_zone limb_count_update += 1 @@ -499,6 +462,8 @@ new_limbs += limb_icon_cache[new_key] else + if(body_zone == BODY_ZONE_HEAD) + head_update = TRUE limb_icon_cache[new_key] ||= limb.get_limb_icon(dropped = FALSE) new_limbs += limb_icon_cache[new_key] icon_render_keys[limb.body_zone] = new_key @@ -514,6 +479,10 @@ overlays_standing[BODYPARTS_LAYER] = new_limbs apply_overlay(BODYPARTS_LAYER) + // for legacy support, head changes triggers an eye/hair update + if(head_update) + update_eyes() + update_hair() /mob/living/carbon/proc/update_face_offset() return @@ -552,13 +521,19 @@ for(var/datum/bodypart_overlay/overlay as anything in bodypart_overlays) if(!overlay.can_draw_on_bodypart(src, owner, is_husked)) continue - . += overlay.generate_icon_cache() + . += overlay.generate_icon_cache(src) if(ishuman(owner)) var/mob/living/carbon/human/human_owner = owner . += "[human_owner.mob_height]" SEND_SIGNAL(src, COMSIG_BODYPART_GENERATE_ICON_KEY, .) return . +/obj/item/bodypart/head/generate_icon_key() + . = ..() + if(lip_style) + . += lip_color + . += lip_style + ///Generates a cache key specifically for husks /obj/item/bodypart/proc/generate_husk_key() RETURN_TYPE(/list) @@ -575,50 +550,12 @@ for(var/datum/bodypart_overlay/overlay as anything in bodypart_overlays) if(!overlay.can_draw_on_bodypart(src, owner, TRUE)) continue - . += overlay.generate_icon_cache() + . += overlay.generate_icon_cache(src) if(ishuman(owner)) var/mob/living/carbon/human/human_owner = owner . += "[human_owner.mob_height]" return . -/obj/item/bodypart/head/generate_icon_key() - . = ..() - if(lip_style) - . += "-[lip_style]" - . += "-[lip_color]" - - if(facial_hair_hidden) - . += "-FACIAL_HAIR_HIDDEN" - else - . += "-[facial_hairstyle]" - . += "-[override_hair_color || fixed_hair_color || facial_hair_color]" - . += "-[facial_hair_alpha]" - var/facial_hair_gradient_style = get_hair_gradient_style(GRADIENT_FACIAL_HAIR_KEY) - if(facial_hair_gradient_style) - . += "-[facial_hair_gradient_style]" - . += "-[get_hair_gradient_color(GRADIENT_FACIAL_HAIR_KEY)]" - - if(show_eyeless) - . += "-SHOW_EYELESS" - if(show_debrained) - . += "-SHOW_DEBRAINED" - return . - - if(hair_hidden) - . += "-HAIR_HIDDEN" - else - . += "-[hairstyle]" - . += "-[override_hair_color || fixed_hair_color || hair_color]" - . += "-[hair_alpha]" - var/hair_gradient_style = get_hair_gradient_style(GRADIENT_HAIR_KEY) - if(hair_gradient_style) - . += "-[hair_gradient_style]" - . += "-[get_hair_gradient_color(GRADIENT_HAIR_KEY)]" - if(LAZYLEN(hair_masks)) - . += "-[jointext(hair_masks, "-")]" - - return . - GLOBAL_LIST_EMPTY(masked_leg_icons_cache) /** diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm index a9e7df05ed1..76fd95fb330 100644 --- a/code/modules/mob/living/carbon/examine.dm +++ b/code/modules/mob/living/carbon/examine.dm @@ -369,7 +369,7 @@ //This checks to see if the body is revivable var/obj/item/organ/brain = get_organ_by_type(/obj/item/organ/brain) if((brain && HAS_TRAIT(brain, TRAIT_GHOSTROLE_ON_REVIVE)) || HAS_TRAIT(src, TRAIT_GHOSTROLE_ON_REVIVE)) - return span_deadsay("[t_He] [t_is] limp and unresponsive; but [t_his] soul might yet come back...") + return span_deadsay("[t_He] [t_is] limp and unresponsive; there are no signs of life, but another soul may take [t_his] place...") var/client_like = client || HAS_TRAIT(src, TRAIT_MIND_TEMPORARILY_GONE) var/valid_ghost = ghost?.can_reenter_corpse && ghost?.client var/valid_soul = brain || !HAS_TRAIT(src, TRAIT_FAKE_SOULLESS) diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm index b87c1df02a9..d255df4eae8 100644 --- a/code/modules/mob/living/carbon/human/_species.dm +++ b/code/modules/mob/living/carbon/human/_species.dm @@ -563,11 +563,6 @@ GLOBAL_LIST_EMPTY(features_by_species) return new_features -/datum/species/proc/spec_life(mob/living/carbon/human/H, seconds_per_tick) - SHOULD_CALL_PARENT(TRUE) - if(HAS_TRAIT(H, TRAIT_NOBREATH) && (H.health < H.crit_threshold) && !HAS_TRAIT(H, TRAIT_NOCRITDAMAGE)) - H.adjust_brute_loss(0.5 * seconds_per_tick) - /datum/species/proc/can_equip(obj/item/I, slot, disable_warning, mob/living/carbon/human/H, bypass_equip_delay_self = FALSE, ignore_equipped = FALSE, indirect_action = FALSE) if(no_equip_flags & slot && !(I.is_mod_shell_component() && (modsuit_slot_exceptions & slot))) // SKYRAT EDIT ADDITION - ORIGINAL: if(no_equip_flags & slot) if(!I.species_exception || !is_type_in_list(src, I.species_exception)) @@ -616,6 +611,7 @@ GLOBAL_LIST_EMPTY(features_by_species) return FALSE /* SKYRAT EDIT REMOVAL if((H.bodyshape & BODYSHAPE_DIGITIGRADE) && !(I.item_flags & IGNORE_DIGITIGRADE)) + if((H.bodytype & BODYTYPE_DIGITIGRADE) && !(I.item_flags & IGNORE_DIGITIGRADE)) if(!(I.supports_variations_flags & DIGITIGRADE_VARIATIONS)) if(!disable_warning) to_chat(H, span_warning("The footwear around here isn't compatible with your feet!")) diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 9242a157bef..6b543bca434 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -40,6 +40,8 @@ GLOBAL_LIST_EMPTY(dead_players_during_shift) Reagents:
    [reagents_readout()]", INVESTIGATE_DEATHS) to_chat(src, span_warning("You have died. Barring complete bodyloss, you can in most cases be revived by other players. \ If you do not wish to be brought back, use the \"Do Not Resuscitate\" button at the bottom of your screen.")) + if(SSlag_switch.measures[DISABLE_DEAD_KEYLOOP] && !client?.holder) + to_chat(src, span_warning("Ghost movement is currently disabled by admins. To leave your body use the Ghost verb.")) /mob/living/carbon/human/proc/reagents_readout() var/readout = "[get_bloodtype()?.get_blood_name() || "Blood"]stream:" diff --git a/code/modules/mob/living/carbon/human/dummy.dm b/code/modules/mob/living/carbon/human/dummy.dm index c183c08a95f..190c8f8f0f4 100644 --- a/code/modules/mob/living/carbon/human/dummy.dm +++ b/code/modules/mob/living/carbon/human/dummy.dm @@ -76,8 +76,12 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy) item.item_flags |= IN_INVENTORY if(!item.visual_equipped(src, slot, initial)) return FALSE - + if(!(slot & item.slot_flags)) // Things below only update if slotted in (ie: not held) + return TRUE add_item_coverage(item) + if(item.hair_mask) + LAZYADD(hair_masks, item.hair_mask) + update_hair() return TRUE /mob/living/carbon/human/dummy/proc/wipe_state() diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 4ef0dd1ffe1..6045b5c160c 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -751,7 +751,7 @@ if(heal_flags & HEAL_NEGATIVE_MUTATIONS) for(var/datum/mutation/existing_mutation in dna.mutations) if(existing_mutation.quality != POSITIVE && existing_mutation.remove_on_aheal) - dna.remove_mutation(existing_mutation, list(MUTATION_SOURCE_ACTIVATED, MUTATION_SOURCE_MUTATOR, MUTATION_SOURCE_TIMED_INJECTOR)) + dna.remove_mutation(existing_mutation, GLOB.standard_mutation_sources) if(heal_flags & HEAL_TEMP) set_coretemperature(get_body_temp_normal(apply_change = FALSE)) @@ -1067,12 +1067,12 @@ /mob/living/carbon/human/proc/add_eye_color_left(color, color_priority, update_body = TRUE) LAZYSET(eye_color_left_overrides, "[color_priority]", color) if (update_body) - update_body() + update_eyes() /mob/living/carbon/human/proc/add_eye_color_right(color, color_priority, update_body = TRUE) LAZYSET(eye_color_right_overrides, "[color_priority]", color) if (update_body) - update_body() + update_eyes() /mob/living/carbon/human/proc/add_eye_color(color, color_priority, update_body = TRUE) add_eye_color_left(color, color_priority, update_body = FALSE) @@ -1082,9 +1082,12 @@ LAZYREMOVE(eye_color_left_overrides, "[color_priority]") LAZYREMOVE(eye_color_right_overrides, "[color_priority]") if (update_body) - update_body() + update_eyes() -/mob/living/carbon/human/proc/get_right_eye_color() +/mob/living/carbon/proc/get_right_eye_color() + return + +/mob/living/carbon/human/get_right_eye_color() if (!LAZYLEN(eye_color_right_overrides)) return eye_color_right @@ -1097,7 +1100,10 @@ eye_color = eye_color_right_overrides[override_priority] return eye_color -/mob/living/carbon/human/proc/get_left_eye_color() +/mob/living/carbon/proc/get_left_eye_color() + return + +/mob/living/carbon/human/get_left_eye_color() if (!LAZYLEN(eye_color_left_overrides)) return eye_color_left @@ -1196,8 +1202,11 @@ /mob/living/carbon/human/species/lizard/silverscale race = /datum/species/lizard/silverscale +/mob/living/carbon/human/species/spirit + race = /datum/species/spirit + /mob/living/carbon/human/species/ghost - race = /datum/species/ghost + race = /datum/species/spirit/ghost /mob/living/carbon/human/species/ethereal race = /datum/species/ethereal 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 00c460a4253..d7b3010611e 100644 --- a/code/modules/mob/living/carbon/human/human_update_icons.dm +++ b/code/modules/mob/living/carbon/human/human_update_icons.dm @@ -48,42 +48,37 @@ There are several things that need to be remembered: /* --------------------------------------- */ //For legacy support. /mob/living/carbon/human/regenerate_icons() - - if(!..()) - update_worn_undersuit() - update_worn_id() - update_worn_glasses() - update_worn_gloves() - update_worn_ears() - update_worn_shoes() - update_suit_storage() - update_worn_mask() - update_worn_head() - update_worn_belt() - update_worn_back() - update_worn_oversuit() - update_pockets() - update_worn_neck() - update_transform() - //mutations - update_mutations_overlay() - //damage overlays - update_damage_overlays() + . = ..() + update_worn_undersuit() + update_worn_id() + update_worn_glasses() + update_worn_gloves() + update_worn_ears() + update_worn_shoes() + update_suit_storage() + update_worn_mask() + update_worn_head() + update_worn_belt() + update_worn_back() + update_worn_oversuit() + update_pockets() + update_worn_neck() + update_transform() + update_mutations_overlay() + update_damage_overlays() + // These are done via parent call update_body(), keeping them here for clarity + // update_hair() + // update_eyes() /* --------------------------------------- */ //vvvvvv UPDATE_INV PROCS vvvvvv /mob/living/carbon/human/update_worn_undersuit() remove_overlay(UNIFORM_LAYER) - - if(client && hud_used) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_ICLOTHING) + 1] - inv.update_icon() + hud_used?.update_inventory_slot(ITEM_SLOT_ICLOTHING) if(istype(w_uniform, /obj/item/clothing/under)) var/obj/item/clothing/under/uniform = w_uniform - update_hud_uniform(uniform) - if(HAS_TRAIT(uniform, TRAIT_NO_WORN_ICON) || (obscured_slots & HIDEJUMPSUIT)) return @@ -138,10 +133,10 @@ There are several things that need to be remembered: default_layer = UNIFORM_LAYER, default_icon_file = icon_file, isinhands = FALSE, - female_uniform = woman ? female_sprite_flags : null, // SKYRAT EDIT CHANGE - Digi female gender shaping - ORIGINAL: female_uniform = woman ? uniform.female_sprite_flags : null, + female_uniform = woman ? female_sprite_flags : null, // BUBBER EDIT CHANGE - Digi female gender shaping - ORIGINAL: female_uniform = woman ? uniform.female_sprite_flags : null, override_state = target_overlay, override_file = handled_by_bodyshape ? icon_file : null, - mutant_styles = mutant_styles, // SKYRAT EDIT ADDITION - Taur-friendly uniforms! + mutant_styles = mutant_styles, // BUBBER EDIT ADDITION - Taur-friendly uniforms! ) var/obj/item/bodypart/chest/my_chest = get_bodypart(BODY_ZONE_CHEST) @@ -149,20 +144,15 @@ There are several things that need to be remembered: overlays_standing[UNIFORM_LAYER] = uniform_overlay apply_overlay(UNIFORM_LAYER) - check_body_shape(BODYSHAPE_DIGITIGRADE, ITEM_SLOT_ICLOTHING) /mob/living/carbon/human/update_worn_id() remove_overlay(ID_LAYER) - - if(client && hud_used) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_ID) + 1] - inv.update_icon() + hud_used?.update_inventory_slot(ITEM_SLOT_ID) var/mutable_appearance/id_overlay = overlays_standing[ID_LAYER] if(wear_id) var/obj/item/worn_item = wear_id - update_hud_id(worn_item) if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON)) return @@ -183,10 +173,7 @@ There are several things that need to be remembered: /mob/living/carbon/human/update_worn_gloves() remove_overlay(GLOVES_LAYER) - - if(client && hud_used && hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_GLOVES) + 1]) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_GLOVES) + 1] - inv.update_icon() + hud_used?.update_inventory_slot(ITEM_SLOT_GLOVES) //Bloody hands begin if(isnull(gloves)) @@ -208,8 +195,6 @@ There are several things that need to be remembered: // Bloody hands end var/obj/item/worn_item = gloves - update_hud_gloves(worn_item) - if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (obscured_slots & HIDEGLOVES)) return @@ -253,19 +238,14 @@ There are several things that need to be remembered: /mob/living/carbon/human/update_worn_glasses() remove_overlay(GLASSES_LAYER) + hud_used?.update_inventory_slot(ITEM_SLOT_EYES) var/obj/item/bodypart/head/my_head = get_bodypart(BODY_ZONE_HEAD) if(isnull(my_head)) //decapitated return - if(client && hud_used) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_EYES) + 1] - inv.update_icon() - if(glasses) var/obj/item/worn_item = glasses - update_hud_glasses(worn_item) - if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (obscured_slots & HIDEEYES)) return @@ -292,19 +272,14 @@ There are several things that need to be remembered: /mob/living/carbon/human/update_worn_ears() remove_overlay(EARS_LAYER) + hud_used?.update_inventory_slot(ITEM_SLOT_EARS) var/obj/item/bodypart/head/my_head = get_bodypart(BODY_ZONE_HEAD) if(isnull(my_head)) //decapitated return - if(client && hud_used) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_EARS) + 1] - inv.update_icon() - if(ears) var/obj/item/worn_item = ears - update_hud_ears(worn_item) - if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (obscured_slots & HIDEEARS)) return @@ -330,14 +305,10 @@ There are several things that need to be remembered: /mob/living/carbon/human/update_worn_neck() remove_overlay(NECK_LAYER) - - if(client && hud_used && hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_NECK) + 1]) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_NECK) + 1] - inv.update_icon() + hud_used?.update_inventory_slot(ITEM_SLOT_NECK) if(wear_neck) var/obj/item/worn_item = wear_neck - update_hud_neck(wear_neck) if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (obscured_slots & HIDENECK)) return @@ -372,17 +343,13 @@ There are several things that need to be remembered: /mob/living/carbon/human/update_worn_shoes() remove_overlay(SHOES_LAYER) + hud_used?.update_inventory_slot(ITEM_SLOT_FEET) if(num_legs < 2) return - if(client && hud_used) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_FEET) + 1] - inv.update_icon() - if(shoes) var/obj/item/worn_item = shoes - update_hud_shoes(worn_item) if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (obscured_slots & HIDESHOES)) return @@ -424,19 +391,13 @@ There are several things that need to be remembered: overlays_standing[SHOES_LAYER] = shoes_overlay apply_overlay(SHOES_LAYER) - check_body_shape(BODYSHAPE_DIGITIGRADE, ITEM_SLOT_FEET) /mob/living/carbon/human/update_suit_storage() remove_overlay(SUIT_STORE_LAYER) - - if(client && hud_used) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_SUITSTORE) + 1] - inv.update_icon() + hud_used?.update_inventory_slot(ITEM_SLOT_SUITSTORE) if(s_store) var/obj/item/worn_item = s_store - update_hud_s_store(worn_item) - if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (obscured_slots & HIDESUITSTORAGE)) return @@ -448,14 +409,10 @@ There are several things that need to be remembered: /mob/living/carbon/human/update_worn_head() remove_overlay(HEAD_LAYER) - if(client && hud_used && hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_HEAD) + 1]) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_HEAD) + 1] - inv.update_icon() + hud_used?.update_inventory_slot(ITEM_SLOT_HEAD) if(head) var/obj/item/worn_item = head - update_hud_head(worn_item) - if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (obscured_slots & HIDEHEADGEAR)) return @@ -485,19 +442,13 @@ There are several things that need to be remembered: overlays_standing[HEAD_LAYER] = head_overlay apply_overlay(HEAD_LAYER) - check_body_shape(BODYSHAPE_SNOUTED, ITEM_SLOT_HEAD) /mob/living/carbon/human/update_worn_belt() remove_overlay(BELT_LAYER) - - if(client && hud_used) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_BELT) + 1] - inv.update_icon() + hud_used?.update_inventory_slot(ITEM_SLOT_BELT) if(belt) var/obj/item/worn_item = belt - update_hud_belt(worn_item) - if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (obscured_slots & HIDEBELT)) return @@ -525,14 +476,10 @@ There are several things that need to be remembered: /mob/living/carbon/human/update_worn_oversuit() remove_overlay(SUIT_LAYER) - - if(client && hud_used) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_OCLOTHING) + 1] - inv.update_icon() + hud_used?.update_inventory_slot(ITEM_SLOT_OCLOTHING) if(wear_suit) var/obj/item/worn_item = wear_suit - update_hud_wear_suit(worn_item) if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON)) return @@ -571,44 +518,22 @@ There are several things that need to be remembered: overlays_standing[SUIT_LAYER] = suit_overlay apply_overlay(SUIT_LAYER) - check_body_shape(BODYSHAPE_DIGITIGRADE, ITEM_SLOT_OCLOTHING) /mob/living/carbon/human/update_pockets() - if(client && hud_used) - var/atom/movable/screen/inventory/inv - - inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_LPOCKET) + 1] - inv.update_icon() - inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_RPOCKET) + 1] - inv.update_icon() - - if(l_store) - l_store.screen_loc = ui_storage1 - if(hud_used.hud_shown) - client.screen += l_store - update_observer_view(l_store) - - if(r_store) - r_store.screen_loc = ui_storage2 - if(hud_used.hud_shown) - client.screen += r_store - update_observer_view(r_store) + if (hud_used) + hud_used.update_inventory_slot(ITEM_SLOT_LPOCKET) + hud_used.update_inventory_slot(ITEM_SLOT_RPOCKET) /mob/living/carbon/human/update_worn_mask() remove_overlay(FACEMASK_LAYER) + hud_used?.update_inventory_slot(ITEM_SLOT_MASK) var/obj/item/bodypart/head/my_head = get_bodypart(BODY_ZONE_HEAD) if(isnull(my_head)) //Decapitated return - if(client && hud_used && hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_MASK) + 1]) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_MASK) + 1] - inv.update_icon() - if(wear_mask) var/obj/item/worn_item = wear_mask - update_hud_wear_mask(worn_item) - if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (obscured_slots & HIDEMASK)) return @@ -637,19 +562,14 @@ There are several things that need to be remembered: overlays_standing[FACEMASK_LAYER] = mask_overlay apply_overlay(FACEMASK_LAYER) - check_body_shape(BODYSHAPE_SNOUTED, ITEM_SLOT_MASK) /mob/living/carbon/human/update_worn_back() remove_overlay(BACK_LAYER) - - if(client && hud_used && hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_BACK) + 1]) - var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_BACK) + 1] - inv.update_icon() + hud_used?.update_inventory_slot(ITEM_SLOT_BACK) if(back) var/obj/item/worn_item = back var/mutable_appearance/back_overlay - update_hud_back(worn_item) if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON)) return @@ -732,16 +652,17 @@ There are several things that need to be remembered: /obj/effect/abstract/held_tk_effect/left is_right = FALSE // BUBBER EDIT END + /mob/living/carbon/human/get_held_overlays() var/list/hands = list() - // BUBBER EDIT START + // BUBBER EDIT ADDITION START if(held_left) held_left.overlays.Cut() held_left.underlays.Cut() if(held_right) held_right.overlays.Cut() held_right.underlays.Cut() - // BUBBER EDIT END + // BUBBER EDIT ADDITION END for(var/obj/item/worn_item in held_items) var/held_index = get_held_index_of_item(worn_item) if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) @@ -766,7 +687,12 @@ There are several things that need to be remembered: var/icon_file = IS_RIGHT_INDEX(held_index) ? worn_item.righthand_file : worn_item.lefthand_file hand_overlay = worn_item.build_worn_icon(default_layer = HANDS_LAYER, default_icon_file = icon_file, isinhands = TRUE) var/obj/item/bodypart/arm/held_in_hand = hand_bodyparts[held_index] - // BUBBER EDIT START + /* // BUBBER EDIT REMOVAL START - Moved down below psionic holding, after an else block + held_in_hand?.held_hand_offset?.apply_offset(hand_overlay) + + hands += hand_overlay + */ // BUBBER EDIT REMOVAL END + // BUBBER EDIT ADDITION START - Psionic holding if(HAS_TRAIT(src, TRAIT_FLOATING_HELD)) if(!held_left) held_left = new(src) @@ -827,7 +753,7 @@ There are several things that need to be remembered: else held_in_hand?.held_hand_offset?.apply_offset(hand_overlay) hands += hand_overlay - // BUBBER EDIT END + // BUBBER EDIT ADDITION END return hands /// Modifies a sprite slightly to conform to female body shapes @@ -945,90 +871,6 @@ There are several things that need to be remembered: out += overlays_standing[i] return out - -//human HUD updates for items in our inventory - -/mob/living/carbon/human/proc/update_hud_uniform(obj/item/worn_item) - worn_item.screen_loc = ui_iclothing - if((client && hud_used) && (hud_used.inventory_shown && hud_used.hud_shown)) - client.screen += worn_item - update_observer_view(worn_item,TRUE) - -/mob/living/carbon/human/proc/update_hud_id(obj/item/worn_item) - worn_item.screen_loc = ui_id - if((client && hud_used?.hud_shown)) - client.screen += worn_item - update_observer_view(worn_item) - -/mob/living/carbon/human/proc/update_hud_gloves(obj/item/worn_item) - worn_item.screen_loc = ui_gloves - if((client && hud_used) && (hud_used.inventory_shown && hud_used.hud_shown)) - client.screen += worn_item - update_observer_view(worn_item,TRUE) - -/mob/living/carbon/human/proc/update_hud_glasses(obj/item/worn_item) - worn_item.screen_loc = ui_glasses - if((client && hud_used) && (hud_used.inventory_shown && hud_used.hud_shown)) - client.screen += worn_item - update_observer_view(worn_item,TRUE) - -/mob/living/carbon/human/proc/update_hud_ears(obj/item/worn_item) - worn_item.screen_loc = ui_ears - if((client && hud_used) && (hud_used.inventory_shown && hud_used.hud_shown)) - client.screen += worn_item - update_observer_view(worn_item,TRUE) - -/mob/living/carbon/human/proc/update_hud_shoes(obj/item/worn_item) - worn_item.screen_loc = ui_shoes - if((client && hud_used) && (hud_used.inventory_shown && hud_used.hud_shown)) - client.screen += worn_item - update_observer_view(worn_item,TRUE) - -/mob/living/carbon/human/proc/update_hud_s_store(obj/item/worn_item) - worn_item.screen_loc = ui_sstore1 - if(client && hud_used?.hud_shown) - client.screen += worn_item - update_observer_view(worn_item,TRUE) - -/mob/living/carbon/human/proc/update_hud_wear_suit(obj/item/worn_item) - worn_item.screen_loc = ui_oclothing - if((client && hud_used) && (hud_used.inventory_shown && hud_used.hud_shown)) - client.screen += worn_item - update_observer_view(worn_item,TRUE) - -/mob/living/carbon/human/proc/update_hud_belt(obj/item/worn_item) - belt.screen_loc = ui_belt - if(client && hud_used?.hud_shown) - client.screen += worn_item - update_observer_view(worn_item,TRUE) - -/mob/living/carbon/human/update_hud_head(obj/item/worn_item) - worn_item.screen_loc = ui_head - if((client && hud_used) && (hud_used.inventory_shown && hud_used.hud_shown)) - client.screen += worn_item - update_observer_view(worn_item,TRUE) - -//update whether our mask item appears on our hud. -/mob/living/carbon/human/update_hud_wear_mask(obj/item/worn_item) - worn_item.screen_loc = ui_mask - if((client && hud_used) && (hud_used.inventory_shown && hud_used.hud_shown)) - client.screen += worn_item - update_observer_view(worn_item,TRUE) - -//update whether our neck item appears on our hud. -/mob/living/carbon/human/update_hud_neck(obj/item/worn_item) - worn_item.screen_loc = ui_neck - if((client && hud_used) && (hud_used.inventory_shown && hud_used.hud_shown)) - client.screen += worn_item - update_observer_view(worn_item,TRUE) - -//update whether our back item appears on our hud. -/mob/living/carbon/human/update_hud_back(obj/item/worn_item) - worn_item.screen_loc = ui_back - if(client && hud_used?.hud_shown) - client.screen += worn_item - update_observer_view(worn_item, inventory = TRUE) - /* Does everything in relation to building the /mutable_appearance used in the mob's overlays list covers: @@ -1100,7 +942,7 @@ mutant_styles: The mutant style - taur bodytype, STYLE_TESHARI, etc. // SKYRAT E type = female_uniform, greyscale_colors = greyscale_colors, ) - if(!isinhands && is_digi && (supports_variations_flags & CLOTHING_DIGITIGRADE_MASK)) + if(!isinhands && (BODYSHAPE_DIGITIGRADE) && (supports_variations_flags & CLOTHING_DIGITIGRADE_MASK)) building_icon = wear_digi_version( base_icon = building_icon || icon(file2use, t_state), item = src, @@ -1181,73 +1023,78 @@ mutant_styles: The mutant style - taur bodytype, STYLE_TESHARI, etc. // SKYRAT E else //No offsets or Unwritten number of hands return list("x" = 0, "y" = 0)//Handle held offsets -/mob/living/carbon/human/proc/update_observer_view(obj/item/worn_item, inventory) - if(observers?.len) - for(var/M in observers) - var/mob/dead/observe = M - if(observe.client && observe.client.eye == src) - if(observe.hud_used) - if(inventory && !observe.hud_used.inventory_shown) - continue - observe.client.screen += worn_item - else - observers -= observe - if(!observers.len) - observers = null - break - /mob/living/carbon/human/update_body(is_creating = FALSE) - update_eyes() - update_underwear() + remove_overlay(BODY_LAYER) + + var/list/body_overlays = list() + body_overlays += get_underwear_overlays() + + if(length(body_overlays)) + overlays_standing[BODY_LAYER] = body_overlays + apply_overlay(BODY_LAYER) + + // parent call will update the actual bodyparts return ..() -/mob/living/carbon/human/proc/update_underwear() // OVERRIDDEN IN MODULAR_ZUBBERS - remove_overlay(BODY_LAYER) +/// Returns a list of all underclothing overlays to be applied to the mob +/mob/living/carbon/human/proc/get_underwear_overlays() // OVERRIDDEN IN MODULAR_ZUBBERS + . = list() if(HAS_TRAIT(src, TRAIT_HUSK) || HAS_TRAIT(src, TRAIT_INVISIBLE_MAN) || HAS_TRAIT(src, TRAIT_NO_UNDERWEAR)) - return + return . + // Underwear, Undershirts & Socks - var/list/standing = list() - var/active_bodyshapes = get_active_bodyshapes() if(underwear) var/datum/sprite_accessory/clothing/underwear/undie_accessory = SSaccessories.underwear_list[underwear] - var/mutable_appearance/underwear_overlay = undie_accessory?.make_appearance(underwear_color, physique, active_bodyshapes) + var/mutable_appearance/underwear_overlay = undie_accessory?.make_appearance(underwear_color, physique, bodyshape) if(underwear_overlay) - standing += underwear_overlay + . += underwear_overlay if(undershirt) var/datum/sprite_accessory/clothing/undershirt/shirt_accessory = SSaccessories.undershirt_list[undershirt] - var/mutable_appearance/shirt_overlay = shirt_accessory?.make_appearance(null, physique, active_bodyshapes) + var/mutable_appearance/shirt_overlay = shirt_accessory?.make_appearance(null, physique, bodyshape) if(shirt_overlay) - standing += shirt_overlay + . += shirt_overlay if(socks && num_legs >= 2 && !(bodyshape & BODYSHAPE_DIGITIGRADE)) var/datum/sprite_accessory/clothing/socks/sock_accessory = SSaccessories.socks_list[socks] - var/mutable_appearance/socks_overlay = sock_accessory?.make_appearance(null, physique, active_bodyshapes) + var/mutable_appearance/socks_overlay = sock_accessory?.make_appearance(null, physique, bodyshape) if(socks_overlay) - standing += socks_overlay + . += socks_overlay - if(standing.len) - overlays_standing[BODY_LAYER] = standing + return . - apply_overlay(BODY_LAYER) +/// Updates eye sprites if relevant +/mob/living/proc/update_eyes(refresh = TRUE) + return -/mob/living/carbon/human/proc/update_eyes() +/mob/living/carbon/human/update_eyes(refresh = TRUE) remove_overlay(EYES_LAYER) - if(HAS_TRAIT(src, TRAIT_HUSK) || HAS_TRAIT(src, TRAIT_INVISIBLE_MAN)) + + var/obj/item/bodypart/head/noggin = get_bodypart(BODY_ZONE_HEAD) + if(isnull(noggin) || noggin.is_husked || noggin.is_invisible) return - // eyes (missing eye sprites get handled by the head itself, but sadly we have to do this stupid shit here, for now) - var/obj/item/organ/eyes/eye_organ = get_organ_slot(ORGAN_SLOT_EYES) - if (!eye_organ) - return + if(refresh) + var/obj/item/organ/eyes/eyes = locate() in noggin + eyes?.refresh(src, call_update = FALSE) - var/obj/item/bodypart/head/noggin = get_bodypart(deprecise_zone(eye_organ.zone)) // Futureproofing for HARS/weird species - if(istype(noggin) && !(noggin?.head_flags & HEAD_EYESPRITES)) - return + var/list/eye_overlays = noggin.get_eye_overlays() + if(length(eye_overlays)) + overlays_standing[EYES_LAYER] = eye_overlays + apply_overlay(EYES_LAYER) - eye_organ.refresh(call_update = FALSE) - overlays_standing[EYES_LAYER] = eye_organ.generate_body_overlay(src, noggin) - apply_overlay(EYES_LAYER) +/// Updates hair sprites if relevant +/mob/living/proc/update_hair() + return + +/mob/living/carbon/human/update_hair() + remove_overlay(HAIR_LAYER) + + var/obj/item/bodypart/head/head = get_bodypart(BODY_ZONE_HEAD) + var/list/head_overlays = head?.get_hair_overlays() + if(length(head_overlays)) + overlays_standing[HAIR_LAYER] = head_overlays + apply_overlay(HAIR_LAYER) /// Updates face (as of now, only eye) offsets /mob/living/carbon/human/update_face_offset() @@ -1268,8 +1115,8 @@ mutant_styles: The mutant style - taur bodytype, STYLE_TESHARI, etc. // SKYRAT E apply_overlay(EYES_LAYER) -// Only renders the head of the human -/mob/living/carbon/human/proc/update_body_parts_head_only(update_limb_data) +/// Makes all aspects of the mob invisibile but the head and its associated sprites +/mob/living/carbon/human/proc/render_only_head() if(!dna?.species) return @@ -1278,69 +1125,13 @@ mutant_styles: The mutant style - taur bodytype, STYLE_TESHARI, etc. // SKYRAT E if(!istype(my_head)) return - my_head.update_limb(is_creating = update_limb_data) - //BUBBER EDIT START - We need to account for different heights when using this proc - var/my_head_icon = my_head.get_limb_icon(dropped = FALSE, update_on = src) - - if(mob_height != HUMAN_HEIGHT_MEDIUM) - var/string_form_index = num2text(HEAD_LAYER) - var/offset_type = GLOB.layers_to_offset[string_form_index] - if(isnull(offset_type)) - if(islist(my_head_icon)) - for(var/image/applied_appearance in my_head_icon) - apply_height_filters(applied_appearance) - else if(isimage(my_head_icon)) - apply_height_filters(my_head_icon) - else - if(islist(my_head_icon)) - for(var/image/applied_appearance in my_head_icon) - apply_height_offsets(applied_appearance, offset_type) - else if(isimage(my_head_icon)) - apply_height_offsets(my_head_icon, offset_type) - - add_overlay(my_head_icon) - //add_overlay(my_head.get_limb_icon(dropped = FALSE, update_on = src)) - //BUBBER EDIT END + cut_overlays() + my_head.update_limb() + add_overlay(my_head.get_limb_icon()) update_worn_head() update_worn_mask() - -/** - * Used to perform regular updates to the limbs of humans with special bodyshapes - * - * * check_shapes: The bodyshapes to check for. - * Any limbs or organs which share this shape, will be updated. - * * ignore_slots: The slots to ignore when updating the limbs. - * This is useful for things like digitigrade legs, where we can skip some slots that we're already updating. - * - * return an integer, the number of limbs updated - */ -/mob/living/carbon/human/proc/check_body_shape(check_shapes = BODYSHAPE_DIGITIGRADE|BODYSHAPE_SNOUTED, ignore_slots = NONE) - . = 0 - if(!(bodyshape & check_shapes)) - // optimization - none of our limbs or organs have the desired shape - return . - - for(var/obj/item/bodypart/limb as anything in get_bodyparts()) - var/checked_bodyshape = limb.bodyshape - // accounts for stuff like snouts - for(var/obj/item/organ/organ in limb) - checked_bodyshape |= organ.external_bodyshapes - - // any limb needs to be updated, so stop here and do it - if(checked_bodyshape & check_shapes) - . = update_body_parts() - break - - if(!.) - return - // hardcoding this here until bodypart updating is more sane - // we need to update clothing items that may have been affected by bodyshape updates - if(check_shapes & BODYSHAPE_DIGITIGRADE) - for(var/obj/item/thing as anything in get_equipped_items(INCLUDE_PROSTHETICS|INCLUDE_ABSTRACT)) - if(thing.slot_flags & ignore_slots) - continue - if(thing.supports_variations_flags & DIGITIGRADE_VARIATIONS) - thing.update_slot_icon() + update_eyes() + update_hair() // Hooks into human apply overlay so that we can modify all overlays applied through standing overlays to our height system. // Some of our overlays will be passed through a displacement filter to make our mob look taller or shorter. @@ -1396,11 +1187,14 @@ mutant_styles: The mutant style - taur bodytype, STYLE_TESHARI, etc. // SKYRAT E var/static/icon/cut_legs_mask = icon('icons/effects/cut.dmi', "Cut2") var/static/icon/lenghten_torso_mask = icon('icons/effects/cut.dmi', "Cut3") var/static/icon/lenghten_legs_mask = icon('icons/effects/cut.dmi', "Cut4") + var/static/icon/lenghten_arms_mask = icon('icons/effects/cut.dmi', "Cut5") + appearance.remove_filter(list( "Cut_Torso", "Cut_Legs", "Lenghten_Legs", "Lenghten_Torso", + "Lenghten_Arms", "Gnome_Cut_Torso", "Gnome_Cut_Legs", "Monkey_Torso", @@ -1502,10 +1296,15 @@ mutant_styles: The mutant style - taur bodytype, STYLE_TESHARI, etc. // SKYRAT E "priority" = 1, "params" = displacement_map_filter(lenghten_torso_mask, x = 0, y = 0, size = 1), ), + list( + "name" = "Lenghten_Arms", + "priority" = 1, + "params" = displacement_map_filter(lenghten_arms_mask, x = 0, y = 0, size = 1), + ), list( "name" = "Lenghten_Legs", "priority" = 1, - "params" = displacement_map_filter(lenghten_legs_mask, x = 0, y = 0, size = 2), + "params" = displacement_map_filter(lenghten_legs_mask, x = 0, y = 0, size = 1), ), )) diff --git a/code/modules/mob/living/carbon/human/init_signals.dm b/code/modules/mob/living/carbon/human/init_signals.dm index 55ab5d6b6b8..9f864884723 100644 --- a/code/modules/mob/living/carbon/human/init_signals.dm +++ b/code/modules/mob/living/carbon/human/init_signals.dm @@ -12,8 +12,9 @@ RegisterSignal(src, COMSIG_COMPONENT_CLEAN_FACE_ACT, PROC_REF(clean_face)) - RegisterSignals(src, list(SIGNAL_ADDTRAIT(TRAIT_HUSK), SIGNAL_REMOVETRAIT(TRAIT_HUSK)), PROC_REF(refresh_obscured)) + RegisterSignals(src, list(SIGNAL_ADDTRAIT(TRAIT_HUSK), SIGNAL_REMOVETRAIT(TRAIT_HUSK)), PROC_REF(husk_trait_toggle)) RegisterSignals(src, list(SIGNAL_ADDTRAIT(TRAIT_INVISIBLE_MAN), SIGNAL_REMOVETRAIT(TRAIT_INVISIBLE_MAN)), PROC_REF(invisible_man_toggle)) + RegisterSignals(src, list(SIGNAL_ADDTRAIT(TRAIT_NO_UNDERWEAR), SIGNAL_REMOVETRAIT(TRAIT_NO_UNDERWEAR)), PROC_REF(no_underwear_toggle)) /// Gaining or losing [TRAIT_DWARF] updates our height and grants passtable /mob/living/carbon/human/proc/on_dwarf_trait(datum/source) @@ -67,8 +68,19 @@ ) playsound(src, SFX_RUSTLE, 50, TRUE, -5, frequency = 0.8) +/mob/living/carbon/human/proc/husk_trait_toggle(datum/source) + SIGNAL_HANDLER + refresh_obscured() + update_body() + /// When [TRAIT_INVISIBLE_MAN] is added or removed we need to update a few things /mob/living/carbon/human/proc/invisible_man_toggle(datum/source) SIGNAL_HANDLER refresh_obscured() update_visible_name() + update_body() + +/// When [TRAIT_NO_UNDERWEAR] is added or removed we need to update our body to hide or show underwear sprites +/mob/living/carbon/human/proc/no_underwear_toggle(datum/source) + SIGNAL_HANDLER + update_body() diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index e0c2a1a1a52..0d644b01e8e 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -299,18 +299,29 @@ var/obj/item/existing_tank = is_external ? external : internal if(tank == existing_tank) return toggle_close_internals(is_external) + // Use breathing tube regardless of mask. if(can_breathe_tube()) return toggle_open_internals(tank, is_external) + // Use mask in absence of tube. - if(isclothing(wear_mask) && ((wear_mask.visor_flags & MASKINTERNALS) || (wear_mask.clothing_flags & MASKINTERNALS))) - // Adjust dishevelled breathing mask back onto face unless it is exempt. - if ((wear_mask.up) && !(wear_mask.clothing_flags & INTERNALS_ADJUST_EXEMPT)) - wear_mask.adjust_visor(src) + if(can_breathe_mask()) return toggle_open_internals(tank, is_external) + // We have a valid mask but it's pulled down + else if(isclothing(wear_mask)) + var/obj/item/clothing/mask = wear_mask + if (mask.up && (mask.visor_flags & MASKINTERNALS) && !(mask.clothing_flags & INTERNALS_ADJUST_EXEMPT) && mask.adjust_visor(src)) + return toggle_open_internals(tank, is_external) + // Use helmet in absence of tube or valid mask. if(can_breathe_helmet()) return toggle_open_internals(tank, is_external) + // We have a valid helmet but its visor is up + else if(isclothing(head)) + var/obj/item/clothing/helmet = head + if (helmet.up && (helmet.visor_flags & HEADINTERNALS) && !(helmet.clothing_flags & INTERNALS_ADJUST_EXEMPT) && helmet.adjust_visor(src)) + return toggle_open_internals(tank, is_external) + // Notify user of missing valid breathing apparatus. if (wear_mask) // Invalid mask diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 4714ba39cb1..3c21ea44ed5 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -23,7 +23,6 @@ return . = ..() - if(QDELETED(src)) return FALSE @@ -45,8 +44,9 @@ handle_heart(seconds_per_tick) // Handles liver failure effects, if we lack a liver handle_liver(seconds_per_tick) - // For special species interactions - dna.species.spec_life(src, seconds_per_tick) + // Crit damage but specifically for people who don't get suffocate while in crit so they can actually die eventually + if(HAS_TRAIT(src, TRAIT_NOBREATH) && (health < crit_threshold) && !HAS_TRAIT(src, TRAIT_NOCRITDAMAGE)) + adjust_brute_loss(0.5 * seconds_per_tick) return stat != DEAD /mob/living/carbon/human/calculate_affecting_pressure(pressure) diff --git a/code/modules/mob/living/carbon/human/species_types/dullahan.dm b/code/modules/mob/living/carbon/human/species_types/dullahan.dm index fb751eefe2e..777e2ca64bd 100644 --- a/code/modules/mob/living/carbon/human/species_types/dullahan.dm +++ b/code/modules/mob/living/carbon/human/species_types/dullahan.dm @@ -60,7 +60,6 @@ eyes.eye_color_left = human.eye_color_left eyes.eye_color_right = human.eye_color_right eyes.bodypart_insert(head) - human.update_body() head.update_limb() head.update_icon_dropped() RegisterSignal(head, COMSIG_QDELETING, PROC_REF(on_head_destroyed)) diff --git a/code/modules/mob/living/carbon/human/species_types/ethereal.dm b/code/modules/mob/living/carbon/human/species_types/ethereal.dm index 9ae530779f9..b786432469e 100644 --- a/code/modules/mob/living/carbon/human/species_types/ethereal.dm +++ b/code/modules/mob/living/carbon/human/species_types/ethereal.dm @@ -112,16 +112,16 @@ currently_flickered = FALSE ethereal_light.set_light_on(TRUE) fixed_mut_color = current_color - ethereal.update_body() ethereal.set_facial_haircolor(current_color, override = TRUE, update = FALSE) - ethereal.set_haircolor(current_color, override = TRUE, update = TRUE) + ethereal.set_haircolor(current_color, override = TRUE, update = FALSE) + ethereal.update_body() else ethereal_light.set_light_on(FALSE) var/dead_color = rgb(128,128,128) fixed_mut_color = dead_color - ethereal.update_body() ethereal.set_facial_haircolor(dead_color, override = TRUE, update = FALSE) - ethereal.set_haircolor(dead_color, override = TRUE, update = TRUE) + ethereal.set_haircolor(dead_color, override = TRUE, update = FALSE) + ethereal.update_body() /datum/species/ethereal/proc/on_emp_act(mob/living/carbon/human/source, severity, protection) SIGNAL_HANDLER 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 c4c3a27f879..54af1a4852f 100644 --- a/code/modules/mob/living/carbon/human/species_types/felinid.dm +++ b/code/modules/mob/living/carbon/human/species_types/felinid.dm @@ -128,17 +128,15 @@ human_for_preview.set_hairstyle("Hime Cut", update = TRUE) - /* SKYRAT EDIT - Making the species menu icons work better - ORIGINAL: + /* // SKYRAT EDIT REMOVAL START - Making the species menu icons work better - ORIGINAL: var/obj/item/organ/ears/cat/cat_ears = human_for_preview.get_organ_by_type(/obj/item/organ/ears/cat) if (cat_ears) cat_ears.color = human_for_preview.hair_color - human_for_preview.update_body() - */ - human_for_preview.dna.mutant_bodyparts[FEATURE_TAIL_GENERIC] = list(MUTANT_INDEX_NAME = "Cat", MUTANT_INDEX_COLOR_LIST = list(human_for_preview.hair_color)) - human_for_preview.dna.mutant_bodyparts[FEATURE_EARS] = list(MUTANT_INDEX_NAME = "Cat", MUTANT_INDEX_COLOR_LIST = list(human_for_preview.hair_color)) + human_for_preview.update_hair() + */ // SKYRAT EDIT REMOVAL END + // SKYRAT EDIT ADDITION START regenerate_organs(human_for_preview, src, visual_only = TRUE) - human_for_preview.update_body(TRUE) - // BUBBER EDIT CHANGE END + // SKYRAT EDIT ADDITION END /datum/species/human/felinid/get_physical_attributes() return "Felinids are very similar to humans in almost all respects, with their biggest differences being the ability to lick their wounds, \ diff --git a/code/modules/mob/living/carbon/human/species_types/flypeople.dm b/code/modules/mob/living/carbon/human/species_types/flypeople.dm index eca9383698f..93d054d5344 100644 --- a/code/modules/mob/living/carbon/human/species_types/flypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/flypeople.dm @@ -26,20 +26,6 @@ BODY_ZONE_CHEST = /obj/item/bodypart/chest/fly, ) -/datum/species/fly/on_species_gain(mob/living/carbon/human/human_who_gained_species, datum/species/old_species, pref_load, regenerate_icons) - . = ..() - RegisterSignal(human_who_gained_species, COMSIG_ATOM_ATTACKBY, PROC_REF(on_attackby)) - -/datum/species/fly/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load) - . = ..() - UnregisterSignal(C, COMSIG_ATOM_ATTACKBY) - -/datum/species/fly/proc/on_attackby(mob/living/source, obj/item/attacking_item, mob/living/attacker, list/modifiers, list/attack_modifiers) - SIGNAL_HANDLER - - if(istype(attacking_item, /obj/item/melee/flyswatter)) - MODIFY_ATTACK_FORCE_MULTIPLIER(attack_modifiers, 30) // Yes, a 30x damage modifier - /datum/species/fly/get_physical_attributes() return "These hideous creatures suffer from pesticide immensely, eat waste, and are incredibly vulnerable to bright lights. They do have wings though." diff --git a/code/modules/mob/living/carbon/human/species_types/ghost.dm b/code/modules/mob/living/carbon/human/species_types/ghost.dm index 0a53c7b41ba..d1da78e3870 100644 --- a/code/modules/mob/living/carbon/human/species_types/ghost.dm +++ b/code/modules/mob/living/carbon/human/species_types/ghost.dm @@ -1,23 +1,22 @@ ///Spirit mob that lacks legs but still roams the station as part of the unliving. -/datum/species/ghost - name = "Ghost" - id = SPECIES_GHOST +/datum/species/spirit + name = "Spirit" + id = SPECIES_SPIRIT inherent_traits = list( TRAIT_GENELESS, - TRAIT_MOVE_FLYING, TRAIT_NEVER_WOUNDED, TRAIT_NOBLOOD, TRAIT_NODISMEMBER, TRAIT_NO_DNA_COPY, - TRAIT_NO_FLOATING_ANIM, TRAIT_NO_PLASMA_TRANSFORM, TRAIT_NO_UNDERWEAR, - TRAIT_RESISTLOWPRESSURE, TRAIT_UNHUSKABLE, + TRAIT_NO_FLOATING_ANIM, + TRAIT_MOVE_FLYING, ) - inherent_biotypes = MOB_HUMANOID | MOB_SPIRIT | MOB_UNDEAD + inherent_biotypes = MOB_SPIRIT | MOB_UNDEAD no_equip_flags = ITEM_SLOT_FEET - changesource_flags = MIRROR_BADMIN | WABBAJACK | SLIME_EXTRACT | MIRROR_PRIDE | MIRROR_MAGIC + changesource_flags = MIRROR_BADMIN | MIRROR_PRIDE | MIRROR_MAGIC | WABBAJACK | SLIME_EXTRACT sexes = FALSE meat = /obj/item/ectoplasm @@ -33,45 +32,34 @@ bodypart_overrides = list( BODY_ZONE_HEAD = /obj/item/bodypart/head/ghost, - BODY_ZONE_CHEST = /obj/item/bodypart/chest/ghost, + BODY_ZONE_CHEST = /obj/item/bodypart/chest/ghost/spirit, BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left/ghost, BODY_ZONE_R_ARM = /obj/item/bodypart/arm/right/ghost, ) - ///Innate passthrough ability given to ghosts that allows them to phase but drops their stuff. - var/datum/action/innate/toggle_passthrough/passthrough_ability + ///Boolean on whether this species type is available at roundstart during halloween, used to deny subtypes. + var/halloween_exclusive = TRUE -/datum/species/ghost/check_roundstart_eligible() - if(check_holidays(HALLOWEEN)) +/datum/species/spirit/check_roundstart_eligible() + if(check_holidays(HALLOWEEN) && halloween_exclusive) return TRUE return ..() -/datum/species/ghost/on_species_gain(mob/living/carbon/human/new_ghost, datum/species/old_species, pref_load, regenerate_icons) - . = ..() - passthrough_ability = new(src) - passthrough_ability.Grant(new_ghost) +/datum/species/spirit/get_physical_attributes() + return "Spirits are the spiritual remains of long-passed entities. They lack legs, can fly, but still eat, breathe, hear and see." -/datum/species/ghost/on_species_loss(mob/living/carbon/human/former_ghost, datum/species/new_species, pref_load) - QDEL_NULL(passthrough_ability) - return ..() - -/datum/species/ghost/get_physical_attributes() - return "Ghosts are the spiritual remains of long-passed entities. They lack legs, can fly, and phase through walls, \ - but still eat, breathe, hear and see." - -/datum/species/ghost/get_species_description() +/datum/species/spirit/get_species_description() return "Spirits are spirits of long-dead creatures whom, for one reason or another, still roam around." -/datum/species/ghost/get_species_lore() +/datum/species/spirit/get_species_lore() return list( - "Ghosts are one of the spookiest creatures known in the galaxy. \ - While they still need their protein to sustain themselves, they are able to control their own bodies, \ - going through walls and getting rid of all their posessions at will. \ - Most knowledge known about them is kept secret by Nanotrasen's top Chaplains, who are keen \ - to keep it private.", + "Spirits are the non-physical remains that linger onto their mortal coil. \ + They still need their protein and organs to keep themselves \"alive\", \ + which leads to many of them still believing they are still part of the living, \ + whether or not they are is a very open-ended debate between philosophers.", ) -/datum/species/ghost/create_pref_unique_perks() +/datum/species/spirit/create_pref_unique_perks() var/list/to_add = list() to_add += list(list( @@ -81,14 +69,6 @@ SPECIES_PERK_DESC = "Ghosts lack legs and float, preventing you from falling into holes in the ground.", )) - to_add += list(list( - SPECIES_PERK_TYPE = SPECIES_NEUTRAL_PERK, - SPECIES_PERK_ICON = "ghost", - SPECIES_PERK_NAME = "Incorporeal", - SPECIES_PERK_DESC = "Ghost carry their tombstones with them and are directly tied to it. \ - dropping the tombstone will allow you to phase through solid matter, but leaves you vulnerable.", - )) - to_add += list(list( SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, SPECIES_PERK_ICON = "shoe-prints", @@ -98,35 +78,102 @@ return to_add +/** + * Ghost subtype + * This is the type of ghost that can actually phase through walls, + * exclusive to magic mirrors & admins, as roundstart-ability to phase anywhere + * is not something that is generally fun to play against. + */ +/datum/species/spirit/ghost + name = "Ghost" + id = SPECIES_GHOST + inherent_traits = list( + TRAIT_GENELESS, + TRAIT_NEVER_WOUNDED, + TRAIT_NOBLOOD, + TRAIT_NODISMEMBER, + TRAIT_NO_DNA_COPY, + TRAIT_NO_PLASMA_TRANSFORM, + TRAIT_NO_UNDERWEAR, + TRAIT_UNHUSKABLE, + TRAIT_NO_FLOATING_ANIM, + TRAIT_MOVE_FLYING, + //ghost-unique + TRAIT_SEE_BLESSED_TILES, + ) + //they have a different chest. + bodypart_overrides = list( + BODY_ZONE_HEAD = /obj/item/bodypart/head/ghost, + BODY_ZONE_CHEST = /obj/item/bodypart/chest/ghost, + BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left/ghost, + BODY_ZONE_R_ARM = /obj/item/bodypart/arm/right/ghost, + ) + changesource_flags = MIRROR_BADMIN | WABBAJACK + halloween_exclusive = FALSE + + ///Innate passthrough ability given to ghosts that allows them to phase but drops their stuff. + var/datum/action/innate/toggle_passthrough/passthrough_ability + +/datum/species/spirit/ghost/get_physical_attributes() + return "Ghosts are the spiritual remains of long-passed entities. They lack legs, can fly, can choose at will to become incorporeal, \ + but still eat, breathe, hear and see." + +/datum/species/spirit/ghost/get_species_lore() + return list( + "Ghosts are one of the spookiest creatures known in the galaxy. \ + While they still need their protein to sustain themselves, they are able to control their own bodies, \ + going through walls and getting rid of all their posessions at will. \ + Most knowledge known about them is kept secret by Nanotrasen's top Chaplains, who are keen \ + to keep it private.", + ) + +/datum/species/spirit/ghost/on_species_gain(mob/living/carbon/human/new_ghost, datum/species/old_species, pref_load, regenerate_icons) + . = ..() + passthrough_ability = new(src) + passthrough_ability.Grant(new_ghost) + for(var/datum/atom_hud/alternate_appearance/basic/blessed_aware/blessed_hud in GLOB.active_alternate_appearances) + blessed_hud.check_hud(new_ghost) + +/datum/species/spirit/ghost/on_species_loss(mob/living/carbon/human/former_ghost, datum/species/new_species, pref_load) + . = ..() + QDEL_NULL(passthrough_ability) + //this has to be called after parent so inherent traits is cleared before we update our HUDs + for(var/datum/atom_hud/alternate_appearance/basic/blessed_aware/blessed_hud in GLOB.active_alternate_appearances) + blessed_hud.check_hud(former_ghost) + +/datum/species/spirit/ghost/create_pref_unique_perks() + var/list/to_add = ..() + + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "ghost", + SPECIES_PERK_NAME = "Incorporeal", + SPECIES_PERK_DESC = "Ghost are able to control their body to the extent where you can willingly make yourself able \ + to phase through anything, including your own equipment.", + )) + + return to_add + /** * Passthrough ability * * Ghost innate ability that allows them to enter ghost mode, - * which gives them the phasing ability, but makes them unable to use anything, - * and they will be tied to a tombstone that, if dug up, will kill them and turn them - * into a skeleton. + * which gives them the phasing ability, but makes them drop everything + * and completely unable to wear anything. */ /datum/action/innate/toggle_passthrough name = "Toggle passthrough" - desc = "Toggles phasing through everything, including your hands. You are tied to your tombstone while this is active. \ - At least you know how to keep your clothes on." + desc = "Toggles your ability to phase through everything, including your gear and any incompatible organs/limbs." button_icon = 'icons/hud/actions.dmi' button_icon_state = "ghost" - ///Grave that appears when we're passing through, which we are also tied to. - var/obj/structure/closet/crate/grave/skeleton/grave - /datum/action/innate/toggle_passthrough/Grant(mob/grant_to) . = ..() - grave = new() - //contents are initialized when the grave is robbed as that's when the crate is opened for the first time. - RegisterSignal(grave, COMSIG_CLOSET_CONTENTS_INITIALIZED, PROC_REF(on_grave_robbed)) - RegisterSignal(grave, COMSIG_CLOSET_POST_OPEN, PROC_REF(post_grave_robbed)) + RegisterSignal(grant_to, COMSIG_CARBON_POST_ATTACH_LIMB, PROC_REF(on_new_limb)) /datum/action/innate/toggle_passthrough/Remove(mob/remove_from) - if(!QDELING(remove_from)) - swap_mode(force_off = TRUE) - QDEL_NULL(grave) + swap_mode(force_off = TRUE) + UnregisterSignal(remove_from, COMSIG_CARBON_POST_ATTACH_LIMB) return ..() /datum/action/innate/toggle_passthrough/Activate() @@ -135,61 +182,75 @@ return swap_mode() +/datum/action/innate/toggle_passthrough/IsAvailable(feedback) + if(!isliving(owner)) + return FALSE + var/mob/living/living_owner = owner + if(living_owner.has_reagent(/datum/reagent/water/holywater)) + return FALSE + //technically you can trap a ghost by blessing them as theyre phasing, + //but they can still be dragged out. + if(locate(/obj/effect/blessing) in get_turf(owner)) + return FALSE + var/obj/item/bodypart/chest/their_chest = living_owner.get_bodypart(BODY_ZONE_CHEST) + if(!their_chest || !(their_chest.bodytype & BODYTYPE_GHOST)) + return FALSE + return ..() + +///Called when the owner of this action gets a new limb, if it isn't a ghost-limb +///the action will turn itself off, and you'll lose said limb if you try using this action again. +/datum/action/innate/toggle_passthrough/proc/on_new_limb(mob/source, obj/item/bodypart/new_part, special) + SIGNAL_HANDLER + if(!iscarbon(owner)) + return + if(!(new_part.bodytype & BODYTYPE_GHOST)) + swap_mode(force_off = TRUE) + ///Swaps the mode, allowing us to phase through stuff but drops everything. Optional 'force_off' arg to prevent being able to turn it on. /datum/action/innate/toggle_passthrough/proc/swap_mode(force_off) //we can only turn off, early return if we're trying to turn it on instead. if(force_off && HAS_TRAIT_FROM(owner, TRAIT_NO_FLOATING_ANIM, SPECIES_TRAIT)) return - if(HAS_TRAIT_FROM(owner, TRAIT_NO_FLOATING_ANIM, SPECIES_TRAIT)) - grave.forceMove(get_turf(owner)) - owner.AddComponent(/datum/component/leash, grave, distance = 7) - REMOVE_TRAIT(owner, TRAIT_NO_FLOATING_ANIM, SPECIES_TRAIT) - owner.add_traits(list( + var/mob/living/carbon/carbon_owner = owner + var/datum/species/carbon_species = carbon_owner.dna.species + + //drop any limbs & organs that can't phase, now that you're phasing. + for(var/obj/item/bodypart/bodypart as anything in carbon_owner.bodyparts) + if(!(bodypart.bodytype & BODYTYPE_GHOST)) + bodypart.drop_limb(special = FALSE, dismembered = FALSE, move_to_floor = TRUE) + for(var/obj/item/organ/organ as anything in carbon_owner.organs) + if(!(organ.organ_flags & ORGAN_GHOST)) + organ.Remove(owner, special = FALSE) + + if(HAS_TRAIT_FROM(carbon_owner, TRAIT_NO_FLOATING_ANIM, SPECIES_TRAIT)) + REMOVE_TRAIT(carbon_owner, TRAIT_NO_FLOATING_ANIM, SPECIES_TRAIT) + carbon_owner.add_traits(list( TRAIT_MOVE_PHASING, TRAIT_PIERCEIMMUNE, TRAIT_INVISIBLE_TO_CAMERA, TRAIT_HANDS_BLOCKED, //MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_STORAGE TRAIT_PULL_BLOCKED, //MOBILITY_PULL TRAIT_UI_BLOCKED, //MOBILITY_UI - ), SPECIES_TRAIT) - RegisterSignal(owner, COMSIG_LIVING_DEATH, PROC_REF(on_owner_died)) + ), SPECIES_TRAIT) + carbon_species.update_no_equip_flags(carbon_owner, ALL) + RegisterSignal(carbon_owner, COMSIG_MOB_CLIENT_PRE_LIVING_MOVE, PROC_REF(attempt_move)) else - qdel(owner.GetComponent(/datum/component/leash)) - owner.forceMove(get_turf(grave)) - grave.moveToNullspace() - ADD_TRAIT(owner, TRAIT_NO_FLOATING_ANIM, SPECIES_TRAIT) - owner.remove_traits(list( + ADD_TRAIT(carbon_owner, TRAIT_NO_FLOATING_ANIM, SPECIES_TRAIT) + carbon_owner.remove_traits(list( TRAIT_MOVE_PHASING, TRAIT_PIERCEIMMUNE, TRAIT_INVISIBLE_TO_CAMERA, TRAIT_HANDS_BLOCKED, TRAIT_PULL_BLOCKED, TRAIT_UI_BLOCKED, - ), SPECIES_TRAIT) - UnregisterSignal(owner, COMSIG_LIVING_DEATH) + ), SPECIES_TRAIT) + carbon_species.update_no_equip_flags(carbon_owner, initial(carbon_species.no_equip_flags)) + UnregisterSignal(carbon_owner, COMSIG_MOB_CLIENT_PRE_LIVING_MOVE) -/datum/action/innate/toggle_passthrough/proc/on_owner_died(mob/living/owner) +///Called when attempting to move to a new tile while the action is active, returns to cancel moving. +/datum/action/innate/toggle_passthrough/proc/attempt_move(mob/source, new_loc, direct) SIGNAL_HANDLER - swap_mode(force_off = TRUE) - -///Called when the contents are made, which means the grave has been 'opened', therefore robbed. -/datum/action/innate/toggle_passthrough/proc/on_grave_robbed(obj/structure/closet/crate/grave/skeleton/source) - SIGNAL_HANDLER - var/mob/living/carbon/human/species/skeleton/skeletons_in_the_closet = locate() in source.contents - skeletons_in_the_closet.real_name = owner.real_name - skeletons_in_the_closet.name = owner.name - - if (owner.mind?.active) - owner.mind?.transfer_to(skeletons_in_the_closet, force_key_move = TRUE) - skeletons_in_the_closet.death(gibbed = TRUE) // This is a lie, but it stops the skeleton from deathgasping as if it only just died - - if (isliving(owner)) // You know just in case we give an observer the crazy ability to walk through walls - var/mob/living/living_owner = owner - living_owner.forceMove(source) - living_owner.unequip_everything() - -///Called AFTER the contents have been spit out, which means the owner is now in the skeleton. Let's clean up. -/datum/action/innate/toggle_passthrough/proc/post_grave_robbed(obj/structure/closet/crate/grave/skeleton/source) - SIGNAL_HANDLER - qdel(owner) + if(locate(/obj/effect/blessing) in new_loc) + to_chat(source, span_warning("Holy energies block your path!")) + return COMSIG_MOB_CLIENT_BLOCK_PRE_LIVING_MOVE diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm index 493540162b5..23e3554d170 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -66,6 +66,7 @@ RegisterSignal(human_who_gained_species, COMSIG_CARBON_DEFIB_HEART_CHECK, PROC_REF(defib_check)) RegisterSignal(human_who_gained_species, COMSIG_ATOM_ITEM_INTERACTION, PROC_REF(rebuild_check)) RegisterSignal(human_who_gained_species, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) + RegisterSignal(human_who_gained_species, COMSIG_LIVING_LIFE, PROC_REF(on_life)) // nutrition = health, so give people a head start human_who_gained_species.set_nutrition(NUTRITION_LEVEL_WELL_FED) @@ -81,14 +82,16 @@ COMSIG_CARBON_DEFIB_HEART_CHECK, COMSIG_ATOM_ITEM_INTERACTION, COMSIG_ATOM_EXAMINE, + COMSIG_LIVING_LIFE, )) human_who_lost_species.physiology.stamina_mod /= 0.6 human_who_lost_species.physiology.stun_mod /= 0.6 human_who_lost_species.physiology.knockdown_mod /= 1.2 -/datum/species/golem/spec_life(mob/living/carbon/human/source, seconds_per_tick) - . = ..() +/datum/species/golem/proc/on_life(mob/living/carbon/human/source, seconds_per_tick) + SIGNAL_HANDLER + if(source.nutrition <= 20) // this is "hard crit" for golems source.Unconscious(1.5 SECONDS * seconds_per_tick) 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 5868244888f..03f69d035c6 100644 --- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -223,7 +223,10 @@ // so if someone mindswapped into them, they'd still be shared. bodies = null C.set_blood_volume(C.get_blood_volume(), maximum = BLOOD_VOLUME_NORMAL) - UnregisterSignal(C, COMSIG_LIVING_DEATH) + UnregisterSignal(C, list( + COMSIG_LIVING_DEATH, + COMSIG_LIVING_LIFE, + )) ..() /datum/species/jelly/slime/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load, regenerate_icons) @@ -240,6 +243,7 @@ bodies |= C RegisterSignal(C, COMSIG_LIVING_DEATH, PROC_REF(on_death_move_body)) + RegisterSignal(C, COMSIG_LIVING_LIFE, PROC_REF(on_life)) /datum/species/jelly/slime/proc/on_death_move_body(mob/living/carbon/human/source, gibbed) SIGNAL_HANDLER @@ -263,16 +267,16 @@ /datum/species/jelly/slime/copy_properties_from(datum/species/jelly/slime/old_species) bodies = old_species.bodies -/datum/species/jelly/slime/spec_life(mob/living/carbon/human/H, seconds_per_tick) - . = ..() - if(H.get_blood_volume() >= BLOOD_VOLUME_SLIME_SPLIT) +/datum/species/jelly/slime/proc/on_life(mob/living/carbon/human/source, seconds_per_tick) + SIGNAL_HANDLER + if(source.get_blood_volume() >= BLOOD_VOLUME_SLIME_SPLIT) if(SPT_PROB(2.5, seconds_per_tick)) - to_chat(H, span_notice("You feel very bloated!")) + to_chat(source, span_notice("You feel very bloated!")) - else if(H.nutrition >= NUTRITION_LEVEL_WELL_FED) - H.adjust_blood_volume(1.5 * seconds_per_tick) - if(H.get_blood_volume() <= BLOOD_VOLUME_LOSE_NUTRITION) - H.adjust_nutrition(-1.25 * seconds_per_tick) + else if(source.nutrition >= NUTRITION_LEVEL_WELL_FED) + source.adjust_blood_volume(1.5 * seconds_per_tick) + if(source.get_blood_volume() <= BLOOD_VOLUME_LOSE_NUTRITION) + source.adjust_nutrition(-1.25 * seconds_per_tick) /datum/action/innate/split_body name = "Split Body" diff --git a/code/modules/mob/living/carbon/human/species_types/mothmen.dm b/code/modules/mob/living/carbon/human/species_types/mothmen.dm index 40dc7be3325..2592d9c287c 100644 --- a/code/modules/mob/living/carbon/human/species_types/mothmen.dm +++ b/code/modules/mob/living/carbon/human/species_types/mothmen.dm @@ -27,20 +27,6 @@ BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/moth, ) -/datum/species/moth/on_species_gain(mob/living/carbon/human/human_who_gained_species, datum/species/old_species, pref_load, regenerate_icons) - . = ..() - RegisterSignal(human_who_gained_species, COMSIG_ATOM_ATTACKBY, PROC_REF(on_attackby)) - -/datum/species/moth/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load) - . = ..() - UnregisterSignal(C, COMSIG_ATOM_ATTACKBY) - -/datum/species/moth/proc/on_attackby(mob/living/source, obj/item/attacking_item, mob/living/attacker, list/modifiers, list/attack_modifiers) - SIGNAL_HANDLER - - if(istype(attacking_item, /obj/item/melee/flyswatter)) - MODIFY_ATTACK_FORCE_MULTIPLIER(attack_modifiers, 10) // Yes, a 10x damage modifier - /datum/species/moth/randomize_features() var/list/features = ..() features[FEATURE_MOTH_MARKINGS] = pick(SSaccessories.feature_list[FEATURE_MOTH_MARKINGS]) 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 4b990a65949..2989fb95a7d 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -67,9 +67,6 @@ /datum/outfit/syndicate/full/loneop = /datum/outfit/syndicate/full/plasmaman/loneop, ) - /// If the bones themselves are burning clothes won't help you much - var/internal_fire = FALSE - /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/human/species_types/vampire.dm b/code/modules/mob/living/carbon/human/species_types/vampire.dm index 6013c6d2b92..fa31d7a89cf 100644 --- a/code/modules/mob/living/carbon/human/species_types/vampire.dm +++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm @@ -31,19 +31,23 @@ . = ..() to_chat(new_vampire, "[info_text]") new_vampire.skin_tone = "albino" - new_vampire.update_body(0) RegisterSignal(new_vampire, COMSIG_ATOM_ATTACKBY, PROC_REF(on_attackby)) RegisterSignal(new_vampire, COMSIG_MOB_HUD_CREATED, PROC_REF(on_hud_created)) + RegisterSignal(new_vampire, COMSIG_LIVING_LIFE, PROC_REF(on_life)) if(new_vampire.hud_used) on_hud_created(new_vampire) /datum/species/human/vampire/on_species_loss(mob/living/carbon/human/old_vampire, datum/species/new_species, pref_load) . = ..() - UnregisterSignal(old_vampire, COMSIG_ATOM_ATTACKBY) + UnregisterSignal(old_vampire, list( + COMSIG_ATOM_ATTACKBY, + COMSIG_MOB_HUD_CREATED, + COMSIG_LIVING_LIFE, + )) old_vampire.hud_used?.remove_screen_object(HUD_MOB_BLOOD_LEVEL) -/datum/species/human/vampire/spec_life(mob/living/carbon/human/vampire, seconds_per_tick) - . = ..() +/datum/species/human/vampire/proc/on_life(mob/living/carbon/human/vampire, seconds_per_tick) + SIGNAL_HANDLER if(istype(vampire.loc, /obj/structure/closet/crate/coffin)) var/need_mob_update = FALSE need_mob_update += vampire.heal_overall_damage(brute = 2 * seconds_per_tick, burn = 2 * seconds_per_tick, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC) @@ -156,7 +160,6 @@ icon_state = "tongue_vampire" actions_types = list(/datum/action/item_action/organ_action/vampire) organ_traits = list( - TRAIT_SPEAKS_CLEARLY, TRAIT_DRINKS_BLOOD, // future todo : tie nobreath and nohunger to a vampire organ set bonus TRAIT_NOBREATH, diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm index 66164a06a93..c2726d5ab0d 100644 --- a/code/modules/mob/living/carbon/human/species_types/zombies.dm +++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm @@ -47,15 +47,6 @@ BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/zombie ) - /// Spooky growls we sometimes play while alive - var/static/list/spooks = list( - 'sound/effects/hallucinations/growl1.ogg', - 'sound/effects/hallucinations/growl2.ogg', - 'sound/effects/hallucinations/growl3.ogg', - 'sound/effects/hallucinations/veryfar_noise.ogg', - 'sound/effects/hallucinations/wail.ogg', - ) - /// Zombies do not stabilize body temperature they are the walking dead and are cold blooded /datum/species/zombie/body_temperature_core(mob/living/carbon/human/humi, seconds_per_tick) return @@ -178,11 +169,6 @@ /datum/species/zombie/infectious/spec_stun(mob/living/carbon/human/H,amount) return min(2 SECONDS, amount) -/datum/species/zombie/infectious/spec_life(mob/living/carbon/carbon_mob, seconds_per_tick) - . = ..() - if(!HAS_TRAIT(carbon_mob, TRAIT_CRITICAL_CONDITION) && SPT_PROB(2, seconds_per_tick)) - playsound(carbon_mob, pick(spooks), 50, TRUE, 10) - // Weaker subtype - less healing, weaker attacks, etc /datum/species/zombie/infectious/mindless name = "Mindless Infectious Zombie" diff --git a/code/modules/mob/living/carbon/inventory.dm b/code/modules/mob/living/carbon/inventory.dm index 34c6e104e29..fcf292496f2 100644 --- a/code/modules/mob/living/carbon/inventory.dm +++ b/code/modules/mob/living/carbon/inventory.dm @@ -112,8 +112,7 @@ if(equipping.pulledby) equipping.pulledby.stop_pulling() - equipping.screen_loc = null - client?.screen -= equipping + hud_used?.update_inventory_slot(slot) for(var/mob/dead/observe as anything in observers) observe.client?.screen -= equipping @@ -172,7 +171,9 @@ if(!(slot & item.slot_flags)) // Things below only update if slotted in (ie: not held) return if(item.hair_mask) - update_body() + LAZYADD(hair_masks, item.hair_mask) + update_hair() + update_body() // this is solely for lizard frills add_item_coverage(item) /mob/living/carbon/has_unequipped(obj/item/item) @@ -182,7 +183,9 @@ hud_used?.update_locked_slots() if(item.hair_mask) - update_body() + LAZYREMOVE(hair_masks, item.hair_mask) + update_hair() + update_body() // this is solely for lizard frills remove_item_coverage(item) /mob/living/carbon/doUnEquip(obj/item/item_dropping, force, newloc, no_move, invdrop = TRUE, silent = FALSE) @@ -256,8 +259,17 @@ * * removed_slots - slots that were removed from obscured_slots */ /mob/living/carbon/proc/item_coverage_changed(added_slots, removed_slots) + SEND_SIGNAL(src, COMSIG_CARBON_ITEM_COVERAGE_CHANGED, added_slots, removed_slots) update_clothing(hidden_slots_to_inventory_slots(added_slots|removed_slots)) - if((added_slots|removed_slots) & (HIDEJUMPSUIT|HIDEEARS|HIDEEYES|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT|HIDEMUTWINGS|HIDEANTENNAE)) + if((added_slots|removed_slots) & HIDESNOUT) + synchronize_bodyshapes() + if((added_slots|removed_slots) & (HIDEHAIR|HIDEFACIALHAIR)) + update_hair() + if((added_slots|removed_slots) & HIDEEYES) + update_eyes() + // HIDEJUMPSUIT is for digitigrade legs, HIDEEARS is for lizard frills, HIDEHAIR is for felinid ears and lizard horns, the others should be obvious + // future todo; we should collect a list of all bodypart overlays and what conceals/reveals them dynamically, rather than hardcoding this + if((added_slots|removed_slots) & (HIDEJUMPSUIT|HIDEEARS|HIDEHAIR|HIDESNOUT|HIDEMUTWINGS|HIDEANTENNAE)) update_body() /// Returns the helmet if an air tank compatible helmet is equipped. @@ -444,6 +456,8 @@ for(var/obj/item/worn_item in get_equipped_items(INCLUDE_ABSTRACT)) if(worn_item.slot_flags & exluded_equipment_slots) continue + if(worn_item.flags_cover & ALLOW_SURGERY_THROUGH) + continue covered_flags |= worn_item.body_parts_covered // NB: we have to convert covered_flags via cover_flags2body_zones here diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index e5d8589b310..3d5001424fe 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -13,6 +13,9 @@ if(HAS_TRAIT(src, TRAIT_STASIS)) . = ..() + if(QDELETED(src)) + return + reagents?.handle_stasis_chems(src, seconds_per_tick) else //Reagent processing needs to come before breathing, to prevent edge cases. @@ -31,9 +34,6 @@ GLOB.addictions[key].process_addiction(src, seconds_per_tick) handle_brain_damage(seconds_per_tick) - if(stat != DEAD) - handle_bodyparts(seconds_per_tick) - if(stat != DEAD) return TRUE @@ -523,10 +523,6 @@ return COMPONENT_NO_EXPOSE_REAGENTS -/mob/living/carbon/proc/handle_bodyparts(seconds_per_tick) - for(var/obj/item/bodypart/limb as anything in get_bodyparts(include_stumps = TRUE)) - . |= limb.on_life(seconds_per_tick) - /mob/living/carbon/proc/handle_organs(seconds_per_tick) if(stat == DEAD) if(reagents && (reagents.has_reagent(/datum/reagent/toxin/formaldehyde, 1) || reagents.has_reagent(/datum/reagent/cryostylane))) // No organ decay if the body contains formaldehyde. @@ -558,48 +554,20 @@ if(organ?.owner) // This exist mostly because reagent metabolization can cause organ reshuffling organ.on_life(seconds_per_tick) -/mob/living/carbon/handle_diseases(seconds_per_tick) - for(var/datum/disease/disease as anything in diseases) - if(QDELETED(disease)) //Got cured/deleted while the loop was still going. - continue - if(stat != DEAD || disease.process_dead) - disease.stage_act(seconds_per_tick) +/** + * Returns a multiplier representing how effectively this mob can regenerate blood + * + * A return value of 0 means the mob cannot regenerate blood at all. (missing heart or the heart has stopped or is failing) + * Mobs that do not require a heart always return 1, as their blood regeneration is unaffected by heart status. + */ +/mob/living/carbon/proc/get_heart_blood_regeneration_multiplier() + if(!needs_heart()) + return 1 + var/obj/item/organ/heart/heart = get_organ_slot(ORGAN_SLOT_HEART) + if(isnull(heart)) + return 0 -/mob/living/carbon/handle_mutations(time_since_irradiated, seconds_per_tick) - if(!LAZYLEN(dna?.temporary_mutations)) - return - - for(var/mut, mut_data in dna.temporary_mutations) - if(mut_data < world.time) - if(!LAZYLEN(dna.previous)) - continue - if(mut == UI_CHANGED) - if(dna.previous["UI"]) - dna.unique_identity = merge_text(dna.unique_identity,dna.previous["UI"]) - updateappearance(mutations_overlay_update=1) - dna.previous.Remove("UI") - LAZYREMOVE(dna.temporary_mutations, mut) - continue - if(mut == UF_CHANGED) - if(dna.previous["UF"]) - dna.unique_features = merge_text(dna.unique_features,dna.previous["UF"]) - updateappearance(mutcolor_update=1, mutations_overlay_update=1) - dna.previous.Remove("UF") - LAZYREMOVE(dna.temporary_mutations, mut) - continue - if(mut == UE_CHANGED) - if(dna.previous["name"]) - real_name = dna.previous["name"] - name = real_name - dna.previous.Remove("name") - if(dna.previous["UE"]) - dna.unique_enzymes = dna.previous["UE"] - dna.previous.Remove("UE") - if(dna.previous["blood_type"]) - set_blood_type(dna.previous["blood_type"]) - dna.previous.Remove("blood_type") - LAZYREMOVE(dna.temporary_mutations, mut) - continue + return heart.get_blood_regeneration_multiplier() /** * Handles calling metabolization for dead people. diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm index cac2c109e9f..0c0863f39d3 100644 --- a/code/modules/mob/living/death.dm +++ b/code/modules/mob/living/death.dm @@ -232,7 +232,7 @@ set_stat(DEAD) timeofdeath = world.time - station_timestamp_timeofdeath = station_time_timestamp() + station_timestamp_timeofdeath = round_timestamp() var/turf/death_turf = get_turf(src) var/area/death_area = get_area(src) // Display a death message if the mob is a player mob (has an active mind) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index dc50f5ec56c..178679bfc91 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -13,7 +13,7 @@ set waitfor = FALSE SHOULD_NOT_SLEEP(TRUE) - var/signal_result = SEND_SIGNAL(src, COMSIG_LIVING_LIFE, seconds_per_tick) + var/signal_result = SEND_SIGNAL(src, COMSIG_LIVING_PRE_LIFE, seconds_per_tick) if(signal_result & COMPONENT_LIVING_CANCEL_LIFE_PROCESSING) // mmm less work return @@ -41,18 +41,15 @@ if(isnull(loc) || HAS_TRAIT(src, TRAIT_NO_TRANSFORM)) return + SEND_SIGNAL(src, COMSIG_LIVING_LIFE, seconds_per_tick) + if(QDELETED(src)) // signal handlers such as diseases could delete the mob + return + if(!HAS_TRAIT(src, TRAIT_STASIS)) if(stat != DEAD) - //Mutations and radiation - handle_mutations(seconds_per_tick) //Breathing, if applicable handle_breathing(seconds_per_tick) - handle_diseases(seconds_per_tick) // DEAD check is in the proc itself; we want it to spread even if the mob is dead, but to handle its disease-y properties only if you're not. - - if (QDELETED(src)) // Diseases can qdel the mob via transformations - return - // Handle temperature/pressure differences between body and environment var/datum/gas_mixture/environment = loc.return_air() if(environment) @@ -64,21 +61,15 @@ update_nutrition() living_flags &= ~QUEUE_NUTRITION_UPDATE - if (living_flags & BLOOD_UPDATE_QUEUED) + if(living_flags & BLOOD_UPDATE_QUEUED) update_blood_effects() + living_flags &= ~BLOOD_UPDATE_QUEUED if(stat != DEAD) return TRUE /mob/living/proc/handle_breathing(seconds_per_tick) SEND_SIGNAL(src, COMSIG_LIVING_HANDLE_BREATHING, seconds_per_tick) - return - -/mob/living/proc/handle_mutations(seconds_per_tick) - return - -/mob/living/proc/handle_diseases(seconds_per_tick) - return // Base mob environment handler for body temperature /mob/living/proc/handle_environment(datum/gas_mixture/environment, seconds_per_tick) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 0299bfb2eea..20bec83bfff 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -13,6 +13,8 @@ var/datum/atom_hud/data/diagnostic/diag_hud = GLOB.huds[DATA_HUD_DIAGNOSTIC] diag_hud.add_atom_to_hud(src) add_ally(src) + if(!pull_force) + remove_verb(src, /mob/living/verb/pulled) GLOB.mob_living_list += src SSpoints_of_interest.make_point_of_interest(src) update_fov() @@ -539,14 +541,11 @@ //mob verbs are a lot faster than object verbs //for more info on why this is not atom/pull, see examinate() in mob.dm -/mob/living/verb/pulled(atom/movable/AM as mob|obj in oview(1)) +/mob/living/verb/pulled(atom/movable/thing_pulled as mob|obj in oview(1)) set name = "Pull" - set category = "IC" - if(istype(AM) && Adjacent(AM)) - start_pulling(AM) - else if(!combat_mode) //Don;'t cancel pulls if misclicking in combat mode. - stop_pulling() + if(istype(thing_pulled) && Adjacent(thing_pulled)) + start_pulling(thing_pulled) /mob/living/stop_pulling() if(ismob(pulling)) @@ -555,11 +554,6 @@ update_pull_movespeed() update_pull_hud_icon() -/mob/living/verb/stop_pulling1() - set name = "Stop Pulling" - set category = "IC" - stop_pulling() - //same as above /mob/living/pointed(atom/A) if(INCAPACITATED_IGNORING(src, INCAPABLE_RESTRAINTS)) @@ -635,7 +629,7 @@ /mob/living/proc/mob_sleep() set name = "Sleep" - set category = "IC" + set hidden = TRUE if(IsSleeping()) to_chat(src, span_warning("You are already sleeping!")) @@ -690,9 +684,6 @@ return account /mob/living/proc/toggle_resting() - set name = "Rest" - set category = "IC" - set_resting(!resting, FALSE) @@ -1188,10 +1179,7 @@ return FALSE return TRUE -/mob/living/verb/resist() - set name = "Resist" - set category = "IC" - +/mob/living/proc/resist() DEFAULT_QUEUE_OR_CALL_VERB(VERB_CALLBACK(src, PROC_REF(execute_resist))) ///proc extender of [/mob/living/verb/resist] meant to make the process queable if the server is overloaded when the verb is called @@ -1528,7 +1516,7 @@ if(shown_stamina_loss >= stam_crit_threshold) stamina.icon_state = "stamina_crit" else if(shown_stamina_loss > 0 && maxHealth > 0) - stamina.icon_state = "stamina_[6 - ceil(shown_stamina_loss / (maxHealth * 0.2))]" + stamina.icon_state = "stamina_[ceil(shown_stamina_loss / (maxHealth * 0.2))]" else stamina.icon_state = "stamina_full" @@ -1613,7 +1601,7 @@ /mob/living/basic/bot/dedbot = 25, /mob/living/basic/bot/cleanbot = 25, /mob/living/basic/bot/firebot = 25, - /mob/living/basic/bot/honkbot = 25, + /mob/living/basic/bot/secbot/honkbot = 25, /mob/living/basic/bot/hygienebot = 25, /mob/living/basic/bot/vibebot = 25, /mob/living/basic/bot/medbot = 13, @@ -1665,6 +1653,7 @@ /mob/living/basic/bear/russian, /mob/living/basic/blob_minion/blobbernaut, /mob/living/basic/blob_minion/spore, + /mob/living/basic/blood_worm/hatchling/polymorph, /mob/living/basic/butterfly, /mob/living/basic/carp, /mob/living/basic/carp/mega, @@ -2178,6 +2167,13 @@ GLOBAL_LIST_EMPTY(fire_appearances) return FALSE update_transform(var_value/current_size) . = TRUE + if(NAMEOF(src, pull_force)) + if(var_value == 0) //no more pulling + remove_verb(src, /mob/living/verb/pulled) + else + add_verb(src, /mob/living/verb/pulled) + . = TRUE + if(!isnull(.)) datum_flags |= DF_VAR_EDITED @@ -2488,7 +2484,7 @@ GLOBAL_LIST_EMPTY(fire_appearances) return if(. <= UNCONSCIOUS || new_stat >= UNCONSCIOUS) - update_body() // to update eyes + update_eyes() switch(.) //Previous stat. if(CONSCIOUS) @@ -3019,10 +3015,7 @@ GLOBAL_LIST_EMPTY(fire_appearances) log_admin("[key_name(admin)] gave a guardian spirit controlled by [guardian_client] to [src].") BLACKBOX_LOG_ADMIN_VERB("Give Guardian Spirit") -/mob/living/verb/lookup() - set name = "Look Up" - set category = "IC" - +/mob/living/proc/lookup() if(looking_vertically) to_chat(src, "You set your head straight again.") end_look() @@ -3039,10 +3032,7 @@ GLOBAL_LIST_EMPTY(fire_appearances) to_chat(src, "You tilt your head upwards.") look_up() -/mob/living/verb/lookdown() - set name = "Look Down" - set category = "IC" - +/mob/living/proc/lookdown() if(looking_vertically) to_chat(src, "You set your head straight again.") end_look() diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index c4635ca4fda..c657807855f 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -595,7 +595,7 @@ shock_damage *= siemens_coeff if((flags & SHOCK_TESLA) && HAS_TRAIT(src, TRAIT_TESLA_SHOCKIMMUNE)) return FALSE - if(HAS_TRAIT(src, TRAIT_SHOCKIMMUNE)) + if(!(flags & SHOCK_IGNORE_IMMUNITY) && HAS_TRAIT(src, TRAIT_SHOCKIMMUNE)) return FALSE if(shock_damage < 1) return FALSE diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index f6e01ba27be..7ab41448918 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -262,3 +262,7 @@ /// Lazy assoc list of currently applied fishing difficulty modifiers keyed to their source var/list/fishing_difficulty_mods_by_source + + /// When less than or equal to this distance (but not adjacent), this mob can hear parts of distant whispers, but not the entire message. + /// When greater than this distance, this mob cannot hear anything of a whisper. + var/eavesdrop_range = EAVESDROP_EXTRA_RANGE diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/living_movement.dm index 5bad5247f49..9a4fbfd83cf 100644 --- a/code/modules/mob/living/living_movement.dm +++ b/code/modules/mob/living/living_movement.dm @@ -46,7 +46,7 @@ return update_gravity(gravity_state) - + SEND_SIGNAL(src, COMSIG_LIVING_GRAVITY_CHANGED, gravity_state, old_grav_state) if(gravity_state > STANDARD_GRAVITY) gravity_animate() else if(old_grav_state > STANDARD_GRAVITY) diff --git a/code/modules/mob/living/living_say.dm b/code/modules/mob/living/living_say.dm index e89e08f0862..a051486c0c9 100644 --- a/code/modules/mob/living/living_say.dm +++ b/code/modules/mob/living/living_say.dm @@ -301,13 +301,13 @@ GLOBAL_LIST_INIT(message_modes_stat_limits, list( var/message = "" // if someone is whispering we make an extra type of message that is obfuscated for people out of range - // Less than or equal to 0 means normal hearing. More than 0 and less than or equal to EAVESDROP_EXTRA_RANGE means - // partial hearing. More than EAVESDROP_EXTRA_RANGE means no hearing. Exception for GOOD_HEARING trait + // Less than or equal to 0 means normal hearing. More than 0 and less than or equal to eavesdrop_range means + // partial hearing. More than eavesdrop_range means no hearing. Exception for GOOD_HEARING trait var/dist = get_dist(speaker, src) - message_range - if(dist > 0 && dist <= EAVESDROP_EXTRA_RANGE && !HAS_TRAIT(src, TRAIT_GOOD_HEARING)) + if(dist > 0 && dist <= eavesdrop_range && !HAS_TRAIT(src, TRAIT_GOOD_HEARING)) raw_message = stars(raw_message) var/speaker_name = span_name("[message_mods[MODE_SPEAKER_NAME_OVERRIDE] || speaker]") - if(message_range != INFINITY && dist > EAVESDROP_EXTRA_RANGE && !HAS_TRAIT(src, TRAIT_GOOD_HEARING)) + if(message_range != INFINITY && dist > eavesdrop_range && !HAS_TRAIT(src, TRAIT_GOOD_HEARING)) // Too far away and don't have good hearing, you can't hear anything if(is_blind() || HAS_TRAIT(speaker, TRAIT_INVISIBLE_MAN)) // Can't see them speak either return FALSE diff --git a/code/modules/mob/living/navigation.dm b/code/modules/mob/living/navigation.dm index dcaee5b0945..c63b4594b65 100644 --- a/code/modules/mob/living/navigation.dm +++ b/code/modules/mob/living/navigation.dm @@ -10,7 +10,7 @@ /mob/living/verb/navigate() set name = "Navigate" - set category = "IC" + set hidden = TRUE if(incapacitated) return diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 6b15e3e695e..756ef0dea36 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -97,6 +97,7 @@ RegisterSignal(ai_tracking_tool, COMSIG_TRACKABLE_GLIDE_CHANGED, PROC_REF(tracked_glidesize_changed)) add_traits(list(TRAIT_PULL_BLOCKED, TRAIT_AI_ACCESS, TRAIT_HANDS_BLOCKED, TRAIT_CAN_GET_AI_TRACKING_MESSAGE, TRAIT_LOUD_BINARY), INNATE_TRAIT) + AddElement(/datum/element/block_area_power_fail) //Heads up to other binary chat listeners that a new AI is online and listening to Binary. if(announce_init_to_others && !is_centcom_level(z)) //Skip new syndicate AIs and also new AIs on centcom Z @@ -1084,16 +1085,10 @@ end_multicam() /mob/living/silicon/ai/up() - set name = "Move Upwards" - set category = "IC" - if(eyeobj.zMove(UP, z_move_flags = ZMOVE_FEEDBACK)) to_chat(src, span_notice("You move upwards.")) /mob/living/silicon/ai/down() - set name = "Move Down" - set category = "IC" - if(eyeobj.zMove(DOWN, z_move_flags = ZMOVE_FEEDBACK)) to_chat(src, span_notice("You move down.")) diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/living/silicon/ai/freelook/chunk.dm index 04281f0b762..3068b3342c1 100644 --- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm +++ b/code/modules/mob/living/silicon/ai/freelook/chunk.dm @@ -50,7 +50,9 @@ seenby -= eye var/client/client = eye.GetViewerClient() - if(client && eye.use_visibility && seenby.len == 0) + // Bandaid fix for AI multicamera. Static disappears on other cameras when focused camera is far away. + // seenby.len check fixes that, but prevents static removal for those, who exit camera console, when a chunk was observed by 2 or more eye mobs. + if(client && eye.use_visibility && (seenby.len == 0 || (isliving(client.mob) && !isAI(client.mob)))) // Bypass for non-AIs, to unsure static removal. client.images -= active_static_images /** diff --git a/code/modules/mob/living/silicon/robot/inventory.dm b/code/modules/mob/living/silicon/robot/inventory.dm index 30790c176b5..e5e3e6f867d 100644 --- a/code/modules/mob/living/silicon/robot/inventory.dm +++ b/code/modules/mob/living/silicon/robot/inventory.dm @@ -73,23 +73,6 @@ deselect_module(module_num) playsound_local(src, SFX_RUSTLE, 40, TRUE) -/mob/living/silicon/robot/update_held_items() - . = ..() - if(isnull(client) || isnull(hud_used) || hud_used.hud_version == HUD_STYLE_NOHUD) - return - - var/turf/our_turf = get_turf(src) - for (var/held_index in 1 to length(held_items)) - var/obj/item/held = held_items[held_index] - if (!held) - continue - SET_PLANE(held, ABOVE_HUD_PLANE, our_turf) - var/atom/movable/screen/robot/module_slot/slot = hud_used.screen_objects[HUD_KEY_CYBORG_MODULE(held_index)] - if (!slot) //?? - continue - held.screen_loc = slot.screen_loc - client.screen |= held - /mob/living/silicon/robot/put_in_hand_check(obj/item/item_equipping) return (item_equipping in model.modules) @@ -143,7 +126,7 @@ audible_message(span_warning("[src] sounds an alarm! \"SYSTEM ERROR: Module [module_num] OFFLINE.\"")) to_chat(src, span_userdanger("SYSTEM ERROR: Module [module_num] OFFLINE.")) - var/atom/movable/screen/robot/module_slot/module = hud_used?.screen_objects[HUD_KEY_CYBORG_MODULE(module_num)] + var/atom/movable/screen/robot/module_slot/module = hud_used?.screen_objects[HUD_KEY_HAND_SLOT(module_num)] if(module) module.icon_state = "[module.base_icon_state] +b" return TRUE @@ -188,7 +171,7 @@ disabled_modules &= ~BORG_MODULE_THREE_DISABLED to_chat(src, span_notice("ERROR CLEARED: Module [module_num] back online.")) - var/atom/movable/screen/robot/module_slot/module = hud_used?.screen_objects[HUD_KEY_CYBORG_MODULE(module_num)] + var/atom/movable/screen/robot/module_slot/module = hud_used?.screen_objects[HUD_KEY_HAND_SLOT(module_num)] if(module) module.icon_state = module.base_icon_state return TRUE @@ -270,10 +253,11 @@ if(is_invalid_module_number(module_num) || !held_items[module_num]) //If the slot number is invalid, or there's nothing there, we have nothing to equip return FALSE - var/atom/movable/screen/robot/module_slot/module = hud_used?.screen_objects[HUD_KEY_CYBORG_MODULE(module_num)] + var/atom/movable/screen/robot/module_slot/module = hud_used?.screen_objects[HUD_KEY_HAND_SLOT(module_num)] if(module && module_active != held_items[module_num]) module.icon_state = "[module.base_icon_state] +a" module_active = held_items[module_num] + SEND_SIGNAL(module_active, COMSIG_SILICON_MODULE_ACTIVATION, TRUE) return TRUE /** @@ -282,9 +266,11 @@ * * module_num - the slot number being de-selected */ /mob/living/silicon/robot/proc/deselect_module(module_num) - var/atom/movable/screen/robot/module_slot/module = hud_used?.screen_objects[HUD_KEY_CYBORG_MODULE(module_num)] + var/atom/movable/screen/robot/module_slot/module = hud_used?.screen_objects[HUD_KEY_HAND_SLOT(module_num)] if(module) module.icon_state = module.base_icon_state + if(module_active) + SEND_SIGNAL(module_active, COMSIG_SILICON_MODULE_ACTIVATION, FALSE) module_active = null return TRUE diff --git a/code/modules/mob/living/silicon/robot/robot_model.dm b/code/modules/mob/living/silicon/robot/robot_model.dm index b39359c9bfe..261f862feb8 100644 --- a/code/modules/mob/living/silicon/robot/robot_model.dm +++ b/code/modules/mob/living/silicon/robot/robot_model.dm @@ -427,7 +427,6 @@ /obj/item/crowbar/cyborg/power, // Skyrat ADDITION - Combines Crowbar and Wirecutters into one /obj/item/multitool/cyborg, //Skyrat ADDITION - Adds multitool for easier access /obj/item/borg/cyborg_omnitool/engineering, - ///obj/item/borg/cyborg_omnitool/engineering, //Skyrat REMOVAL /obj/item/t_scanner, /obj/item/analyzer, /obj/item/holosign_creator/atmos, // Skyrat Edit - Adds Holofans to engineering borgos @@ -690,6 +689,9 @@ if(reagents.has_reagent(amount = 1, chemical_flags = REAGENT_CLEANS)) our_turf.wash(CLEAN_SCRUB) + var/datum/component/bloodysoles/bot/trackfilth = robot_owner.GetComponent(/datum/component/bloodysoles/bot) + if(trackfilth) + trackfilth.change_blood_amount(-trackfilth.total_bloodiness) reagents.expose(our_turf, TOUCH, min(1, 10 / reagents.total_volume)) // We use more water doing this then mopping @@ -1017,7 +1019,6 @@ /obj/item/pipe_dispenser, /obj/item/restraints/handcuffs/cable/zipties, /obj/item/extinguisher, - /obj/item/weldingtool/largetank/cyborg, /obj/item/analyzer, /obj/item/borg/cyborg_omnitool/engineering, /obj/item/borg/cyborg_omnitool/engineering, diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index d612d1cd336..3640d99a99a 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -489,7 +489,7 @@ create_modularInterface() var/mob/living/silicon/robot/robo = modularInterface.silicon_owner if(istype(robo)) - modularInterface.borglog += "[station_time_timestamp()] - [string]" + modularInterface.borglog += "[round_timestamp()] - [string]" var/datum/computer_file/program/robotact/program = modularInterface.get_robotact() if(program) var/datum/tgui/active_ui = SStgui.get_open_ui(src, program.computer) diff --git a/code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm b/code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm deleted file mode 100644 index ee7e53b7141..00000000000 --- a/code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm +++ /dev/null @@ -1,146 +0,0 @@ -/mob/living/simple_animal/bot/secbot/grievous //This bot is powerful. If you managed to get 4 eswords somehow, you deserve this horror. Emag him for best results. - name = "General Beepsky" - desc = "Is that a secbot with four eswords in its arms...?" - icon = 'icons/mob/silicon/aibots.dmi' - icon_state = "grievous" - health = 150 - maxHealth = 150 - - baton_type = /obj/item/melee/energy/sword/saber - base_speed = 4 //he's a fast fucker - weapon_force = 30 - - var/block_chance = 50 - -/mob/living/simple_animal/bot/secbot/grievous/Initialize(mapload) - . = ..() - RegisterSignal(src, COMSIG_ATOM_PRE_BULLET_ACT, PROC_REF(block_bullets)) - -/mob/living/simple_animal/bot/secbot/grievous/toy //A toy version of general beepsky! - name = "Genewul Bweepskee" - desc = "An adorable looking secbot with four toy swords taped to its arms" - health = 50 - maxHealth = 50 - baton_type = /obj/item/toy/sword - weapon_force = 0 - -/mob/living/simple_animal/bot/secbot/grievous/proc/block_bullets(datum/source, obj/projectile/hitting_projectile) - SIGNAL_HANDLER - - if(stat != CONSCIOUS) - return NONE - - visible_message(span_warning("[source] deflects [hitting_projectile] with its energy swords!")) - playsound(source, 'sound/items/weapons/blade1.ogg', 50, TRUE) - return COMPONENT_BULLET_BLOCKED - -/mob/living/simple_animal/bot/secbot/grievous/on_entered(datum/source, atom/movable/AM) - . = ..() - if(ismob(AM) && AM == target) - visible_message(span_warning("[src] flails his swords and cuts [AM]!")) - playsound(src,'sound/mobs/non-humanoids/beepsky/beepskyspinsabre.ogg',100,TRUE,-1) - INVOKE_ASYNC(src, PROC_REF(stun_attack), AM) - -/mob/living/simple_animal/bot/secbot/grievous/Initialize(mapload) - . = ..() - INVOKE_ASYNC(weapon, TYPE_PROC_REF(/obj/item, attack_self), src) - -/mob/living/simple_animal/bot/secbot/grievous/Destroy() - QDEL_NULL(weapon) - return ..() - -/mob/living/simple_animal/bot/secbot/grievous/special_retaliate_after_attack(mob/user) - if(mode != BOT_HUNT) - return - if(prob(block_chance)) - visible_message(span_warning("[src] deflects [user]'s attack with his energy swords!")) - playsound(src, 'sound/items/weapons/blade1.ogg', 50, TRUE, -1) - return TRUE - -/mob/living/simple_animal/bot/secbot/grievous/stun_attack(mob/living/carbon/C) //Criminals don't deserve to live - weapon.attack(C, src) - playsound(src, 'sound/items/weapons/blade1.ogg', 50, TRUE, -1) - if(C.stat == DEAD) - addtimer(CALLBACK(src, TYPE_PROC_REF(/atom/, update_appearance)), 0.2 SECONDS) - back_to_idle() - - -/mob/living/simple_animal/bot/secbot/grievous/handle_automated_action() - if(!(bot_mode_flags & BOT_MODE_ON)) - return - switch(mode) - if(BOT_IDLE) // idle - update_appearance() - GLOB.move_manager.stop_looping(src) - look_for_perp() // see if any criminals are in range - if(!mode && bot_mode_flags & BOT_MODE_AUTOPATROL) // still idle, and set to patrol - mode = BOT_START_PATROL // switch to patrol mode - if(BOT_HUNT) // hunting for perp - update_appearance() - playsound(src,'sound/mobs/non-humanoids/beepsky/beepskyspinsabre.ogg',100,TRUE,-1) - // general beepsky doesn't give up so easily, jedi scum - if(frustration >= 20) - GLOB.move_manager.stop_looping(src) - back_to_idle() - return - if(target) // make sure target exists - if(Adjacent(target) && isturf(target.loc)) // if right next to perp - target_lastloc = target.loc //stun_attack() can clear the target if they're dead, so this needs to be set first - stun_attack(target) - set_anchored(TRUE) - return - else // not next to perp - var/turf/olddist = get_dist(src, target) - GLOB.move_manager.move_to(src, target, 1, 4) - if((get_dist(src, target)) >= (olddist)) - frustration++ - else - frustration = 0 - else - back_to_idle() - - if(BOT_START_PATROL) - look_for_perp() - start_patrol() - - if(BOT_PATROL) - look_for_perp() - bot_patrol() - -/mob/living/simple_animal/bot/secbot/grievous/look_for_perp() - set_anchored(FALSE) - var/judgement_criteria = judgement_criteria() - for (var/mob/living/carbon/C in view(7,src)) //Let's find us a criminal - if((C.stat) || (C.handcuffed)) - continue - - if((C.name == oldtarget_name) && (world.time < last_found + 100)) - continue - - threatlevel = C.assess_threat(judgement_criteria) - - if (threatlevel < THREAT_ASSESS_DANGEROUS) - continue - target = C - oldtarget_name = C.name - speak("Level [threatlevel] infraction alert!") - playsound(src, pick( - 'sound/mobs/non-humanoids/beepsky/criminal.ogg', - 'sound/mobs/non-humanoids/beepsky/justice.ogg', - 'sound/mobs/non-humanoids/beepsky/freeze.ogg', - ), 50, FALSE) - playsound(src,'sound/items/weapons/saberon.ogg',50,TRUE,-1) - visible_message(span_warning("[src] ignites his energy swords!")) - icon_state = "grievous-c" - visible_message("[src] points at [C.name]!") - mode = BOT_HUNT - INVOKE_ASYNC(src, PROC_REF(handle_automated_action)) - break - -/mob/living/simple_animal/bot/secbot/grievous/explode() - var/atom/Tsec = drop_location() - //Parent is dropping the weapon, so let's drop 3 more to make up for it. - for(var/dropped_weapons = 0 to 3) - drop_part(weapon, Tsec) - - return ..() diff --git a/code/modules/mob/living/simple_animal/bot/construction.dm b/code/modules/mob/living/simple_animal/bot/construction.dm index ec18b3d51ec..97b0753fcde 100644 --- a/code/modules/mob/living/simple_animal/bot/construction.dm +++ b/code/modules/mob/living/simple_animal/bot/construction.dm @@ -198,8 +198,8 @@ to_chat(user, span_notice("You start attaching the gun to the frame...")) if(!tool.use_tool(src, user, 40, volume=100)) return ITEM_INTERACT_BLOCKING - var/mob/living/simple_animal/bot/secbot/ed209/B = new(drop_location()) - B.name = created_name + var/mob/living/basic/bot/secbot/ed209/new_bot = new(drop_location()) + new_bot.name = created_name to_chat(user, span_notice("You complete the ED-209.")) qdel(src) return ITEM_INTERACT_SUCCESS @@ -347,7 +347,7 @@ if(!can_finish_build(tool, user)) return ITEM_INTERACT_BLOCKING to_chat(user, span_notice("You add the [tool] to [src]! Honk!")) - var/mob/living/basic/bot/honkbot/new_honkbot = new(drop_location()) + var/mob/living/basic/bot/secbot/honkbot/new_honkbot = new(drop_location()) new_honkbot.name = created_name playsound(new_honkbot, 'sound/machines/ping.ogg', 50, TRUE, -1) qdel(tool) @@ -437,10 +437,10 @@ if(!can_finish_build(tool, user)) return ITEM_INTERACT_BLOCKING to_chat(user, span_notice("You complete the Securitron! Beep boop.")) - var/mob/living/simple_animal/bot/secbot/S = new(drop_loc) - S.name = created_name - S.baton_type = tool.type - S.robot_arm = robot_arm + var/mob/living/basic/bot/secbot/new_bot = new(drop_loc) + new_bot.name = created_name + new_bot.baton_type = tool.type + new_bot.robot_arm = robot_arm qdel(tool) qdel(src) return ITEM_INTERACT_SUCCESS @@ -482,9 +482,9 @@ return ITEM_INTERACT_BLOCKING to_chat(user, span_notice("You complete the Securitron!...Something seems a bit wrong with it..?")) - var/mob/living/simple_animal/bot/secbot/grievous/toy/S = new(drop_loc) - S.name = created_name - S.robot_arm = robot_arm + var/mob/living/basic/bot/secbot/grievous/toy/new_bot = new(drop_loc) + new_bot.name = created_name + new_bot.robot_arm = robot_arm qdel(tool) qdel(src) return ITEM_INTERACT_SUCCESS @@ -517,9 +517,9 @@ return ITEM_INTERACT_BLOCKING to_chat(user, span_notice("You complete the Securitron!...Something seems a bit wrong with it..?")) - var/mob/living/simple_animal/bot/secbot/grievous/S = new(drop_loc) - S.name = created_name - S.robot_arm = robot_arm + var/mob/living/basic/bot/secbot/grievous/new_bot = new(drop_loc) + new_bot.name = created_name + new_bot.robot_arm = robot_arm qdel(tool) qdel(src) return ITEM_INTERACT_SUCCESS diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm deleted file mode 100644 index 945d0c2eba9..00000000000 --- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm +++ /dev/null @@ -1,138 +0,0 @@ -/mob/living/simple_animal/bot/secbot/ed209 - name = "\improper ED-209 Security Robot" - desc = "A security robot. He looks less than thrilled." - icon_state = "ed209" - light_color = "#f84e4e" - density = TRUE - health = 100 - maxHealth = 100 - obj_damage = 60 - environment_smash = ENVIRONMENT_SMASH_WALLS //Walls can't stop THE LAW - mob_size = MOB_SIZE_LARGE - - bot_type = ADVANCED_SEC_BOT - hackables = "combat inhibitors" - - automated_announcements = list(ED209_VOICED_DOWN_WEAPONS = 'sound/mobs/non-humanoids/ed209/ed209_20sec.ogg') - - custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 2.8, /datum/material/glass = SMALL_MATERIAL_AMOUNT * 2.1) - - var/lastfired = 0 - var/shot_delay = 1.5 SECONDS - var/shoot_sound = 'sound/items/weapons/laser.ogg' - var/projectile = /obj/projectile/beam/disabler - var/fair_market_projectile = /obj/projectile/bullet/c38 // For shooting the worst scumbags of all: the poor - -/mob/living/simple_animal/bot/secbot/ed209/Initialize(mapload) - . = ..() - set_weapon() //giving it the right projectile and firing sound. - - AddComponent(/datum/component/defaceable, \ - icon = 'icons/mob/silicon/aibot_faces.dmi', \ - icon_states = list("ed209" = FALSE, "ed209_highlight" = TRUE), \ - drawing_of = "a face", \ - ) - -/mob/living/simple_animal/bot/secbot/ed209/bot_reset() - ..() - set_weapon() - -/mob/living/simple_animal/bot/secbot/ed209/emag_act(mob/user, obj/item/card/emag/emag_card) - . = ..() - icon_state = "ed209[get_bot_flag(bot_mode_flags, BOT_MODE_ON)]" - set_weapon() - balloon_alert(user, "safeties disabled") - audible_message(span_bolddanger("[src] buzzes menacingly!")) - return TRUE - -/mob/living/simple_animal/bot/secbot/ed209/handle_automated_action() - var/judgement_criteria = judgement_criteria() - var/list/targets = list() - for(var/mob/living/carbon/nearby_carbon in view(7, src)) //Let's find us a target - var/threatlevel = 0 - if(nearby_carbon.incapacitated) - continue - threatlevel = nearby_carbon.assess_threat(judgement_criteria) - if(threatlevel < THREAT_ASSESS_DANGEROUS) - continue - var/dst = get_dist(src, nearby_carbon) - if(dst <= 1 || dst > 7) - continue - targets += nearby_carbon - if(targets.len > 0) - var/mob/living/carbon/all_targets = pick(targets) - if(all_targets.stat != DEAD && !all_targets.handcuffed) //we don't shoot people who are dead, cuffed or lying down. - shoot_at(all_targets) - ..() - -/mob/living/simple_animal/bot/secbot/ed209/threat_react(threatlevel) - speak("Level [threatlevel] infraction alert!") - playsound(src, pick( - 'sound/mobs/non-humanoids/ed209/ed209_20sec.ogg', - 'sound/mobs/non-humanoids/ed209/edplaceholder.ogg', - ), 50, FALSE) - -/mob/living/simple_animal/bot/secbot/ed209/proc/set_weapon() //used to update the projectile type and firing sound - shoot_sound = 'sound/items/weapons/laser.ogg' - if(bot_cover_flags & BOT_COVER_EMAGGED) - projectile = /obj/projectile/beam - else - projectile = /obj/projectile/beam/disabler - -/mob/living/simple_animal/bot/secbot/ed209/proc/shoot_at(mob/target) - if(world.time <= lastfired + shot_delay) - return - lastfired = world.time - var/turf/T = loc - var/turf/U = get_turf(target) - if(!U) - return - if(!isturf(T)) - return - if(!projectile) - return - - var/obj/projectile/fired_bullet = new projectile(loc) - playsound(src, shoot_sound, 50, TRUE) - fired_bullet.aim_projectile(target, src) - fired_bullet.fire() - -/mob/living/simple_animal/bot/secbot/ed209/emp_act(severity) - if(severity == 2 && prob(70)) - severity = 1 - . = ..() - if(. & EMP_PROTECT_SELF) - return - if(severity <= 1) - return - new /obj/effect/temp_visual/emp(loc) - var/list/mob/living/carbon/targets = list() - for(var/mob/living/carbon/nearby_carbons in view(12,src)) - if(nearby_carbons.stat == DEAD) - continue - targets += nearby_carbons - if(!targets.len) - return - if(prob(50)) - var/mob/toshoot = pick(targets) - if(toshoot) - targets -= toshoot - if(prob(50) && !(bot_cover_flags & BOT_COVER_EMAGGED)) // Temporarily emags it - bot_cover_flags |= BOT_COVER_EMAGGED - set_weapon() - shoot_at(toshoot) - bot_cover_flags &= ~BOT_COVER_EMAGGED - set_weapon() - else - shoot_at(toshoot) - else if(prob(50)) - if(targets.len) - var/mob/to_arrest = pick(targets) - if(to_arrest) - target = to_arrest - mode = BOT_HUNT - -/mob/living/simple_animal/bot/secbot/ed209/RangedAttack(atom/A) - if(!(bot_mode_flags & BOT_MODE_ON)) - return - shoot_at(A) diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm deleted file mode 100644 index 67796f179e0..00000000000 --- a/code/modules/mob/living/simple_animal/bot/secbot.dm +++ /dev/null @@ -1,596 +0,0 @@ -/mob/living/simple_animal/bot/secbot - name = "\improper Securitron" - desc = "A little security robot. He looks less than thrilled." - icon = 'icons/mob/silicon/aibots.dmi' - icon_state = "secbot" - light_color = "#f56275" - light_power = 0.8 - gender = MALE - density = FALSE - anchored = FALSE - health = 25 - maxHealth = 25 - damage_coeff = list(BRUTE = 0.5, BURN = 0.7, TOX = 0, STAMINA = 0, OXY = 0) - pass_flags = PASSMOB | PASSFLAPS - combat_mode = TRUE - can_buckle_to = FALSE - - req_one_access = list(ACCESS_SECURITY) - radio_key = /obj/item/encryptionkey/secbot //AI Priv + Security - radio_channel = RADIO_CHANNEL_SECURITY //Security channel - bot_type = SEC_BOT - bot_mode_flags = ~BOT_MODE_CAN_BE_SAPIENT - data_hud_type = TRAIT_SECURITY_HUD - hackables = "target identification systems" - path_image_color = COLOR_RED - possessed_message = "You are a securitron! Guard the station to the best of your ability!" - - automated_announcements = list( - BEEPSKY_VOICED_CRIMINAL_DETECTED = 'sound/mobs/non-humanoids/beepsky/criminal.ogg', - BEEPSKY_VOICED_FREEZE = 'sound/mobs/non-humanoids/beepsky/freeze.ogg', - BEEPSKY_VOICED_JUSTICE = 'sound/mobs/non-humanoids/beepsky/justice.ogg', - BEEPSKY_VOICED_YOUR_MOVE = 'sound/mobs/non-humanoids/beepsky/creep.ogg', - BEEPSKY_VOICED_I_AM_THE_LAW = 'sound/mobs/non-humanoids/beepsky/iamthelaw.ogg', - BEEPSKY_VOICED_SECURE_DAY = 'sound/mobs/non-humanoids/beepsky/secureday.ogg', - ) - - custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 1.2, /datum/material/glass = SMALL_MATERIAL_AMOUNT * 3.2) - - ///Whether this secbot is considered 'commissioned' and given the trait on Initialize. - var/commissioned = FALSE - ///The type of baton this Secbot will use - var/baton_type = /obj/item/melee/baton/security - ///The type of cuffs we use on criminals after making arrests - var/cuff_type = /obj/item/restraints/handcuffs/cable/zipties/used - ///The weapon (from baton_type) that will be used to make arrests. - var/obj/item/weapon - ///Their current target - var/mob/living/carbon/target - ///Name of their last target to prevent spamming - var/oldtarget_name - ///The threat level of the BOT, will arrest anyone at threatlevel 4 or above - var/threatlevel = 0 - ///The last location their target was seen at - var/target_lastloc - ///Time since last seeing their perpetrator - var/last_found - - ///Flags SecBOTs use on what to check on targets when arresting, and whether they should announce it to security/handcuff their target - var/security_mode_flags = SECBOT_DECLARE_ARRESTS | SECBOT_CHECK_RECORDS | SECBOT_HANDCUFF_TARGET -// Selections: SECBOT_DECLARE_ARRESTS | SECBOT_CHECK_IDS | SECBOT_CHECK_WEAPONS | SECBOT_CHECK_RECORDS | SECBOT_HANDCUFF_TARGET - - /// On arrest, charges the violator this much. - /// If they don't have that much in their account, they will get beaten instead - var/price_arrest = 0 - /// Charged each time the violator is stunned on detain - var/price_detain = 0 - ///Force of the harmbaton used on them - var/weapon_force = 20 - ///The department the secbot will deposit collected money into - var/payment_department = ACCOUNT_SEC - -/mob/living/simple_animal/bot/secbot/beepsky - name = "Commander Beep O'sky" - desc = "It's Commander Beep O'sky! Officially the superior officer of all bots on station, Beepsky remains as humble and dedicated to the law as the day he was first fabricated." - bot_mode_flags = BOT_MODE_ON | BOT_MODE_AUTOPATROL | BOT_MODE_REMOTE_ENABLED - commissioned = TRUE - - -/mob/living/simple_animal/bot/secbot/beepsky/officer - name = "Officer Beepsky" - desc = "It's Officer Beepsky! Powered by a potato and a shot of whiskey, and with a sturdier reinforced chassis, too." - health = 45 - -/mob/living/simple_animal/bot/secbot/beepsky/officer/Initialize(mapload) - . = ..() - // Beepsky hates people scanning them - RegisterSignal(src, COMSIG_MOVABLE_SPY_STEALING, PROC_REF(retaliate_async)) - -/mob/living/simple_animal/bot/secbot/beepsky/ofitser - name = "Prison Ofitser" - desc = "Powered by the tears and sweat of laborers." - bot_mode_flags = ~(BOT_MODE_CAN_BE_SAPIENT|BOT_MODE_AUTOPATROL) - -/mob/living/simple_animal/bot/secbot/beepsky/armsky - name = "Sergeant-At-Armsky" - desc = "It's Sergeant-At-Armsky! He's a disgruntled assistant to the warden that would probably shoot you if he had hands." - health = 45 - bot_mode_flags = ~(BOT_MODE_CAN_BE_SAPIENT|BOT_MODE_AUTOPATROL) - security_mode_flags = SECBOT_DECLARE_ARRESTS | SECBOT_CHECK_IDS | SECBOT_CHECK_RECORDS | SECBOT_CHECK_WEAPONS - -/mob/living/simple_animal/bot/secbot/beepsky/jr - name = "Officer Pipsqueak" - desc = "It's Commander Beep O'sky's smaller, just-as aggressive cousin, Pipsqueak." - commissioned = FALSE - -/mob/living/simple_animal/bot/secbot/beepsky/jr/Initialize(mapload) - . = ..() - update_transform(0.8) - -/mob/living/simple_animal/bot/secbot/pingsky - name = "Officer Pingsky" - desc = "It's Officer Pingsky! Delegated to satellite guard duty for harbouring anti-human sentiment." - light_color = "#62baf5" - radio_channel = RADIO_CHANNEL_AI_PRIVATE - bot_mode_flags = ~(BOT_MODE_CAN_BE_SAPIENT|BOT_MODE_AUTOPATROL) - security_mode_flags = SECBOT_DECLARE_ARRESTS | SECBOT_CHECK_IDS | SECBOT_CHECK_RECORDS - -/mob/living/simple_animal/bot/secbot/genesky - name = "Officer Genesky" - desc = "A beefy variant of the standard securitron model." - health = 50 - faction = list(FACTION_NANOTRASEN_PRIVATE) - bot_mode_flags = BOT_MODE_ON - bot_cover_flags = BOT_COVER_LOCKED | BOT_COVER_EMAGGED - -/mob/living/simple_animal/bot/secbot/beepsky/explode() - var/atom/Tsec = drop_location() - new /obj/item/stock_parts/power_store/cell/potato(Tsec) - var/obj/item/reagent_containers/cup/glass/drinkingglass/shotglass/drinking_oil = new(Tsec) - drinking_oil.reagents.add_reagent(/datum/reagent/consumable/ethanol/whiskey, 15) - return ..() - -/mob/living/simple_animal/bot/secbot/Initialize(mapload) - . = ..() - weapon = new baton_type() - update_appearance(UPDATE_ICON) - if(commissioned) - ADD_TRAIT(src, TRAIT_COMMISSIONED, INNATE_TRAIT) - - // Doing this hurts my soul, but simplebot access reworks are for another day. - var/datum/id_trim/job/det_trim = SSid_access.trim_singletons_by_path[/datum/id_trim/job/detective] - access_card.add_access(det_trim.access + det_trim.wildcard_access) - prev_access = access_card.access.Copy() - - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_entered), - ) - AddElement(/datum/element/connect_loc, loc_connections) - AddComponent(/datum/component/security_vision, judgement_criteria = NONE, update_judgement_criteria = CALLBACK(src, PROC_REF(judgement_criteria))) - -/mob/living/simple_animal/bot/secbot/Destroy() - QDEL_NULL(weapon) - return ..() - -/mob/living/simple_animal/bot/secbot/update_icon_state() - if(mode == BOT_HUNT) - icon_state = "[initial(icon_state)]-c" - return - return ..() - -/mob/living/simple_animal/bot/secbot/turn_off() - ..() - mode = BOT_IDLE - -/mob/living/simple_animal/bot/secbot/bot_reset() - ..() - target = null - oldtarget_name = null - set_anchored(FALSE) - GLOB.move_manager.stop_looping(src) - last_found = world.time - -/mob/living/simple_animal/bot/secbot/on_saboteur(datum/source, disrupt_duration) - . = ..() - if(!(security_mode_flags & SECBOT_SABOTEUR_AFFECTED)) - security_mode_flags |= SECBOT_SABOTEUR_AFFECTED - addtimer(CALLBACK(src, PROC_REF(remove_saboteur_effect)), disrupt_duration) - return TRUE - -/mob/living/simple_animal/bot/secbot/proc/remove_saboteur_effect() - security_mode_flags &= ~SECBOT_SABOTEUR_AFFECTED - -/mob/living/simple_animal/bot/secbot/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)//shocks only make him angry - if(base_speed < initial(base_speed) + 3) - base_speed += 3 - addtimer(VARSET_CALLBACK(src, base_speed, base_speed - 3), 6 SECONDS) - playsound(src, 'sound/machines/defib/defib_zap.ogg', 50) - visible_message(span_warning("[src] shakes and speeds up!")) - -/mob/living/simple_animal/bot/secbot/Exited(atom/movable/gone, direction) - . = ..() - if(gone == weapon) - weapon = null - update_appearance() - -// Variables sent to TGUI -/mob/living/simple_animal/bot/secbot/ui_data(mob/user) - var/list/data = ..() - if(!(bot_cover_flags & BOT_COVER_LOCKED) || HAS_SILICON_ACCESS(user)) - data["custom_controls"]["check_id"] = security_mode_flags & SECBOT_CHECK_IDS - data["custom_controls"]["check_weapons"] = security_mode_flags & SECBOT_CHECK_WEAPONS - data["custom_controls"]["check_warrants"] = security_mode_flags & SECBOT_CHECK_RECORDS - data["custom_controls"]["handcuff_targets"] = security_mode_flags & SECBOT_HANDCUFF_TARGET - data["custom_controls"]["arrest_alert"] = security_mode_flags & SECBOT_DECLARE_ARRESTS - return data - -// Actions received from TGUI -/mob/living/simple_animal/bot/secbot/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) - . = ..() - var/mob/user = ui.user - if(. || (bot_cover_flags & BOT_COVER_LOCKED && !HAS_SILICON_ACCESS(user))) - return - - switch(action) - if("check_id") - security_mode_flags ^= SECBOT_CHECK_IDS - if("check_weapons") - security_mode_flags ^= SECBOT_CHECK_WEAPONS - if("check_warrants") - security_mode_flags ^= SECBOT_CHECK_RECORDS - if("handcuff_targets") - security_mode_flags ^= SECBOT_HANDCUFF_TARGET - if("arrest_alert") - security_mode_flags ^= SECBOT_DECLARE_ARRESTS - -/mob/living/simple_animal/bot/secbot/proc/retaliate_async(datum/source, mob/user, ...) - SIGNAL_HANDLER - - INVOKE_ASYNC(src, PROC_REF(retaliate), user) - -/mob/living/simple_animal/bot/secbot/proc/retaliate(mob/living/carbon/human/attacking_human) - var/judgement_criteria = judgement_criteria() - threatlevel = attacking_human.assess_threat(judgement_criteria) - threatlevel += 6 - if(threatlevel >= THREAT_ASSESS_DANGEROUS) - target = attacking_human - mode = BOT_HUNT - if(threatlevel < 0 && prob(5)) - manual_emote("salutes.") - speak("Thank you sir.") - -/mob/living/simple_animal/bot/secbot/proc/judgement_criteria() - var/final = FALSE - if(bot_cover_flags & BOT_COVER_EMAGGED) - final |= JUDGE_EMAGGED - if(security_mode_flags & SECBOT_CHECK_IDS) - final |= JUDGE_IDCHECK - if(security_mode_flags & SECBOT_CHECK_RECORDS) - final |= JUDGE_RECORDCHECK - if(security_mode_flags & SECBOT_CHECK_WEAPONS) - final |= JUDGE_WEAPONCHECK - if(security_mode_flags & SECBOT_SABOTEUR_AFFECTED) - final |= JUDGE_CHILLOUT - return final - -/mob/living/simple_animal/bot/secbot/proc/special_retaliate_after_attack(mob/user) //allows special actions to take place after being attacked. - return - -/mob/living/simple_animal/bot/secbot/attack_hand(mob/living/carbon/human/user, list/modifiers) - if(user.combat_mode) - retaliate(user) - if(special_retaliate_after_attack(user)) - return - - // Turns an oversight into a feature. Beepsky will now announce when pacifists taunt him over sec comms. - if(HAS_TRAIT(user, TRAIT_PACIFISM)) - user.visible_message(span_notice("[user] taunts [src], daring [p_them()] to give chase!"), \ - span_notice("You taunt [src], daring [p_them()] to chase you!"), span_hear("You hear someone shout a daring taunt!"), DEFAULT_MESSAGE_RANGE, user) - speak("Taunted by pacifist scumbag [RUNECHAT_BOLD("[user]")] in [get_area(src)].", radio_channel) - - // Interrupt the attack chain. We've already handled this scenario for pacifists. - return - - return ..() - -/mob/living/simple_animal/bot/secbot/attackby(obj/item/attacking_item, mob/living/user, list/modifiers, list/attack_modifiers) - ..() - if(!(bot_mode_flags & BOT_MODE_ON)) // Bots won't remember if you hit them while they're off. - return - if(attacking_item.tool_behaviour == TOOL_WELDER && !user.combat_mode) // Any intent but harm will heal, so we shouldn't get angry. - return - if(attacking_item.tool_behaviour != TOOL_SCREWDRIVER && (attacking_item.force) && (!target) && (attacking_item.damtype != STAMINA)) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass. - retaliate(user) - special_retaliate_after_attack(user) - -/mob/living/simple_animal/bot/secbot/emag_act(mob/user, obj/item/card/emag/emag_card) - . = ..() - if(!(bot_cover_flags & BOT_COVER_EMAGGED)) - return - if(user) - balloon_alert(user, "target assessment circuits shorted") - oldtarget_name = user.name - - if(bot_type == HONK_BOT) - audible_message(span_danger("[src] gives out an evil laugh!")) - playsound(src, 'sound/mobs/non-humanoids/honkbot/honkbot_evil_laugh.ogg', 75, TRUE, -1) // evil laughter - else - audible_message(span_danger("[src] buzzes oddly!")) - - security_mode_flags &= ~SECBOT_DECLARE_ARRESTS - update_appearance() - return TRUE - -/mob/living/simple_animal/bot/secbot/bullet_act(obj/projectile/proj) - . = ..() - if(. != BULLET_ACT_HIT) - return - - if(istype(proj, /obj/projectile/beam) || istype(proj, /obj/projectile/bullet)) - if((proj.damage_type == BURN) || (proj.damage_type == BRUTE)) - if(proj.is_hostile_projectile() && proj.damage < src.health && ishuman(proj.firer)) - retaliate(proj.firer) - -/mob/living/simple_animal/bot/secbot/UnarmedAttack(atom/attack_target, proximity_flag, list/modifiers) - if(!(bot_mode_flags & BOT_MODE_ON)) - return - if(!can_unarmed_attack()) - return - if(!iscarbon(attack_target)) - return ..() - var/mob/living/carbon/carbon_target = attack_target - if(!carbon_target.IsParalyzed() || !(security_mode_flags & SECBOT_HANDCUFF_TARGET)) - stun_attack(attack_target, payment_check()) - else if(carbon_target.canBeHandcuffed() && !carbon_target.handcuffed) - start_handcuffing(attack_target) - -/mob/living/simple_animal/bot/secbot/hitby(atom/movable/hitting_atom, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) - if(isitem(hitting_atom)) - var/obj/item/item_hitby = hitting_atom - var/mob/thrown_by = throwingdatum?.get_thrower() - if(item_hitby.throwforce < src.health && thrown_by && ishuman(thrown_by)) - var/mob/living/carbon/human/human_throwee = thrown_by - retaliate(human_throwee) - ..() - -/mob/living/simple_animal/bot/secbot/proc/start_handcuffing(mob/living/carbon/current_target) - mode = BOT_ARREST - playsound(src, 'sound/items/weapons/cablecuff.ogg', 30, TRUE, -2) - current_target.visible_message(span_danger("[src] is trying to put zipties on [current_target]!"),\ - span_userdanger("[src] is trying to put zipties on you!")) - addtimer(CALLBACK(src, PROC_REF(handcuff_target), current_target), 6 SECONDS) - -/mob/living/simple_animal/bot/secbot/proc/handcuff_target(mob/living/carbon/current_target) - if(!(bot_mode_flags & BOT_MODE_ON)) //if he's in a closet or not adjacent, we cancel cuffing. - return FALSE - if(!isturf(current_target.loc)) - return FALSE - if(!Adjacent(current_target)) - return FALSE - if(!current_target.handcuffed) - current_target.set_handcuffed(new cuff_type(current_target)) - playsound(src, SFX_LAW, 50, FALSE) - back_to_idle() - -/mob/living/simple_animal/bot/secbot/proc/stun_attack(mob/living/carbon/current_target, harm = FALSE) - var/judgement_criteria = judgement_criteria() - playsound(src, 'sound/items/weapons/egloves.ogg', 50, TRUE, -1) - icon_state = "[initial(icon_state)]-c" - addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_appearance)), 0.2 SECONDS) - var/threat = 5 - - if(harm) - weapon.attack(current_target, src) - if(ishuman(current_target)) - current_target.set_stutter(10 SECONDS) - current_target.Paralyze(60) // SKYRAT EDIT CHANGE - original was current_target.Paralyze(100) - var/mob/living/carbon/human/human_target = current_target - threat = human_target.assess_threat(judgement_criteria) - else - current_target.Paralyze(60) // SKYRAT EDIT CHANGE - original was current_target.Paralyze(100) - current_target.set_stutter(10 SECONDS) - threat = current_target.assess_threat(judgement_criteria) - - log_combat(src, current_target, "stunned") - if(security_mode_flags & SECBOT_DECLARE_ARRESTS) - var/area/location = get_area(src) - speak("[security_mode_flags & SECBOT_HANDCUFF_TARGET ? "Arresting" : "Detaining"] level [threat] scumbag [RUNECHAT_BOLD("[current_target]")] in [location].", radio_channel) - current_target.visible_message(span_danger("[src] stuns [current_target]!"),\ - span_userdanger("[src] stuns you!")) - - target_lastloc = current_target.loc - mode = BOT_PREP_ARREST - -/mob/living/simple_animal/bot/secbot/handle_automated_action() - . = ..() - if(!.) - return - - switch(mode) - - if(BOT_IDLE) // idle - GLOB.move_manager.stop_looping(src) - look_for_perp() // see if any criminals are in range - if((mode == BOT_IDLE) && bot_mode_flags & BOT_MODE_AUTOPATROL) // didn't start hunting during look_for_perp, and set to patrol - mode = BOT_START_PATROL // switch to patrol mode - - if(BOT_HUNT) // hunting for perp - // if can't reach perp for long enough, go idle - if(frustration >= 8) - GLOB.move_manager.stop_looping(src) - back_to_idle() - return - - if(!target) // make sure target exists - back_to_idle() - return - if(Adjacent(target) && isturf(target.loc)) // if right next to perp - stun_attack(target, payment_check()) - set_anchored(TRUE) - return - - // not next to perp - var/turf/olddist = get_dist(src, target) - GLOB.move_manager.move_to(src, target, 1, 4) - if((get_dist(src, target)) >= (olddist)) - frustration++ - else - frustration = 0 - - if(BOT_PREP_ARREST) // preparing to arrest target - // see if he got away. If he's no no longer adjacent or inside a closet or about to get up, we hunt again. - if(!Adjacent(target) || !isturf(target.loc) || !HAS_TRAIT(target, TRAIT_FLOORED)) - back_to_hunt() - return - - if(!iscarbon(target) || !target.canBeHandcuffed()) - back_to_idle() - return - - if(security_mode_flags & SECBOT_HANDCUFF_TARGET) - if(!target.handcuffed) //he's not cuffed? Try to cuff him! - start_handcuffing(target) - else - back_to_idle() - return - - if(BOT_ARREST) - if(!target) - set_anchored(FALSE) - mode = BOT_IDLE - last_found = world.time - frustration = 0 - return - - if(target.handcuffed) // target is cuffed, mission accomplished - if(payment_check()) // try to fine them - give them a love tap if they fail - stun_attack(target, TRUE) - else // otherwise return to idle state - back_to_idle() - return - - if(!Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && !HAS_TRAIT(target, TRAIT_FLOORED))) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again. - back_to_hunt() - return - else //Try arresting again if the target escapes. - mode = BOT_PREP_ARREST - set_anchored(FALSE) - - if(BOT_START_PATROL) - look_for_perp() - start_patrol() - - if(BOT_PATROL) - look_for_perp() - bot_patrol() - -/mob/living/simple_animal/bot/secbot/proc/back_to_idle() - set_anchored(FALSE) - mode = BOT_IDLE - target = null - last_found = world.time - frustration = 0 - INVOKE_ASYNC(src, PROC_REF(handle_automated_action)) - -/mob/living/simple_animal/bot/secbot/proc/back_to_hunt() - set_anchored(FALSE) - frustration = 0 - mode = BOT_HUNT - INVOKE_ASYNC(src, PROC_REF(handle_automated_action)) -// look for a criminal in view of the bot - -/mob/living/simple_animal/bot/secbot/proc/look_for_perp() - set_anchored(FALSE) - var/judgement_criteria = judgement_criteria() - for(var/mob/living/carbon/nearby_carbons in view(7, src)) //Let's find us a criminal - if((nearby_carbons.stat) || (nearby_carbons.handcuffed)) - continue - - if((nearby_carbons.name == oldtarget_name) && (world.time < last_found + 100)) - continue - - //BUBBERSTATION CHANGE START: BEEPSKY IS A DINOSAUR NOW. CAN'T SEE YOU IF YOU DON'T MOVE. - if(nearby_carbons.client) //We have a client. We're a player that uses move_delay. - if(nearby_carbons.client.move_delay + 4 SECONDS <= world.time) - continue - else if(nearby_carbons.next_move + 4 SECONDS <= world.time) //No client. We're a mob that uses next_move. - continue - //BUBBERSTATION CHANGE END: BEEPSKY IS A DINOSAUR NOW. CAN'T SEE YOU IF YOU DON'T MOVE. - - threatlevel = nearby_carbons.assess_threat(judgement_criteria) - - if(threatlevel < THREAT_ASSESS_DANGEROUS) - continue - - target = nearby_carbons - oldtarget_name = nearby_carbons.name - threat_react(threatlevel) - visible_message("[src] points at [nearby_carbons.name]!") - mode = BOT_HUNT - INVOKE_ASYNC(src, PROC_REF(handle_automated_action)) - break - -/// React to detecting criminal scum by making some kind of noise -/mob/living/simple_animal/bot/secbot/proc/threat_react(threatlevel) - speak("Level [threatlevel] infraction alert!") - playsound(src, pick( - 'sound/mobs/non-humanoids/beepsky/criminal.ogg', - 'sound/mobs/non-humanoids/beepsky/justice.ogg', - 'sound/mobs/non-humanoids/beepsky/freeze.ogg', - ), 50, FALSE) - -/mob/living/simple_animal/bot/secbot/explode() - var/atom/Tsec = drop_location() - switch(bot_type) - if(ADVANCED_SEC_BOT) - var/obj/item/bot_assembly/ed209/ed_assembly = new(Tsec) - ed_assembly.build_step = ASSEMBLY_FIRST_STEP - ed_assembly.add_overlay("hs_hole") - ed_assembly.created_name = name - new /obj/item/assembly/prox_sensor(Tsec) - var/obj/item/gun/energy/disabler/disabler_gun = new(Tsec) - disabler_gun.cell.charge = 0 - disabler_gun.update_appearance() - if(prob(50)) - new /obj/item/bodypart/leg/left/robot(Tsec) - if(prob(25)) - new /obj/item/bodypart/leg/right/robot(Tsec) - if(prob(25))//50% chance for a helmet OR vest - if(prob(50)) - new /obj/item/clothing/head/helmet(Tsec) - else - new /obj/item/clothing/suit/armor/vest(Tsec) - if(HONK_BOT) - var/obj/item/bot_assembly/honkbot/honkbot_assembly = new(Tsec) - honkbot_assembly.build_step = ASSEMBLY_FIRST_STEP - honkbot_assembly.created_name = name - new /obj/item/assembly/prox_sensor(Tsec) - drop_part(baton_type, Tsec) - else - var/obj/item/bot_assembly/secbot/secbot_assembly = new(Tsec) - secbot_assembly.build_step = ASSEMBLY_FIRST_STEP - secbot_assembly.add_overlay("hs_hole") - secbot_assembly.created_name = name - new /obj/item/assembly/prox_sensor(Tsec) - drop_part(baton_type, Tsec) - - new /obj/effect/decal/cleanable/blood/oil(loc) - return ..() - -/mob/living/simple_animal/bot/secbot/attack_alien(mob/living/carbon/alien/user, list/modifiers) - . = ..() - if(!isalien(target)) - target = user - mode = BOT_HUNT - -/mob/living/simple_animal/bot/secbot/proc/on_entered(datum/source, atom/movable/AM) - SIGNAL_HANDLER - if(has_gravity() && ismob(AM) && target) - var/mob/living/carbon/C = AM - if(!istype(C) || !C || in_range(src, target)) - return - knockOver(C) - -/// Returns true if the current target is unable to pay to be detained/arrested -/mob/living/simple_animal/bot/secbot/proc/payment_check() - var/fair_market_price = (security_mode_flags & SECBOT_HANDCUFF_TARGET) ? price_arrest : price_detain - if(fair_market_price <= 0) - return FALSE - if(!ishuman(target)) - return FALSE - var/mob/living/carbon/human/human_target = target - var/obj/item/card/id/target_id = human_target.get_idcard() - if(!target_id) - say("Unable to pay fine: No ID card found.") - return TRUE - var/datum/bank_account/insurance = target_id.registered_account - if(!insurance) - say("Unable to pay fine: No bank account found.") - return TRUE - if(!insurance.adjust_money(-fair_market_price, "Securitron fine")) - say("Unable to pay fine: Not enough funds in account.") - return TRUE - - SSeconomy.get_dep_account(payment_department)?.adjust_money(fair_market_price) - say("Fine paid: Thank you for your compliance. Your account been charged [fair_market_price] [MONEY_NAME].") - return FALSE diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm index d62fa709e77..fd4c4d58a96 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm @@ -230,19 +230,19 @@ min_damage = 30 max_damage = 35 -/obj/effect/goliath_tentacle/broodmother/patch/Initialize(mapload, new_spawner) +/obj/effect/goliath_tentacle/broodmother/patch/Initialize(mapload, mob/living/goliath) . = ..() INVOKE_ASYNC(src, PROC_REF(createpatch)) /obj/effect/goliath_tentacle/broodmother/patch/proc/createpatch() var/tentacle_locs = spiral_range_turfs(1, get_turf(src)) for(var/T in tentacle_locs) - new /obj/effect/goliath_tentacle/broodmother(T) + new /obj/effect/goliath_tentacle/broodmother(T, owner) var/list/directions = GLOB.cardinals.Copy() for(var/i in directions) var/turf/T = get_step(get_turf(src), i) T = get_step(T, i) - new /obj/effect/goliath_tentacle/broodmother(T) + new /obj/effect/goliath_tentacle/broodmother(T, owner) #undef CALL_CHILDREN #undef RAGE diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 46f5958cc17..f0531f0a1b8 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -475,17 +475,6 @@ . = ..() update_held_items() -/mob/living/simple_animal/update_held_items() - . = ..() - if(!client || !hud_used || hud_used.hud_version == HUD_STYLE_NOHUD) - return - var/turf/our_turf = get_turf(src) - for(var/obj/item/I in held_items) - var/index = get_held_index_of_item(I) - SET_PLANE(I, ABOVE_HUD_PLANE, our_turf) - I.screen_loc = ui_hand_position(index) - client.screen |= I - //ANIMAL RIDING /mob/living/simple_animal/user_buckle_mob(mob/living/M, mob/user, check_loc = TRUE) diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm index 359ac2c56f2..2c5f0af4451 100644 --- a/code/modules/mob/living/status_procs.dm +++ b/code/modules/mob/living/status_procs.dm @@ -513,20 +513,17 @@ REMOVE_TRAIT(src, TRAIT_HUSK, source) if(HAS_TRAIT(src, TRAIT_HUSK)) return FALSE - update_body() UnregisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_UNHUSKABLE)) return TRUE /mob/living/proc/become_husk(source) if(HAS_TRAIT(src, TRAIT_UNHUSKABLE)) - return + return FALSE var/was_husk = HAS_TRAIT(src, TRAIT_HUSK) ADD_TRAIT(src, TRAIT_HUSK, source) - if (was_husk) - return - update_body() - RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_UNHUSKABLE), PROC_REF(became_unhuskable)) - return TRUE //MODULAR ZUBBERS CHANGE: RETURN TRUE + if (!was_husk) + RegisterSignal(src, SIGNAL_ADDTRAIT(TRAIT_UNHUSKABLE), PROC_REF(became_unhuskable)) + return TRUE /// Called when we become unhuskable while already husked /mob/living/proc/became_unhuskable() @@ -543,7 +540,7 @@ if(stat != DEAD) if(!silent) emote("deathgasp") - station_timestamp_timeofdeath = station_time_timestamp() + station_timestamp_timeofdeath = round_timestamp() if(!HAS_TRAIT(src, TRAIT_FAKEDEATH) && !silent) send_death_moodlets() diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index 1f0069e203c..541734ff8e4 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -104,6 +104,7 @@ stop_sound_channel(CHANNEL_AMBIENCE) if(client) + client.view_size?.resetToDefault() // Resets the client.view in case it was changed. for(var/datum/action/A as anything in persistent_client.player_actions) @@ -121,6 +122,9 @@ ) auto_deadmin_on_login() + //Check if they should have a stat panel, after they deadmined. + client.set_stat_panel() + log_message("Client [key_name(src)] has taken ownership of mob [src]([src.type])", LOG_OWNERSHIP) log_mob_tag("TAG: [tag] NEW OWNER: [key_name(src)]") SEND_SIGNAL(src, COMSIG_MOB_CLIENT_LOGIN, client) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 8ec3f4d4e47..a173093a46f 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -815,11 +815,7 @@ * * Calls attack self on the item and updates the inventory hud for hands */ -/mob/verb/mode() - set name = "Activate Held Object" - set category = "IC" - set src = usr - +/mob/proc/mode() DEFAULT_QUEUE_OR_CALL_VERB(VERB_CALLBACK(src, PROC_REF(execute_mode))) ///proc version to finish /mob/verb/mode() execution. used in case the proc needs to be queued for the tick after its first called @@ -988,14 +984,8 @@ var/previous_index = active_hand_index active_hand_index = held_index - if(hud_used) - var/atom/movable/screen/inventory/hand/held_location - held_location = hud_used.hand_slots[previous_index] - if(!isnull(held_location)) - held_location.update_appearance() - held_location = hud_used.hand_slots[held_index] - if(!isnull(held_location)) - held_location.update_appearance() + hud_used?.update_inventory_slot(ITEM_SLOT_HANDS, previous_index) + hud_used?.update_inventory_slot(ITEM_SLOT_HANDS, held_index) return TRUE /mob/proc/activate_hand(selected_hand) @@ -1513,13 +1503,6 @@ //Do not do parent's actions, as we *usually* do this differently. fully_replace_character_name(real_name, new_name) -///Show the language menu for this mob -/mob/verb/open_language_menu_verb() - set name = "Open Language Menu" - set category = "IC" - - get_language_holder().open_language_menu(usr) - ///Adjust the nutrition of a mob /mob/proc/adjust_nutrition(change, forced = FALSE) //Honestly FUCK the oldcoders for putting nutrition on /mob someone else can move it up because holy hell I'd have to fix SO many typechecks if(HAS_TRAIT(src, TRAIT_NOHUNGER) && !forced) @@ -1643,21 +1626,6 @@ clear_important_client_contents() canon_client = null -///Shows a tgui window with memories -/mob/verb/memory() - set name = "Memories" - set category = "IC" - set desc = "View your character's memories." - if(!mind) - var/fail_message = "You have no mind!" - if(isobserver(src)) - fail_message += " You have to be in the current round at some point to have one." - to_chat(src, span_warning(fail_message)) - return - if(!mind.memory_panel) - mind.memory_panel = new(usr, mind) - mind.memory_panel.ui_interact(usr) - ///Shows a tgui window with memories /mob/proc/open_memory_panel() if(!mind) @@ -1710,12 +1678,6 @@ data["memories"] = memories return data -/mob/verb/view_skills() - set category = "IC" - set name = "View Skills" - - mind?.print_levels(src) - /mob/key_down(key, client/client, full_key) ..() SEND_SIGNAL(src, COMSIG_MOB_KEYDOWN, key, client, full_key) diff --git a/code/modules/mob/mob_lists.dm b/code/modules/mob/mob_lists.dm index 4e50a4d8595..f47f316c078 100644 --- a/code/modules/mob/mob_lists.dm +++ b/code/modules/mob/mob_lists.dm @@ -47,10 +47,6 @@ /mob/proc/add_to_player_list() SHOULD_CALL_PARENT(TRUE) GLOB.player_list |= src - if(client.holder) - GLOB.keyloop_list |= src - else if(stat != DEAD || !SSlag_switch?.measures[DISABLE_DEAD_KEYLOOP]) - GLOB.keyloop_list |= src if(stat == DEAD) add_to_current_dead_players() else @@ -70,12 +66,19 @@ ///Adds the cliented mob reference to either the list of dead player-mobs or to the list of observers, depending on how they joined the game. /mob/proc/add_to_current_dead_players() GLOB.dead_player_list |= src + if(!SSlag_switch.measures[DISABLE_DEAD_KEYLOOP] || client.holder) + GLOB.keyloop_list |= src + else + GLOB.keyloop_list -= src /mob/dead/observer/add_to_current_dead_players() + if(!SSlag_switch.measures[DISABLE_DEAD_KEYLOOP] || client?.holder) // observers can move + GLOB.keyloop_list |= src if(started_as_observer) GLOB.current_observers_list |= src return - return ..() + else + GLOB.dead_player_list |= src /mob/dead/new_player/add_to_current_dead_players() return @@ -94,6 +97,7 @@ ///Adds the cliented mob reference to the list of living player-mobs. If the mob is an antag, it adds it to the list of living antag player-mobs. /mob/proc/add_to_current_living_players() GLOB.alive_player_list |= src + GLOB.keyloop_list |= src if(is_antag(NONE)) add_to_current_living_antags() diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 75cc97cb5f4..8ecf22b4e76 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -27,7 +27,7 @@ * in the parent proc with istype checks right?): * * having incorporeal_move set (calls Process_Incorpmove() instead) * * being grabbed - * * being buckled (relaymove() is called to the buckled atom instead) + * * being buckled (relaymove() is called to the buckled atom instead) * * having your loc be some other mob (relaymove() is called on that mob instead) * * Not having MOBILITY_MOVE * * Failing Process_Spacemove() call @@ -551,10 +551,7 @@ SEND_SIGNAL(src, COMSIG_MOVE_INTENT_TOGGLED) ///Moves a mob upwards in z level -/mob/verb/up() - set name = "Move Upwards" - set category = "IC" - +/mob/proc/up() if(remote_control) return remote_control.relaymove(src, UP) @@ -578,10 +575,7 @@ to_chat(src, span_notice("You move upwards.")) ///Moves a mob down a z level -/mob/verb/down() - set name = "Move Down" - set category = "IC" - +/mob/proc/down() if(remote_control) return remote_control.relaymove(src, DOWN) diff --git a/code/modules/mob/mob_say.dm b/code/modules/mob/mob_say.dm index 4befd284cb9..cc37a85321b 100644 --- a/code/modules/mob/mob_say.dm +++ b/code/modules/mob/mob_say.dm @@ -2,9 +2,7 @@ ///what clients use to speak. when you type a message into the chat bar in say mode, this is the first thing that goes off serverside. /mob/verb/say_verb(message as text) - set name = "Say" - set category = "IC" - set instant = TRUE + set name = VERB_SAY if(GLOB.say_disabled) //This is here to try to identify lag problems to_chat(usr, span_danger("Speech is currently admin-disabled.")) @@ -17,9 +15,7 @@ ///Whisper verb /mob/verb/whisper_verb(message as text) - set name = "Whisper" - set category = "IC" - set instant = TRUE + set name = VERB_WHISPER if(GLOB.say_disabled) //This is here to try to identify lag problems to_chat(usr, span_danger("Speech is currently admin-disabled.")) @@ -40,9 +36,7 @@ ///The me emote verb /mob/verb/me_verb(message as text) - set name = "Me" - set category = "IC" - set desc = "Perform a custom emote. Leave blank to pick between an audible or a visible emote (Defaults to visible)." + set name = VERB_ME if(GLOB.say_disabled) //This is here to try to identify lag problems to_chat(usr, span_danger("Speech is currently admin-disabled.")) @@ -171,12 +165,7 @@ var/displayed_key = key if(client?.holder?.fakekey) displayed_key = null - deadchat_broadcast(rendered, source, follow_target = src, speaker_key = displayed_key) - for(var/mob/mobs_hearing as anything in GLOB.player_list) - if(SSticker.current_state != GAME_STATE_FINISHED && (mobs_hearing.see_invisible < invisibility || !isdead(mobs_hearing))) - continue - if(runechat_prefs_check(mobs_hearing)) - mobs_hearing.create_chat_message(src, /datum/language/common, message) + deadchat_broadcast(rendered, source, follow_target = src, speaker_key = displayed_key, original_message = message) ///Check if this message is an emote /mob/proc/check_emote(message, forced) diff --git a/code/modules/mob/mob_update_icons.dm b/code/modules/mob/mob_update_icons.dm index 210c041408c..11da749e89a 100644 --- a/code/modules/mob/mob_update_icons.dm +++ b/code/modules/mob/mob_update_icons.dm @@ -66,6 +66,7 @@ /mob/proc/update_held_items() SHOULD_CALL_PARENT(TRUE) SEND_SIGNAL(src, COMSIG_MOB_UPDATE_HELD_ITEMS) + hud_used?.update_inventory_slot(ITEM_SLOT_HANDS) ///Updates the mask overlay & HUD element. /mob/proc/update_worn_mask() @@ -95,9 +96,6 @@ /mob/proc/update_body() return -/mob/proc/update_hair() - return - ///Updates the glasses overlay & HUD element. /mob/proc/update_worn_glasses() return diff --git a/code/modules/mob/status_procs.dm b/code/modules/mob/status_procs.dm index fccd64ab705..1f190d6cdb4 100644 --- a/code/modules/mob/status_procs.dm +++ b/code/modules/mob/status_procs.dm @@ -39,5 +39,5 @@ if(new_sight == see_invisible) return var/old_invis = see_invisible - see_invisible = new_sight - SEND_SIGNAL(src, COMSIG_MOB_SEE_INVIS_CHANGE, see_invisible, old_invis) + if(!(SEND_SIGNAL(src, COMSIG_MOB_SEE_INVIS_CHANGE, new_sight, old_invis) & COMPONENT_BLOCK_INVIS_CHANGE)) + see_invisible = new_sight diff --git a/code/modules/mob_spawn/mob_spawn.dm b/code/modules/mob_spawn/mob_spawn.dm index 957c6324f45..e01b47c8569 100644 --- a/code/modules/mob_spawn/mob_spawn.dm +++ b/code/modules/mob_spawn/mob_spawn.dm @@ -230,7 +230,7 @@ /obj/effect/mob_spawn/ghost_role/proc/can_ghost_take(mob/dead/observer/user) if(is_banned_from(user.ckey, role_ban)) to_chat(user, span_warning("You are banned from this role!")) - return FALL_STOP_INTERCEPTING + return FALSE if(!(GLOB.ghost_role_flags & GHOSTROLE_SPAWNER) && !(flags_1 & ADMIN_SPAWNED_1)) to_chat(user, span_warning("An admin has temporarily disabled non-admin ghost roles!")) return FALSE diff --git a/code/modules/mod/mod_theme.dm b/code/modules/mod/mod_theme.dm index ec8e719f5d2..92c4fd390ab 100644 --- a/code/modules/mod/mod_theme.dm +++ b/code/modules/mod/mod_theme.dm @@ -1553,9 +1553,10 @@ inbuilt_modules = list(/obj/item/mod/module/anti_magic/wizard) hearing_protection = EAR_PROTECTION_NORMAL allowed_suit_storage = list( - /obj/item/teleportation_scroll, - /obj/item/highfrequencyblade/wizard, /obj/item/gun/magic, + /obj/item/highfrequencyblade/wizard, + /obj/item/storage/belt/wand_bandolier, + /obj/item/teleportation_scroll, ) variants = list( "enchanted" = list( diff --git a/code/modules/mod/modules/module_holding.dm b/code/modules/mod/modules/module_holding.dm index fc235663f1f..1d8c8642333 100644 --- a/code/modules/mod/modules/module_holding.dm +++ b/code/modules/mod/modules/module_holding.dm @@ -58,10 +58,12 @@ storage_type = /datum/storage/bag_of_holding create_storage(storage_type = /datum/storage/bag_of_holding) atom_storage.set_locked(STORAGE_FULLY_LOCKED) + item_flags |= BLUESPACE_INTERFERENCE /obj/item/mod/module/storage/holding/proc/on_core_removed() QDEL_NULL(atom_storage) storage_type = null + item_flags &= ~BLUESPACE_INTERFERENCE /obj/item/mod/module/storage/holding/proc/try_install(_source, obj/item/mod/control/suit, mob/user) SIGNAL_HANDLER @@ -92,6 +94,7 @@ /obj/item/mod/module/storage/holding/prebuilt prebuilt = TRUE + item_flags = BLUESPACE_INTERFERENCE /obj/item/mod/module/storage/holding/prebuilt/locked core_removable = FALSE diff --git a/code/modules/mod/modules/modules_antag.dm b/code/modules/mod/modules/modules_antag.dm index 44443c90fa2..f7d28ed1341 100644 --- a/code/modules/mod/modules/modules_antag.dm +++ b/code/modules/mod/modules/modules_antag.dm @@ -527,7 +527,7 @@ /obj/item/mod/module/stealth/wraith/proc/start_stealth() if(!COOLDOWN_FINISHED(src, recloak_timer)) // Prevents being able to bypass the cooldown by disabling and re-enabling the module - addtimer(CALLBACK(src, PROC_REF(start_stealth)), recloak_timer) + addtimer(CALLBACK(src, PROC_REF(start_stealth)), COOLDOWN_TIMELEFT(src, recloak_timer)) return RegisterSignals(mod.wearer, list(COMSIG_LIVING_MOB_BUMP, COMSIG_ATOM_BUMPED, COMSIG_MOB_FIRED_GUN), PROC_REF(unstealth)) RegisterSignal(mod.wearer, COMSIG_LIVING_UNARMED_ATTACK, PROC_REF(on_unarmed_attack)) diff --git a/code/modules/mod/modules/modules_general.dm b/code/modules/mod/modules/modules_general.dm index 5b830ea3578..63f417ad505 100644 --- a/code/modules/mod/modules/modules_general.dm +++ b/code/modules/mod/modules/modules_general.dm @@ -244,7 +244,7 @@ /obj/item/mod/module/status_readout/add_ui_data() . = ..() .["display_time"] = display_time - .["shift_time"] = station_time_timestamp() + .["shift_time"] = round_timestamp() .["shift_id"] = GLOB.round_id .["health"] = mod.wearer?.health || 0 .["health_max"] = mod.wearer?.getMaxHealth() || 0 diff --git a/code/modules/mod/modules/modules_supply.dm b/code/modules/mod/modules/modules_supply.dm index 0ebd99635ae..9fe1b8a137b 100644 --- a/code/modules/mod/modules/modules_supply.dm +++ b/code/modules/mod/modules/modules_supply.dm @@ -194,7 +194,7 @@ if (!istype(giberal_turf) || giberal_turf.stage != GIBTONITE_UNSTRUCK) last_bumpmine_tick = world.time var/turf/closed/mineral/rock = bumped_into - INVOKE_ASYNC(rock, TYPE_PROC_REF(/atom, attackby), src, bumper, null, null, exp_multiplier) + INVOKE_ASYNC(src, PROC_REF(mine_rock), rock, bumper) return if (!COOLDOWN_FINISHED(src, gibtonite_warning_cd)) @@ -204,12 +204,21 @@ playsound(bumper, 'sound/machines/scanner/scanbuzz.ogg', 25, TRUE, SILENCED_SOUND_EXTRARANGE) to_chat(bumper, span_warning("[icon2html(src, bumper)] Unstable gibtonite ore deposit detected!")) +/obj/item/mod/module/drill/proc/mine_rock(turf/closed/mineral/rock, mob/living/carbon/human/bumper) + // Even faster if it has ore! + var/has_ore = !isnull(rock.mineral_type) + if (has_ore) + toolspeed /= 2 + rock.attackby(src, bumper, null, null, exp_multiplier) + if (has_ore) + toolspeed *= 2 + /obj/item/mod/module/drill/proc/on_module_activated(datum/source, obj/item/mod/module/module) SIGNAL_HANDLER if (!istype(module, /obj/item/mod/module/sphere_transform)) return - // In sphere mode we get instamine and halved power drain - toolspeed = 0 + // In sphere mode we get faster mining and halved power drain + toolspeed = 0.075 use_energy_cost *= 0.5 exp_multiplier *= 0.2 if (!active) @@ -222,7 +231,7 @@ return toolspeed = initial(toolspeed) use_energy_cost *= 2 - exp_multiplier /= 2 + exp_multiplier /= 0.2 ballin = FALSE if (!active) on_deactivation() @@ -568,7 +577,7 @@ /obj/item/mod/module/sphere_transform name = "MOD sphere transform module" desc = "A module able to move the suit's parts around, turning it and the user into a sphere. \ - The sphere can move quickly, even through lava, and launch mining bombs to decimate terrain." + The sphere can move quickly, even through lava, and launch mining micromissile to decimate terrain and fauna alike." icon_state = "sphere" module_type = MODULE_ACTIVE removable = FALSE @@ -678,12 +687,19 @@ . = ..() if(!.) return - var/obj/projectile/bullet/mining_bomb/bomb = new(mod.wearer.loc) - bomb.aim_projectile(target, mod.wearer) - bomb.firer = mod.wearer - playsound(src, 'sound/items/weapons/gun/general/grenade_launch.ogg', 75, TRUE) - INVOKE_ASYNC(bomb, TYPE_PROC_REF(/obj/projectile, fire)) drain_power(use_energy_cost) + INVOKE_ASYNC(src, PROC_REF(fire_missile), target) + for (var/i in 1 to 2) + addtimer(CALLBACK(src, PROC_REF(fire_missile), target), 0.2 SECONDS * i) + +/obj/item/mod/module/sphere_transform/proc/fire_missile(atom/target) + var/obj/projectile/bullet/mining_missile/missile = new(mod.wearer.loc) + missile.aim_projectile(target, mod.wearer) + missile.firer = mod.wearer + if (isliving(target)) + missile.set_homing_target(target) + playsound(src, 'sound/items/weapons/gun/general/rocket_launch.ogg', 30, TRUE) + missile.fire() /obj/item/mod/module/sphere_transform/on_active_process(seconds_per_tick) if(!mod.wearer.has_gravity()) @@ -694,76 +710,60 @@ if(mod.wearer.stat) deactivate() -/obj/projectile/bullet/mining_bomb - name = "mining bomb" - desc = "A bomb. Why are you examining this?" - icon_state = "mine_bomb" +/obj/projectile/bullet/mining_missile + name = "mining micromissile" + desc = "A missile. Why are you examining this?" + icon_state = "mine_missile" icon = 'icons/obj/clothing/modsuit/mod_modules.dmi' - damage = 0 + damage = 3 // 3 * 4 = 12, *3 = 36 damage between 3 missiles range = 6 + homing_turn_speed = 12 suppressed = SUPPRESSED_VERY armor_flag = BOMB light_system = OVERLAY_LIGHT light_range = 1 light_power = 1 - light_color = COLOR_LIGHT_ORANGE + light_color = LIGHT_COLOR_BABY_BLUE embed_type = null can_hit_turfs = TRUE - -/obj/projectile/bullet/mining_bomb/Initialize(mapload) - . = ..() - AddElement(/datum/element/projectile_drop, /obj/structure/mining_bomb) - RegisterSignal(src, COMSIG_PROJECTILE_ON_SPAWN_DROP, PROC_REF(handle_drop)) - -/obj/projectile/bullet/mining_bomb/proc/handle_drop(datum/source, obj/structure/mining_bomb/mining_bomb) - SIGNAL_HANDLER - addtimer(CALLBACK(mining_bomb, TYPE_PROC_REF(/obj/structure/mining_bomb, prime), firer), mining_bomb.prime_time) - -/obj/structure/mining_bomb - name = "mining bomb" - desc = "A bomb. Why are you examining this?" - icon_state = "mine_bomb" - icon = 'icons/obj/clothing/modsuit/mod_modules.dmi' - anchored = TRUE - resistance_flags = FIRE_PROOF|LAVA_PROOF - light_system = OVERLAY_LIGHT - light_range = 1 - light_power = 1 - light_color = COLOR_LIGHT_ORANGE - /// Time to prime the explosion - var/prime_time = 0.1 SECONDS - /// Time to explode from the priming - var/explosion_time = 0.9 SECONDS // Roughly this much until the blast part of the explosion animation - /// Damage done on explosion. - var/damage = 7 - /// Damage multiplier on hostile fauna. + /// Damage multiplier against lavaland fauna var/fauna_boost = 4 -/obj/structure/mining_bomb/proc/prime(atom/movable/firer) - var/mutable_appearance/explosion_image = mutable_appearance('icons/effects/96x96.dmi', "judicial_explosion", FLOAT_LAYER, src, ABOVE_GAME_PLANE) - explosion_image.pixel_w = -32 - explosion_image.pixel_z = -32 - var/turf/our_loc = get_turf(src) - our_loc.flick_overlay_view(explosion_image, 1.35 SECONDS) - addtimer(CALLBACK(src, PROC_REF(boom), firer), explosion_time) +/obj/projectile/bullet/mining_missile/on_hit(atom/target, blocked, pierce_hit) + playsound(get_turf(target), 'sound/items/weapons/sonic_jackhammer.ogg', 75, TRUE) + if (ismineralturf(target)) + . = ..() + spawn_particles(target) + var/turf/closed/mineral/rock = target + rock.gets_drilled(firer) + return BULLET_ACT_HIT -/obj/structure/mining_bomb/proc/boom(atom/movable/firer) - visible_message(span_danger("[src] explodes!")) - playsound(src, 'sound/effects/magic/magic_missile.ogg', 200, vary = TRUE) - for(var/turf/closed/mineral/rock in circle_range_turfs(src, 1)) - rock.gets_drilled() - for(var/mob/living/victim in range(1, src)) - if(HAS_TRAIT(victim, TRAIT_MINING_AOE_IMMUNE)) - continue - victim.apply_damage(damage * (ismining(victim) ? fauna_boost : 1), BRUTE, spread_damage = TRUE) - to_chat(victim, span_userdanger("You are hit by a mining bomb explosion!")) - if(!firer) - continue - if(ishostile(victim)) - var/mob/living/simple_animal/hostile/hostile_mob = victim - hostile_mob.GiveTarget(firer) - else if(isbasicmob(victim)) - victim.ai_controller.set_blackboard_key(BB_BASIC_MOB_CURRENT_TARGET, firer) - for(var/obj/object in range(1, src)) - object.take_damage(damage, BRUTE, BOMB) - qdel(src) + if (!isliving(target)) + . = ..() + spawn_particles(target) + return + + if (isliving(target)) + var/mob/living/victim = target + if (ismining(victim)) + damage *= fauna_boost + . = ..() + spawn_particles(target) + +/obj/projectile/bullet/mining_missile/proc/spawn_particles(atom/target) + var/obj/effect/abstract/particle_holder/impact_particles = new(get_turf(target), /particles/micromissile_impact) + impact_particles.particles.position = generator(GEN_BOX, list(impact_x - 2, impact_y - 2), list(impact_x + 2, impact_y + 2), NORMAL_RAND) + impact_particles.particles.velocity = generator(GEN_BOX, list(movement_vector.pixel_x * 0.5 * speed * ICON_SIZE_X - 2, movement_vector.pixel_y * 0.5 * speed * ICON_SIZE_Y - 2, ), list(movement_vector.pixel_x * 0.5 * speed * ICON_SIZE_X + 2, movement_vector.pixel_y * 0.5 * speed * ICON_SIZE_Y + 2), NORMAL_RAND) + QDEL_IN(impact_particles, /particles/micromissile_impact::lifespan) + +/particles/micromissile_impact + icon = 'icons/effects/particles/generic.dmi' + icon_state = "cross" + width = 100 + height = 100 + count = 10 + spawning = 10 + color = LIGHT_COLOR_BABY_BLUE + lifespan = 1 SECONDS + fade = 1 SECONDS + spin = generator(GEN_NUM, -20, 20) diff --git a/code/modules/mod/modules/modules_timeline.dm b/code/modules/mod/modules/modules_timeline.dm index a544e0963e0..0573d23e7b1 100644 --- a/code/modules/mod/modules/modules_timeline.dm +++ b/code/modules/mod/modules/modules_timeline.dm @@ -418,9 +418,8 @@ /obj/structure/chrono_field/return_air() //we always have nominal air and temperature var/datum/gas_mixture/fresh_air = new - fresh_air.add_gases(/datum/gas/oxygen, /datum/gas/nitrogen) - fresh_air.gases[/datum/gas/oxygen][MOLES] = MOLES_O2STANDARD - fresh_air.gases[/datum/gas/nitrogen][MOLES] = MOLES_N2STANDARD + fresh_air.set_gas(/datum/gas/oxygen, MOLES_O2STANDARD) + fresh_air.set_gas(/datum/gas/nitrogen, MOLES_N2STANDARD) fresh_air.temperature = T20C return fresh_air diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm index 400d50d3b0b..d50d05864a7 100644 --- a/code/modules/modular_computers/computers/item/computer.dm +++ b/code/modules/modular_computers/computers/item/computer.dm @@ -688,7 +688,7 @@ data["PC_programheaders"] = program_headers - data["PC_stationtime"] = station_time_timestamp() + data["PC_stationtime"] = round_timestamp() data["PC_stationdate"] = "[time2text(world.realtime, "DDD, Month DD", NO_TIMEZONE)], [CURRENT_STATION_YEAR]" data["PC_showexitprogram"] = !!active_program // Hides "Exit Program" button on mainscreen return data diff --git a/code/modules/modular_computers/computers/item/pda.dm b/code/modules/modular_computers/computers/item/pda.dm index 4f6ff07ec18..cf1424cd189 100644 --- a/code/modules/modular_computers/computers/item/pda.dm +++ b/code/modules/modular_computers/computers/item/pda.dm @@ -369,6 +369,7 @@ /obj/item/modular_computer/pda/silicon/Destroy() silicon_owner = null + robotact = null return ..() ///Silicons don't have the tools (or hands) to make circuits setups with their own PDAs. diff --git a/code/modules/modular_computers/file_system/data.dm b/code/modules/modular_computers/file_system/data.dm index 7721d50b763..661318f4baf 100644 --- a/code/modules/modular_computers/file_system/data.dm +++ b/code/modules/modular_computers/file_system/data.dm @@ -98,6 +98,10 @@ src.workspace = workspace src.source_photo_or_painting = source_photo_or_painting +/datum/computer_file/data/paint_project/Destroy(force) + source_photo_or_painting = null + return ..() + /datum/computer_file/data/paint_project/clone(rename) var/datum/computer_file/data/paint_project/temp = ..() temp.workspace = workspace.copy() diff --git a/code/modules/modular_computers/file_system/image_file.dm b/code/modules/modular_computers/file_system/image_file.dm index f029793701d..8dcfd942f22 100644 --- a/code/modules/modular_computers/file_system/image_file.dm +++ b/code/modules/modular_computers/file_system/image_file.dm @@ -27,6 +27,10 @@ src.image_name = image_name set_source(source_photo_or_painting) +/datum/computer_file/image/Destroy(force) + source_photo_or_painting = null + return ..() + /datum/computer_file/image/on_install(datum/computer_file/source, obj/item/modular_computer/computer_installing) . = ..() assign_path() diff --git a/code/modules/modular_computers/file_system/programs/budgetordering.dm b/code/modules/modular_computers/file_system/programs/budgetordering.dm index 9aa1424b53d..9064df7067c 100644 --- a/code/modules/modular_computers/file_system/programs/budgetordering.dm +++ b/code/modules/modular_computers/file_system/programs/budgetordering.dm @@ -64,7 +64,7 @@ var/datum/bank_account/buyer = SSeconomy.get_dep_account(cargo_account) var/obj/item/card/id/id_card = computer.stored_id?.GetID() - if(id_card?.registered_account) + if(id_card?.registered_account?.account_job?.paycheck_department) buyer = SSeconomy.get_dep_account(id_card?.registered_account.account_job.paycheck_department) if((ACCESS_BUDGET in id_card.access)) requestonly = FALSE diff --git a/code/modules/modular_computers/file_system/programs/chatroom/conversation.dm b/code/modules/modular_computers/file_system/programs/chatroom/conversation.dm index 969e56195ed..0e65dfedd2a 100644 --- a/code/modules/modular_computers/file_system/programs/chatroom/conversation.dm +++ b/code/modules/modular_computers/file_system/programs/chatroom/conversation.dm @@ -46,13 +46,13 @@ return ..() /datum/ntnet_conversation/proc/add_message(message, username) - message = "[station_time_timestamp(format = "hh:mm")] [username]: [message]" + message = "[round_timestamp(format = "hh:mm")] [username]: [message]" messages["[next_message_id]"] = message next_message_id++ trim_message_list() /datum/ntnet_conversation/proc/add_status_message(message) - message = "[station_time_timestamp(format = "hh:mm")] -!- [message]" + message = "[round_timestamp(format = "hh:mm")] -!- [message]" messages["[next_message_id]"] = message next_message_id++ trim_message_list() diff --git a/code/modules/modular_computers/file_system/programs/chatroom/ntnrc_client.dm b/code/modules/modular_computers/file_system/programs/chatroom/ntnrc_client.dm index f71d985197c..5ea1bb1f51b 100644 --- a/code/modules/modular_computers/file_system/programs/chatroom/ntnrc_client.dm +++ b/code/modules/modular_computers/file_system/programs/chatroom/ntnrc_client.dm @@ -126,8 +126,8 @@ if("PRG_savelog") if(!channel) return - var/logname = stripped_input(params["log_name"]) - if(!logname) + var/logname = trim(params["log_name"], MAX_MESSAGE_LEN) + if(!length(logname) || !filter_filename_pda(logname)) return var/datum/computer_file/data/text/logfile = new() // Now we will generate HTML-compliant file that can actually be viewed/printed. diff --git a/code/modules/modular_computers/file_system/programs/crewmanifest.dm b/code/modules/modular_computers/file_system/programs/crewmanifest.dm index d0dcf0ae873..eccb78a58ff 100644 --- a/code/modules/modular_computers/file_system/programs/crewmanifest.dm +++ b/code/modules/modular_computers/file_system/programs/crewmanifest.dm @@ -23,7 +23,7 @@
    [GLOB.manifest ? GLOB.manifest.get_html(0) : ""] "} - if(!computer.print_text(contents, "crew manifest ([station_time_timestamp()])")) + if(!computer.print_text(contents, "crew manifest ([round_timestamp()])")) to_chat(usr, span_notice("Printer is out of paper.")) return else diff --git a/code/modules/modular_computers/file_system/programs/file_browser.dm b/code/modules/modular_computers/file_system/programs/file_browser.dm index d25a9894307..8c3dbfe213a 100644 --- a/code/modules/modular_computers/file_system/programs/file_browser.dm +++ b/code/modules/modular_computers/file_system/programs/file_browser.dm @@ -119,8 +119,8 @@ GLOBAL_LIST_INIT(print_types, init_print_types()) var/datum/computer_file/file = computer.find_file_by_name(params["name"]) if(!file) return - var/newname = reject_bad_name(params["new_name"], allow_numbers = TRUE, cap_after_symbols = FALSE, cap_at_start = FALSE) - if(!newname || newname != params["new_name"]) + var/newname = trim(params["new_name"], MAX_MESSAGE_LEN) + if(!length(newname) || !filter_filename_pda(newname)) playsound(computer, 'sound/machines/terminal/terminal_error.ogg', 25, FALSE) return file.filename = newname @@ -131,8 +131,8 @@ GLOBAL_LIST_INIT(print_types, init_print_types()) var/datum/computer_file/file = computer.find_file_by_name(params["name"], computer.inserted_disk) if(!file) return - var/newname = reject_bad_name(params["new_name"], allow_numbers = TRUE, cap_after_symbols = FALSE, cap_at_start = FALSE) - if(!newname || newname != params["new_name"]) + var/newname = trim(params["new_name"], MAX_MESSAGE_LEN) + if(!length(newname) || !filter_filename_pda(newname)) playsound(computer, 'sound/machines/terminal/terminal_error.ogg', 25, FALSE) return file.filename = newname diff --git a/code/modules/modular_computers/file_system/programs/messenger/messenger_program.dm b/code/modules/modular_computers/file_system/programs/messenger/messenger_program.dm index e559d42e858..b52011f5c8e 100644 --- a/code/modules/modular_computers/file_system/programs/messenger/messenger_program.dm +++ b/code/modules/modular_computers/file_system/programs/messenger/messenger_program.dm @@ -552,7 +552,7 @@ return FALSE // Log it in our logs - var/datum/pda_message/message_datum = new(message, TRUE, station_time_timestamp(PDA_MESSAGE_TIMESTAMP_FORMAT), photo_asset_key, everyone, subtle = subtle) // BUBBER EDIT CHANGE - SUBTLE MESSAGES - Original: var/datum/pda_message/message_datum = new(message, TRUE, station_time_timestamp(PDA_MESSAGE_TIMESTAMP_FORMAT), photo_asset_key, everyone) + var/datum/pda_message/message_datum = new(message, TRUE, round_timestamp(PDA_MESSAGE_TIMESTAMP_FORMAT), photo_asset_key, everyone, subtle = subtle) // BUBBER EDIT CHANGE - SUBTLE MESSAGES - Original: var/datum/pda_message/message_datum = new(message, TRUE, round_timestamp(PDA_MESSAGE_TIMESTAMP_FORMAT), photo_asset_key, everyone) for(var/datum/pda_chat/target_chat as anything in target_chats) target_chat.add_message(message_datum, show_in_recents = !everyone) target_chat.unread_messages = 0 @@ -705,7 +705,7 @@ // don't create a new chat for rigged messages, make it a one off notif if(!is_rigged) - var/datum/pda_message/message = new(signal.data["message"], FALSE, station_time_timestamp(PDA_MESSAGE_TIMESTAMP_FORMAT), signal.data["photo"], signal.data["everyone"], signal.data["subtle"]) // BUBBER EDIT CHANGE - SUBTLE MESSAGES - Original: var/datum/pda_message/message = new(signal.data["message"], FALSE, station_time_timestamp(PDA_MESSAGE_TIMESTAMP_FORMAT), signal.data["photo"], signal.data["everyone"]) + var/datum/pda_message/message = new(signal.data["message"], FALSE, round_timestamp(PDA_MESSAGE_TIMESTAMP_FORMAT), signal.data["photo"], signal.data["everyone"], signal.data["subtle"]) // BUBBER EDIT CHANGE - SUBTLE MESSAGES - Original: var/datum/pda_message/message = new(signal.data["message"], FALSE, round_timestamp(PDA_MESSAGE_TIMESTAMP_FORMAT), signal.data["photo"], signal.data["everyone"]) chat = find_chat_by_recipient(is_fake_user ? fake_name : sender_ref, is_fake_user) if(!istype(chat)) diff --git a/code/modules/modular_computers/file_system/programs/nanopaint.dm b/code/modules/modular_computers/file_system/programs/nanopaint.dm index 6e2d4bd49ab..4d499db7c24 100644 --- a/code/modules/modular_computers/file_system/programs/nanopaint.dm +++ b/code/modules/modular_computers/file_system/programs/nanopaint.dm @@ -175,11 +175,14 @@ GLOBAL_LIST_INIT(nanopaint_supported_filetypes, zebra_typecacheof(list(\ return dialog = null var/uid = params["uid"] - var/new_file_name = params["name"] + var/new_file_name = trim(params["name"], MAX_MESSAGE_LEN) var/saving_to_disk = params["onDisk"] var/datum/computer_file/new_file_type = text2path(params["typepath"]) var/extension = new_file_type::filetype var/datum/computer_file/existing_file + if(!length(new_file_name)) + dialog = list("type" = "error", "message" = "No name specified.") + return TRUE if(saving_to_disk) if(!computer.inserted_disk) dialog = list("type" = "error", "message" = "[new_file_name] - The disk has been removed.") @@ -208,6 +211,12 @@ GLOBAL_LIST_INIT(nanopaint_supported_filetypes, zebra_typecacheof(list(\ else INVOKE_ASYNC(src, PROC_REF(write_to_file), user, existing_file) return TRUE + if(is_ic_filtered_for_pdas(new_file_name) || is_soft_ic_filtered_for_pdas(new_file_name)) + dialog = list("type" = "error", "message" = "The entered file name violates company policy.") + return TRUE + if(!filter_illegal_filename_chars(new_file_name)) + dialog = list("type" = "error", "message" = "[new_file_name] - File names cannot include the following characters. \n \\ / : * ? \" < > |") + return TRUE INVOKE_ASYNC(src, PROC_REF(save_file), user, new_file_name, new_file_type, saving_to_disk && computer.inserted_disk) return TRUE @@ -283,7 +292,7 @@ GLOBAL_LIST_INIT(nanopaint_supported_filetypes, zebra_typecacheof(list(\ /datum/computer_file/program/nanopaint/proc/save_file(mob/user, name, file_type, obj/item/disk/computer/target_disk) var/datum/computer_file/file = new file_type() - file.filename = reject_bad_name(name, allow_numbers = TRUE, cap_after_symbols = FALSE, cap_at_start = FALSE) + file.filename = name var/file_stored if(target_disk) file_stored = target_disk.add_file(file) diff --git a/code/modules/modular_computers/file_system/programs/secureye.dm b/code/modules/modular_computers/file_system/programs/secureye.dm index c488e1d0ec6..640de44979c 100644 --- a/code/modules/modular_computers/file_system/programs/secureye.dm +++ b/code/modules/modular_computers/file_system/programs/secureye.dm @@ -174,7 +174,7 @@ CRASH("[src] was able to track [target] through /datum/trackable, but was not on a visible turf to cameras.") for(var/obj/machinery/camera/cameras as anything in target_camerachunk.cameras["[target.z]"]) // We need to find a particular camera that can see this turf - if(length(cameras.can_see() & list(target_turf))) + if(!(length(cameras.can_see() & list(target_turf)))) continue var/new_camera = WEAKREF(cameras) if(camera_ref == new_camera) diff --git a/code/modules/movespeed/modifiers/mobs.dm b/code/modules/movespeed/modifiers/mobs.dm index f3107b31af3..a4003d92987 100644 --- a/code/modules/movespeed/modifiers/mobs.dm +++ b/code/modules/movespeed/modifiers/mobs.dm @@ -163,7 +163,7 @@ variable = TRUE /datum/movespeed_modifier/goliath_mount - multiplicative_slowdown = -27.5 + multiplicative_slowdown = -9.5 /datum/movespeed_modifier/goldgrub_mount multiplicative_slowdown = -4.5 diff --git a/code/modules/paperwork/fax.dm b/code/modules/paperwork/fax.dm index 3626a5122b2..1d8c3fa4ba2 100644 --- a/code/modules/paperwork/fax.dm +++ b/code/modules/paperwork/fax.dm @@ -491,7 +491,7 @@ GLOBAL_VAR_INIT(fax_autoprinting, FALSE) var/list/history_data = list() history_data["history_type"] = history_type history_data["history_fax_name"] = history_fax_name - history_data["history_time"] = station_time_timestamp() + history_data["history_time"] = round_timestamp() fax_history += list(history_data) /// Clears the history of fax operations. diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 71e3c03cb8a..5b2459d3caf 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -233,9 +233,9 @@ if(is_signature) field_text = signature_name else if(is_date) - field_text = "[time2text(world.timeofday, "DD/MM", NO_TIMEZONE)]/[CURRENT_STATION_YEAR]" + field_text = "[server_timestamp("DD/MM/YYYY", ic_time = TRUE)]" else if(is_time) - field_text = time2text(world.timeofday, "hh:mm", NO_TIMEZONE) + field_text = round_timestamp() var/field_font = is_signature ? SIGNATURE_FONT : font @@ -850,10 +850,8 @@ /// Returns the raw contents of the input as html, with **ZERO SANITIZATION** /datum/paper_input/proc/to_raw_html() var/final = raw_text - if(font) - final = "[final]" - if(colour) - final = "[final]" + if(font || colour) + final = "[final]" if(bold) final = "[final]" return final diff --git a/code/modules/paperwork/paper_biscuit.dm b/code/modules/paperwork/paper_biscuit.dm index cd45586c9e6..75d14f551d2 100644 --- a/code/modules/paperwork/paper_biscuit.dm +++ b/code/modules/paperwork/paper_biscuit.dm @@ -147,6 +147,8 @@ add_fingerprint(user) if(!cracked) return ..() + if(has_been_sealed) + return if(tgui_alert(user, "Do you want to seal it? This can only be done once.", "Biscuit Sealing", list("Yes", "No")) != "Yes") return cracked = FALSE diff --git a/code/modules/photography/_pictures.dm b/code/modules/photography/_pictures.dm index a59435f5549..76a0cf74bc2 100644 --- a/code/modules/photography/_pictures.dm +++ b/code/modules/photography/_pictures.dm @@ -205,9 +205,9 @@ P.has_blueprints = has_blueprints if(greyscale) if(picture_image) - P.picture_image.MapColors(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0)) + P.picture_image.GrayScale() if(picture_icon) - P.picture_icon.MapColors(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0)) + P.picture_icon.GrayScale() if(cropx || cropy) if(picture_image) P.picture_image.Crop(cropx, cropy, psize_x - cropx, psize_y - cropy) diff --git a/code/modules/photography/camera/camera.dm b/code/modules/photography/camera/camera.dm index 00815854fbe..c1d51316cd6 100644 --- a/code/modules/photography/camera/camera.dm +++ b/code/modules/photography/camera/camera.dm @@ -31,6 +31,8 @@ var/pictures_left = 10 /// Currently inserted holorecord disk. var/obj/item/disk/holodisk/disk + ///Boolean on whether or not the camera will print in monochrome. + var/print_monochrome = FALSE /// Whether we flash upon taking a picture. var/flash_enabled = TRUE /// Whether we silence our picture taking and zoom adjusting sounds. @@ -77,6 +79,7 @@ /obj/item/camera/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) context[SCREENTIP_CONTEXT_ALT_LMB] = "Adjust Zoom" + context[SCREENTIP_CONTEXT_CTRL_LMB] = "Change Printer Mode" if(istype(held_item, /obj/item/camera_film)) context[SCREENTIP_CONTEXT_LMB] = "Insert Film" @@ -96,6 +99,7 @@ . = ..() . += span_notice("It has [pictures_left] photos left.") . += span_notice("Alt-click to change its focusing, allowing you to set how big of an area it will capture.") + . += span_notice("Ctrl-click to change the printer between color and monochrome.") . += span_notice("The present dimensions of the picture are [EXAMINE_HINT("[APERTURE_TO_METERS(picture_size_x)]x[APERTURE_TO_METERS(picture_size_y)]")]") if(isnull(disk)) @@ -137,6 +141,7 @@ to_chat(user, span_notice("The dimensions of the picture will be [EXAMINE_HINT("[APERTURE_TO_METERS(picture_size_x)]x[APERTURE_TO_METERS(picture_size_y)]")]")) return TRUE + /// Resets flash to be used again /obj/item/camera/proc/cooldown() PRIVATE_PROC(TRUE) @@ -182,6 +187,7 @@ /** * Attempts to take an image of the target and all its surrounding tiles + * Returns TRUE if it successfully starts taking a picture. * Arguments * * * atom/target - the target we are trying to take a photo of @@ -193,14 +199,16 @@ if(!on) if(user) user.balloon_alert(user, "flash still charging!") - return + return FALSE if(blending) if(user) user.balloon_alert(user, "image still blending!") - return + return FALSE + blending = TRUE INVOKE_ASYNC(src, PROC_REF(capture_image), target, user) + return TRUE /** * Renders an image of the target and all its surrounding tiles @@ -208,31 +216,33 @@ */ /obj/item/camera/proc/capture_image(atom/target, mob/user) PRIVATE_PROC(TRUE) - //Checking if we can target var/turf/target_turf = get_turf(target) + var/view_size = user?.client?.view || world.view if(isnull(target_turf)) + blending = FALSE return - if(isAI(user) && !SScameras.is_visible_by_cameras(target_turf)) - return - if(isliving(loc) && !(target_turf in view(world.view, loc))) - return - if(!(target_turf in view(world.view, user || src))) + if(isAI(user)) + if(!SScameras.is_visible_by_cameras(target_turf)) + blending = FALSE + return + else if(!(target_turf in view(view_size, user))) + blending = FALSE return //These vars will be reused later on var/size_x = picture_size_x - 1 var/size_y = picture_size_y - 1 - var/list/viewlist = getviewsize(user?.client?.view || world.view) + var/list/viewlist = getviewsize(view_size) var/view_range = max(viewlist[1], viewlist[2]) + max(size_x, size_y) - var/viewer = get_turf(user?.client?.eye || user || target) // not sure why target is a fallback + var/viewer = get_turf(user?.client?.eye || user) var/list/seen = get_hear_turfs(view_range, viewer) if(!(target_turf in seen)) + blending = FALSE return //taking the actual picture on_flash(target, user) - blending = TRUE var/list/mobs_spotted = list() var/list/dead_spotted = list() var/list/turfs = list() @@ -286,7 +296,19 @@ continue names += "[person.name]" - var/datum/picture/picture = new("picture", desc.Join("
    "), mobs_spotted, dead_spotted, names, get_icon, null, width * ICON_SIZE_X, height * ICON_SIZE_X, blueprints, can_see_ghosts = see_ghosts) + var/datum/picture/picture = new( + "picture", + desc.Join("
    "), + mobs_spotted, + dead_spotted, + names, + get_icon, + null, + width * ICON_SIZE_X, + height * ICON_SIZE_Y, + blueprints, + can_see_ghosts = see_ghosts, + ) after_picture(user, picture) SEND_SIGNAL(src, COMSIG_CAMERA_IMAGE_CAPTURED, target, user, picture) blending = FALSE @@ -302,7 +324,9 @@ /obj/item/camera/proc/after_picture(mob/user, datum/picture/picture) PROTECTED_PROC(TRUE) - if(!silent) + if(silent) + user.playsound_local(get_turf(src), SFX_POLAROID, 35, TRUE) + else playsound(loc, SFX_POLAROID, 75, TRUE, -3) if(print_picture_on_snap) @@ -429,3 +453,12 @@ else playsound(src, 'sound/machines/click.ogg', 50, TRUE) return CLICK_ACTION_SUCCESS + +/obj/item/camera/item_ctrl_click(mob/user) + print_monochrome = !print_monochrome + user.balloon_alert(user, "printing [print_monochrome ? "monochrome" : "in color"]") + if(silent) // Don't out your silent cameras + user.playsound_local(get_turf(src), 'sound/machines/click.ogg', 50, TRUE) + else + playsound(src, 'sound/machines/click.ogg', 50, TRUE) + return CLICK_ACTION_SUCCESS diff --git a/code/modules/photography/camera/camera_image_capturing.dm b/code/modules/photography/camera/camera_image_capturing.dm index 7a4cc5857a0..c2e516b6cfc 100644 --- a/code/modules/photography/camera/camera_image_capturing.dm +++ b/code/modules/photography/camera/camera_image_capturing.dm @@ -41,7 +41,7 @@ atoms += new /obj/effect/appearance_clone(newT, T.loc) if(T.lighting_object) var/obj/effect/appearance_clone/lighting_overlay = new(newT) - lighting_overlay.appearance = T.lighting_object.current_underlay + lighting_overlay.appearance = T.lighting_object.appearance lighting_overlay.underlays += backdrop lighting_overlay.blend_mode = BLEND_MULTIPLY lighting += lighting_overlay @@ -61,7 +61,7 @@ atoms += T if(T.lighting_object) var/obj/effect/appearance_clone/lighting_overlay = new(T) - lighting_overlay.appearance = T.lighting_object.current_underlay + lighting_overlay.appearance = T.lighting_object.appearance lighting_overlay.underlays += backdrop lighting_overlay.blend_mode = BLEND_MULTIPLY lighting += lighting_overlay @@ -155,6 +155,9 @@ else QDEL_LIST(lighting) + if(print_monochrome) + res.GrayScale() + return res #undef PHYSICAL_POSITION diff --git a/code/modules/photography/camera/other.dm b/code/modules/photography/camera/other.dm index cb976a8cf31..8598302c840 100644 --- a/code/modules/photography/camera/other.dm +++ b/code/modules/photography/camera/other.dm @@ -27,11 +27,8 @@ /obj/item/camera/detective name = "detective's camera" desc = "A silent polaroid camera with extra capacity for crime investigations." + print_monochrome = TRUE flash_enabled = FALSE silent = TRUE pictures_max = 30 pictures_left = 30 - -/obj/item/camera/detective/after_picture(mob/user, datum/picture/picture) - . = ..() - user.playsound_local(get_turf(src), SFX_POLAROID, 35, TRUE) diff --git a/code/modules/photography/photos/photo.dm b/code/modules/photography/photos/photo.dm index a6009b63528..1d98d728b29 100644 --- a/code/modules/photography/photos/photo.dm +++ b/code/modules/photography/photos/photo.dm @@ -20,8 +20,8 @@ /obj/item/photo/get_save_vars() return ..() - NAMEOF(src, icon) -/obj/item/photo/Initialize(mapload, datum/picture/P, datum_name = TRUE, datum_desc = TRUE) - set_picture(P, datum_name, datum_desc, TRUE) +/obj/item/photo/Initialize(mapload, datum/picture/P, datum_name = TRUE, datum_desc = TRUE, override_name = TRUE) + set_picture(P, datum_name, datum_desc, override_name) //Photos are quite rarer than papers, so they're more likely to be added to the queue to make things even. if(!mapload && prob(MESSAGE_BOTTLE_CHANCE * 5) && picture?.id) LAZYADD(SSpersistence.queued_message_bottles, src) @@ -55,7 +55,7 @@ if(!seen) P.mobs_seen -= seen_ref continue - if(!isobserver(seen) && !isghostspecies(seen)) + if(!isobserver(seen) && !isspirit(seen)) continue set_custom_materials(list(/datum/material/hauntium =SHEET_MATERIAL_AMOUNT)) break @@ -111,7 +111,7 @@ + "" \ + "" \ + "[scribble ? "
    Written on the back:
    [scribble]" : ""]"\ - + "", "window=photo_showing;size=480x608") + + "", "window=photo_showing;size=[scribble ? "480x580" : "480x480"]") onclose(user, "[name]") /obj/item/photo/verb/rename() diff --git a/code/modules/plumbing/ducts.dm b/code/modules/plumbing/ducts.dm index 961ee534128..fe86c09e712 100644 --- a/code/modules/plumbing/ducts.dm +++ b/code/modules/plumbing/ducts.dm @@ -114,7 +114,7 @@ neighbours[other] = direction //connecting duct to us LAZYADDASSOC(other.neighbours, src, opposite_dir) - other.update_appearance(UPDATE_ICON_STATE) + other.update_appearance(UPDATE_ICON) continue @@ -138,7 +138,7 @@ //assign neighbour neighbours[plumbing.parent] = direction - update_appearance(UPDATE_ICON_STATE) + update_appearance(UPDATE_ICON) ///we disconnect ourself from our neighbours. we also destroy our ductnet and tell our neighbours to make a new one /obj/machinery/duct/on_deconstruction() @@ -152,7 +152,7 @@ //remove ourself from the duct net.ducts -= src if(!net.ducts.len) - qdel(net) //destroy the pipeline. Suppliers aren't important if there are ducts + qdel(net) //destroy the pipeline. Suppliers aren't important if there aren't any ducts left net = null /obj/machinery/duct/Destroy() @@ -168,7 +168,7 @@ var/obj/machinery/duct/pipe = neighbour if(istype(pipe)) pipe.neighbours -= src - pipe.update_appearance(UPDATE_ICON_STATE) + pipe.update_appearance(UPDATE_ICON) //find every node that can be reached from our neighbour making sure to not revisit it again in circles if(visited[neighbour]) diff --git a/code/modules/plumbing/plumbers/acclimator.dm b/code/modules/plumbing/plumbers/acclimator.dm index 28c1ef7b821..0e9e1443344 100644 --- a/code/modules/plumbing/plumbers/acclimator.dm +++ b/code/modules/plumbing/plumbers/acclimator.dm @@ -1,5 +1,5 @@ -///Same as a tier 1 chem heater -#define HEATER_COFFICIENT 0.1 +///Same as a tier 3 chem heater +#define HEATER_COFFICIENT 0.3 ///Decimal point in rounding temperature #define TEMP_ROUNDING 0.01 ///Minimal allowed difference temperature range @@ -11,7 +11,7 @@ icon_state = "acclimator" base_icon_state = "acclimator" buffer = 200 - active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 2 + active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 2.5 ///towards wich temperature do we build? var/target_temperature = 300 diff --git a/code/modules/plumbing/plumbers/synthesizer.dm b/code/modules/plumbing/plumbers/synthesizer.dm index f7adedddd03..941837c8b6c 100644 --- a/code/modules/plumbing/plumbers/synthesizer.dm +++ b/code/modules/plumbing/plumbers/synthesizer.dm @@ -189,3 +189,24 @@ . = ..() dispensable_reagents = beer_reagents + +/obj/machinery/plumbing/synthesizer/mining + name = "mining synthesizer" + desc = "Can generate all the tasty plumbing chems that make mining more profitable or destructive." + + var/static/list/mining_chems = list( + /datum/reagent/toxin/acid, + /datum/reagent/toxin/acid/fluacid, + /datum/reagent/toxin/acid/nitracid, + /datum/reagent/teslium, + /datum/reagent/fuel, + /datum/reagent/thermite, + /datum/reagent/gunpowder, + /datum/reagent/liquid_dark_matter, + /datum/reagent/toxin/acid/industrial_waste, + ) + +/obj/machinery/plumbing/synthesizer/mining/Initialize(mapload, layer) + . = ..() + + dispensable_reagents = mining_chems diff --git a/code/modules/point/point.dm b/code/modules/point/point.dm index e07086c8753..00b2e995f24 100644 --- a/code/modules/point/point.dm +++ b/code/modules/point/point.dm @@ -110,12 +110,13 @@ /// either called immediately or in the tick after pointed() was called, as per the [DEFAULT_QUEUE_OR_CALL_VERB()] macro /mob/proc/_pointed(atom/pointing_at) if(client) //Clientless mobs can just go ahead and point + var/atom/atom_to_view_verify = pointing_at if(ismovable(pointing_at)) var/atom/movable/pointed_movable = pointing_at if(HAS_TRAIT(pointed_movable, TRAIT_SKIP_BASIC_REACH_CHECK) || pointing_at.loc.IsContainedAtomAccessible(pointing_at, src)) - pointing_at = pointed_movable.loc + atom_to_view_verify = pointed_movable.loc - if(!(pointing_at in view(client.view, src))) + if(!(atom_to_view_verify in view(client.view, src))) return FALSE if(iscarbon(src)) // special interactions for carbons var/mob/living/carbon/our_carbon = src diff --git a/code/modules/power/apc/apc_main.dm b/code/modules/power/apc/apc_main.dm index 2b1390e1564..57e3fa0b11d 100644 --- a/code/modules/power/apc/apc_main.dm +++ b/code/modules/power/apc/apc_main.dm @@ -100,7 +100,7 @@ var/long_term_power = 10 ///Automatically name the APC after the area is in var/auto_name = FALSE - ///Time to allow the APC to regain some power and to turn the channels back online + ///Time to allow the APC to regain some power and to turn the channels back online in seconds var/failure_timer = 0 ///Forces an update on the power use to ensure that the apc has enough power var/force_update = FALSE @@ -282,8 +282,8 @@ /obj/machinery/power/apc/on_saboteur(datum/source, disrupt_duration) . = ..() - disrupt_duration *= 0.1 // so, turns out, failure timer is in seconds, not deciseconds; without this, disruptions last 10 times as long as they probably should - energy_fail(disrupt_duration) + // failure timer is in seconds, not deciseconds, so we need to convert + energy_fail(disrupt_duration * 0.1) return TRUE /obj/machinery/power/apc/on_set_is_operational(old_value) @@ -589,7 +589,7 @@ if(!area?.requires_power) return if(failure_timer) - failure_timer-- + failure_timer = max(0, failure_timer - seconds_per_tick) force_update = TRUE return @@ -660,9 +660,11 @@ equipment = autoset(equipment, AUTOSET_ON) lighting = autoset(lighting, AUTOSET_ON) environ = autoset(environ, AUTOSET_ON) - if(nightshift_lights && low_power_nightshift_lights) + //If nightlights are on, and we're recovering from low power/nightlight event, we'll remove it. + var/nightshift_disabled = !(locate(/datum/round_event/nightshift) in SSevents.running) + if(nightshift_lights && (nightshift_disabled || low_power_nightshift_lights)) low_power_nightshift_lights = FALSE - if(!SSnightshift.nightshift_active) + if(nightshift_disabled) INVOKE_ASYNC(src, PROC_REF(set_nightshift), FALSE) if(cell_percent > APC_CHANNEL_ALARM_TRESHOLD) alarm_manager.clear_alarm(ALARM_POWER) diff --git a/code/modules/power/apc/apc_power_proc.dm b/code/modules/power/apc/apc_power_proc.dm index 7c00dc20c50..eb6474e9977 100644 --- a/code/modules/power/apc/apc_power_proc.dm +++ b/code/modules/power/apc/apc_power_proc.dm @@ -127,16 +127,15 @@ terminal.master = null terminal = null +/** + * Temporarily disables all power to the room for a set duration + * + * Some rooms are immune to this effect due to having important machines + * + * * duration - the duration of the power failure in seconds (not deciseconds) + */ /obj/machinery/power/apc/proc/energy_fail(duration) - for(var/obj/machinery/failing_machine in area.contents) - if(failing_machine.critical_machine) - return - - for(var/mob/living/silicon/ai as anything in GLOB.ai_list) - if(get_area(ai) == area) - return - - failure_timer = max(failure_timer, round(duration)) + failure_timer = max(failure_timer, round(duration, SSMACHINES_DT)) update() queue_icon_update() @@ -147,10 +146,9 @@ if(nightshift_lights == on) return //no change nightshift_lights = on - for (var/list/zlevel_turfs as anything in area.get_zlevel_turf_lists()) - for(var/turf/area_turf as anything in zlevel_turfs) - for(var/obj/machinery/light/night_light in area_turf) - if(night_light.nightshift_allowed) - night_light.nightshift_enabled = nightshift_lights - night_light.update(trigger = FALSE, play_sound = FALSE) // BUBBER EDIT CHANGE - LIGHTING - Original: update(FALSE) - CHECK_TICK + for(var/turf/area_turf as anything in area.get_turfs_from_all_zlevels()) + for(var/obj/machinery/light/night_light in area_turf) + if(night_light.nightshift_allowed) + night_light.nightshift_enabled = nightshift_lights + night_light.update(trigger = FALSE, play_sound = FALSE) // BUBBER EDIT CHANGE - LIGHTING - Original: update(FALSE) + CHECK_TICK diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index a8a729977f3..bfc4f55f558 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -689,11 +689,11 @@ GLOBAL_LIST_INIT(wire_node_generating_types, typecacheof(list( ////////////////////////////////////////////// // called when cable_coil is clicked on a turf -/obj/item/stack/cable_coil/proc/place_turf(turf/T, mob/user, dirnew) +/obj/item/stack/cable_coil/proc/place_turf(turf/target_turf, mob/user, dirnew) if(!isturf(user.loc)) return - if(!isturf(T) || T.underfloor_accessibility < UNDERFLOOR_INTERACTABLE || !T.can_have_cabling()) + if(!isturf(target_turf) || target_turf.underfloor_accessibility < UNDERFLOOR_INTERACTABLE || !target_turf.can_have_cabling()) to_chat(user, span_warning("You can only lay cables on catwalks and plating!")) return @@ -701,31 +701,31 @@ GLOBAL_LIST_INIT(wire_node_generating_types, typecacheof(list( to_chat(user, span_warning("There is no cable left!")) return - if(get_dist(T,user) > 1) // Too far + if(get_dist(target_turf,user) > 1) // Too far to_chat(user, span_warning("You can't lay cable at a place that far away!")) return - for(var/obj/structure/cable/C in T) - if(C.cable_layer & target_layer) + for(var/obj/structure/cable/old_cable in target_turf) + if(old_cable.cable_layer & target_layer) to_chat(user, span_warning("There's already a cable at that position!")) return - var/obj/structure/cable/C = new target_type(T) + var/obj/structure/cable/new_cable = new target_type(target_turf) //create a new powernet with the cable, if needed it will be merged later - var/datum/powernet/PN = new() - PN.add_cable(C) + var/datum/powernet/new_powernet = new() + new_powernet.add_cable(new_cable) for(var/dir_check in GLOB.cardinals) - C.mergeConnectedNetworks(dir_check) //merge the powernet with adjacents powernets - C.mergeConnectedNetworksOnTurf() //merge the powernet with on turf powernets + new_cable.mergeConnectedNetworks(dir_check) //merge the powernet with adjacents powernets + new_cable.mergeConnectedNetworksOnTurf() //merge the powernet with on turf powernets use(1) - if(C.shock(user, 50) && prob(50)) //fail - C.deconstruct() + if(new_cable.powernet.avail && new_cable.shock(user, 50) && prob(50)) + new_cable.deconstruct() - return C + return new_cable /obj/item/stack/cable_coil/five amount = 5 diff --git a/code/modules/power/lighting/light.dm b/code/modules/power/lighting/light.dm index 69ba3373a5d..0d77245a72e 100644 --- a/code/modules/power/lighting/light.dm +++ b/code/modules/power/lighting/light.dm @@ -84,6 +84,8 @@ var/power_consumption_rate = 20 ///break if moved, if false also makes it ignore if the wall its on breaks var/break_if_moved = TRUE + /// If TRUE we can break on init + var/allow_break_on_init = TRUE // create a new lighting fixture /obj/machinery/light/Initialize(mapload) @@ -129,13 +131,14 @@ /obj/machinery/light/post_machine_initialize() . = ..() #ifndef MAP_TEST - switch(fitting) - if("tube") - if(prob(2)) - break_light_tube(TRUE) - if("bulb") - if(prob(5)) - break_light_tube(TRUE) + if(allow_break_on_init) + switch(fitting) + if("tube") + if(prob(2)) + break_light_tube(TRUE) + if("bulb") + if(prob(5)) + break_light_tube(TRUE) #endif update(trigger = FALSE) diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index 22c24818165..8160c902140 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -78,6 +78,7 @@ sparks.attach(src) AddElement(/datum/element/simple_rotation) AddElement(/datum/element/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES) + AddComponent(/datum/component/usb_port, typecacheof(list(/obj/item/circuit_component/emitter), only_root_path = TRUE)) /obj/machinery/power/emitter/welded/Initialize(mapload) welded = TRUE @@ -190,6 +191,7 @@ log_game("[src] turned [active ? "ON" : "OFF"] by [key_name(user)] in [AREACOORD(src)]") investigate_log("turned [active ? "ON" : "OFF"] by [key_name(user)] at [AREACOORD(src)]", INVESTIGATE_ENGINE) update_appearance() + SEND_SIGNAL(src, COMSIG_EMITTER_MACHINE_SET_ON, active ? TRUE : FALSE) /obj/machinery/power/emitter/attack_animal(mob/living/simple_animal/user, list/modifiers) if(ismegafauna(user) && anchored) @@ -268,6 +270,7 @@ else fire_delay = rand(minimum_fire_delay,maximum_fire_delay) * fire_rate_mod shot_number = 0 + SEND_SIGNAL(src, COMSIG_EMITTER_MACHINE_ON_FIRE) return projectile /obj/machinery/power/emitter/can_be_unfasten_wrench(mob/user, silent) diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index b737ca8a4df..72e6b3985dd 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -1,5 +1,4 @@ #define SOLAR_GEN_RATE 2500 -#define OCCLUSION_DISTANCE 20 #define PANEL_Z_OFFSET 13 #define PANEL_EDGE_Z_OFFSET (PANEL_Z_OFFSET - 2) @@ -17,6 +16,7 @@ var/id + /// Tracks if the sun is obscured from the panel by the station (or something else) var/obscured = FALSE ///`[0-1]` measure of obscuration -- multipllier against power generation var/sunfrac = 0 @@ -204,30 +204,10 @@ if(azimuth_current != azimuth_target) visually_turn(azimuth_target) azimuth_current = azimuth_target - occlusion_setup() + var/turf/sun_turf = get_turf(src) + obscured = isnull(sun_turf) ? TRUE : sun_turf.is_sunlight_blocked() needs_to_update_solar_exposure = TRUE -///trace towards sun to see if we're in shadow -/obj/machinery/power/solar/proc/occlusion_setup() - obscured = TRUE - - var/distance = OCCLUSION_DISTANCE - var/target_x = round(sin(SSsun.azimuth), 0.01) - var/target_y = round(cos(SSsun.azimuth), 0.01) - var/x_hit = x - var/y_hit = y - var/turf/hit - - for(var/run in 1 to distance) - x_hit += target_x - y_hit += target_y - hit = locate(round(x_hit, 1), round(y_hit, 1), z) - if(IS_OPAQUE_TURF(hit)) - return - if(hit.x == 1 || hit.x == world.maxx || hit.y == 1 || hit.y == world.maxy) //edge of the map - break - obscured = FALSE - ///calculates the fraction of the sunlight that the panel receives /obj/machinery/power/solar/proc/update_solar_exposure() needs_to_update_solar_exposure = FALSE @@ -245,12 +225,9 @@ sunfrac = . /obj/machinery/power/solar/process() - if(machine_stat & BROKEN) - return - // space vines block out sunlight - var/obj/structure/spacevine/vine = locate(/obj/structure/spacevine) in loc - if(istype(vine) && !(/datum/spacevine_mutation/transparency in vine.mutations)) - unset_control() + // If the turf is sun blocked directly we have no hope of being able to see the sun so don't bother processing + // On the other hand if the station is blocking the sun we might we might be able to see it later, so check for that (in update_turn) + if((machine_stat & BROKEN) || isnull(loc) || HAS_TRAIT(loc, TRAIT_TURF_SUN_BLOCKED)) return if(control && (!powernet || control.powernet != powernet)) @@ -663,6 +640,5 @@ default_raw_text = "

    Welcome

    At greencorps we love the environment, and space. With this package you are able to help mother nature and produce energy without any usage of fossil fuel or plasma! Singularity energy is dangerous while solar energy is safe, which is why it's better. Now here is how you setup your own solar array.

    You can make a solar panel by wrenching the solar assembly onto a cable node. Adding a glass panel, any non reinforced glass will do, will finish the construction of your solar panel. It is that easy!

    Now after setting up 19 more of these solar panels you will want to create a solar tracker to keep track of our mother nature's gift, the sun. These are the same steps as before except you insert the tracker equipment circuit into the assembly before performing the final step of adding the glass. You now have a tracker! Now the last step is to add a computer to calculate the sun's movements and to send commands to the solar panels to change direction with the sun. Setting up the solar computer is the same as setting up any computer, so you should have no trouble in doing that. You do need to put a wire node under the computer, and the wire needs to be connected to the tracker.

    Congratulations, you should have a working solar array. If you are having trouble, here are some tips. Make sure all solar equipment are on a cable node, even the computer. You can always deconstruct your creations if you make a mistake.

    That's all to it, be safe, be green!

    " #undef SOLAR_GEN_RATE -#undef OCCLUSION_DISTANCE #undef PANEL_Z_OFFSET #undef PANEL_EDGE_Z_OFFSET diff --git a/code/modules/power/supermatter/supermatter_gas.dm b/code/modules/power/supermatter/supermatter_gas.dm index b6eb2804c28..01eb977325e 100644 --- a/code/modules/power/supermatter/supermatter_gas.dm +++ b/code/modules/power/supermatter/supermatter_gas.dm @@ -113,10 +113,10 @@ GLOBAL_LIST_INIT(sm_gas_behavior, init_sm_gas()) ) if(!consumed_co2) return - sm.absorbed_gasmix.gases[/datum/gas/carbon_dioxide][MOLES] -= consumed_co2 - sm.absorbed_gasmix.gases[/datum/gas/oxygen][MOLES] -= consumed_co2 - ASSERT_GAS(/datum/gas/pluoxium, sm.absorbed_gasmix) - sm.absorbed_gasmix.gases[/datum/gas/pluoxium][MOLES] += consumed_co2 + sm.absorbed_gasmix.adjust_gas(/datum/gas/carbon_dioxide, -consumed_co2) + sm.absorbed_gasmix.adjust_gas(/datum/gas/oxygen, -consumed_co2) + + sm.absorbed_gasmix.adjust_gas(/datum/gas/pluoxium, consumed_co2) /datum/sm_gas/plasma gas_path = /datum/gas/plasma @@ -178,7 +178,7 @@ GLOBAL_LIST_INIT(sm_gas_behavior, init_sm_gas()) var/consumed_miasma = sm.absorbed_gasmix.gases[/datum/gas/miasma][MOLES] * miasma_ratio if(!consumed_miasma) return - sm.absorbed_gasmix.gases[/datum/gas/miasma][MOLES] -= consumed_miasma + sm.absorbed_gasmix.adjust_gas(/datum/gas/miasma, -consumed_miasma) sm.external_power_trickle += consumed_miasma * MIASMA_POWER_GAIN sm.log_activation("miasma absorption") diff --git a/code/modules/power/thermoelectric_generator.dm b/code/modules/power/thermoelectric_generator.dm index 86620bd85bb..d7513294f07 100644 --- a/code/modules/power/thermoelectric_generator.dm +++ b/code/modules/power/thermoelectric_generator.dm @@ -92,8 +92,7 @@ Skyrat removal START, moved to modular file return TRUE /obj/machinery/power/thermoelectric_generator/crowbar_act(mob/living/user, obj/item/tool) - default_deconstruction_crowbar(tool) - return TRUE + return default_deconstruction_crowbar(user, tool) /obj/machinery/power/thermoelectric_generator/process() //Setting this number higher just makes the change in power output slower, it doesnt actualy reduce power output cause **math** diff --git a/code/modules/procedural_mapping/mapGenerators/lava_river.dm b/code/modules/procedural_mapping/mapGenerators/lava_river.dm index 59e430e1791..f1ab90ddf0a 100644 --- a/code/modules/procedural_mapping/mapGenerators/lava_river.dm +++ b/code/modules/procedural_mapping/mapGenerators/lava_river.dm @@ -18,7 +18,7 @@ /datum/map_generator_module/river var/river_type = /turf/open/lava/smooth - var/river_nodes = 4 + var/river_nodes = 3 // +1 from mapped-in one near the base /datum/map_generator_module/river/generate() var/datum/map_generator/lavaland/L = mother diff --git a/code/modules/procedural_mapping/mapGenerators/lavaland.dm b/code/modules/procedural_mapping/mapGenerators/lavaland.dm index 5251f5e8435..b638e7908dd 100644 --- a/code/modules/procedural_mapping/mapGenerators/lavaland.dm +++ b/code/modules/procedural_mapping/mapGenerators/lavaland.dm @@ -18,9 +18,7 @@ /datum/map_generator_module/splatter_layer/lavaland_tendrils spawnableTurfs = list() - spawnableAtoms = list(/obj/structure/spawner/lavaland = 5, - /obj/structure/spawner/lavaland/legion = 5, - /obj/structure/spawner/lavaland/goliath = 5) + spawnableAtoms = list(/mob/living/basic/mining/tendril = 15) /datum/map_generator/lavaland/ground_only modules = list(/datum/map_generator_module/bottom_layer/lavaland_default) diff --git a/code/modules/projectiles/ammunition/ballistic/pistol.dm b/code/modules/projectiles/ammunition/ballistic/pistol.dm index 56962984229..17539c3e359 100644 --- a/code/modules/projectiles/ammunition/ballistic/pistol.dm +++ b/code/modules/projectiles/ammunition/ballistic/pistol.dm @@ -22,11 +22,6 @@ desc = "A 10mm incendiary bullet casing." projectile_type = /obj/projectile/bullet/incendiary/c10mm -/obj/item/ammo_casing/c10mm/reaper - name = "10mm reaper bullet casing" - desc = "A 10mm reaper bullet casing." - projectile_type = /obj/projectile/bullet/c10mm/reaper - // 9mm (Makarov, Stechkin APS) /obj/item/ammo_casing/c9mm diff --git a/code/modules/projectiles/ammunition/ballistic/smg.dm b/code/modules/projectiles/ammunition/ballistic/smg.dm index 7e84bc1a918..e2be056126b 100644 --- a/code/modules/projectiles/ammunition/ballistic/smg.dm +++ b/code/modules/projectiles/ammunition/ballistic/smg.dm @@ -41,3 +41,8 @@ name = ".45 incendiary bullet casing" desc = "A .45 bullet casing." projectile_type = /obj/projectile/bullet/incendiary/c45 + +/obj/item/ammo_casing/c45/reaper + name = ".45 reaper bullet casing" + desc = "A .45 reaper bullet casing." + projectile_type = /obj/projectile/bullet/c45/reaper diff --git a/code/modules/projectiles/ammunition/energy/plasma.dm b/code/modules/projectiles/ammunition/energy/plasma.dm index 840244a3d67..ccc0c1c3157 100644 --- a/code/modules/projectiles/ammunition/energy/plasma.dm +++ b/code/modules/projectiles/ammunition/energy/plasma.dm @@ -2,11 +2,11 @@ projectile_type = /obj/projectile/plasma select_name = "plasma burst" fire_sound = 'sound/items/weapons/plasma_cutter.ogg' - delay = 15 - e_cost = LASER_SHOTS(40, STANDARD_CELL_CHARGE) + delay = 12 + e_cost = LASER_SHOTS(30, STANDARD_CELL_CHARGE) /obj/item/ammo_casing/energy/plasma/adv projectile_type = /obj/projectile/plasma/adv - delay = 10 - e_cost = LASER_SHOTS(100, STANDARD_CELL_CHARGE) + delay = 8 + e_cost = LASER_SHOTS(75, STANDARD_CELL_CHARGE) diff --git a/code/modules/projectiles/boxes_magazines/external/pistol.dm b/code/modules/projectiles/boxes_magazines/external/pistol.dm index afde03e6924..40af66c5367 100644 --- a/code/modules/projectiles/boxes_magazines/external/pistol.dm +++ b/code/modules/projectiles/boxes_magazines/external/pistol.dm @@ -111,25 +111,6 @@ MAGAZINE_TYPE_ARMORPIERCE ammo_type = /obj/item/ammo_casing/c10mm/ap -// Regal Condor (10mm) // - -/obj/item/ammo_box/magazine/r10mm - name = "regal condor magazine (10mm Reaper)" - desc = "A very expensive 10mm handgun magazine, suitable for the Regal Condor. Loaded with \"reaper\" rounds, which are dangerously effective against everything." - icon_state = "r10mm-8" - base_icon_state = "r10mm" - ammo_type = /obj/item/ammo_casing/c10mm/reaper - caliber = CALIBER_10MM - max_ammo = 8 - multiple_sprites = AMMO_BOX_PER_BULLET - multiple_sprite_use_base = TRUE - custom_materials = list( - /datum/material/iron = SHEET_MATERIAL_AMOUNT * 10, - /datum/material/gold = SHEET_MATERIAL_AMOUNT * 10, - /datum/material/silver = SHEET_MATERIAL_AMOUNT * 10, - /datum/material/plasma = SHEET_MATERIAL_AMOUNT * 10, - ) - // M1911 (.45) // /obj/item/ammo_box/magazine/m45 @@ -153,3 +134,22 @@ caliber = CALIBER_50AE max_ammo = 7 multiple_sprites = AMMO_BOX_PER_BULLET + +// Regal Condor (.45) // + +/obj/item/ammo_box/magazine/r45 + name = "regal condor magazine (.45 Reaper)" + desc = "A very expensive .45 handgun magazine, suitable for the Regal Condor. Loaded with \"reaper\" rounds, which are dangerously effective against everything." + icon_state = "r45-8" + base_icon_state = "r45" + ammo_type = /obj/item/ammo_casing/c45/reaper + caliber = CALIBER_10MM + max_ammo = 8 + multiple_sprites = AMMO_BOX_PER_BULLET + multiple_sprite_use_base = TRUE + custom_materials = list( + /datum/material/iron = SHEET_MATERIAL_AMOUNT * 10, + /datum/material/gold = SHEET_MATERIAL_AMOUNT * 10, + /datum/material/silver = SHEET_MATERIAL_AMOUNT * 10, + /datum/material/plasma = SHEET_MATERIAL_AMOUNT * 10, + ) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index cdc3c71f700..6673f2b631d 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -125,6 +125,7 @@ give_gun_safeties() // SKYRAT EDIT ADDITION - GUN SAFETIES give_manufacturer_examine() // SKYRAT EDIT ADDITON - MANUFACTURER EXAMINE add_bayonet_point() + add_deep_lore() RegisterSignal(src, COMSIG_ITEM_IN_UNWRAPPED_TRAITOR_MAIL, PROC_REF(on_mail_unwrap)) /obj/item/gun/Destroy() @@ -155,6 +156,10 @@ /obj/item/gun/proc/add_bayonet_point() return +/// For when you want to add the lore element to a gun, this is the proc to use. +/obj/item/gun/proc/add_deep_lore() + return + /obj/item/gun/Exited(atom/movable/gone, direction) . = ..() if(gone == pin) @@ -465,8 +470,9 @@ balloon_alert(user, "trigger locked, firing pin needed!") return FALSE +/// Called to put ammo back in a gun which recharges itself, should call super if successful /obj/item/gun/proc/recharge_newshot() - return + SEND_SIGNAL(src, COMSIG_GUN_REPLENISHED_CHARGE) /obj/item/gun/proc/process_burst(mob/living/user, atom/target, message = TRUE, params=null, zone_override = "", random_spread = 0, burst_spread_mult = 0, iteration = 0) if(!user || !firing_burst) diff --git a/code/modules/projectiles/guns/ballistic/bows/bow_arrows.dm b/code/modules/projectiles/guns/ballistic/bows/bow_arrows.dm index c50694aaf61..3d247b63e85 100644 --- a/code/modules/projectiles/guns/ballistic/bows/bow_arrows.dm +++ b/code/modules/projectiles/guns/ballistic/bows/bow_arrows.dm @@ -117,8 +117,8 @@ /obj/projectile/bullet/arrow/holy/Initialize(mapload) . = ..() - //50 damage to revenants - AddElement(/datum/element/bane, mob_biotypes = MOB_SPIRIT, damage_multiplier = 0, added_damage = 30) + // 50 damage to revenants + AddComponent(/datum/component/bane, affected_biotypes = MOB_SPIRIT, added_damage = 30) /// plastic arrows // completely dogshit quality and they break when they hit something. @@ -190,5 +190,4 @@ /obj/projectile/bullet/arrow/ashen/Initialize(mapload) . = ..() - AddElement(/datum/element/bane, mob_biotypes = MOB_MINING, damage_multiplier = 0, added_damage = 40) - + AddComponent(/datum/component/bane, affected_biotypes = MOB_MINING, added_damage = 40) diff --git a/code/modules/projectiles/guns/ballistic/pistol.dm b/code/modules/projectiles/guns/ballistic/pistol.dm index ff703b751fb..cfd437e441b 100644 --- a/code/modules/projectiles/guns/ballistic/pistol.dm +++ b/code/modules/projectiles/guns/ballistic/pistol.dm @@ -61,6 +61,17 @@ empty_indicator = TRUE suppressor_x_offset = 12 +/obj/item/gun/ballistic/automatic/pistol/clandestine/add_deep_lore() + AddElement(/datum/element/examine_lore, \ + lore = "Manufactured by Scarborough Arms, the Ansem is regarded as one of the best sidearms on the market. Minimal recoil combined with \ + high stopping power makes it a favourite amongst soldiers of fortune across known space.
    \ +
    \ + The ease of concealment due to the weapon's sleek profile has given it a well-earned reputation as the 'smuggler's gun of course'. While \ + space pirate bands tend to favour the HDS-1 created by Nanotrasen due to their low maintenance cost, the Ansem has seen plenty of use by \ + mercernaries, hitmen and espionage agents. Dozens of seized Ansem pistols line evidence lockups across the Spinward. Many with extremely \ + long and bloodied histories from years of service amongst underground criminal elements." \ + ) + /obj/item/gun/ballistic/automatic/pistol/clandestine/fisher name = "\improper Ansem/SC pistol" desc = "A modified variant of the Ansem, spiritual successor to the Makarov, featuring an integral suppressor and push-button trigger on the grip \ @@ -75,6 +86,8 @@ /obj/item/gun/ballistic/automatic/pistol/clandestine/fisher/Initialize(mapload) . = ..() underbarrel = new /obj/item/gun/energy/recharge/fisher(src) + +/obj/item/gun/ballistic/automatic/pistol/clandestine/fisher/add_deep_lore() AddElement(/datum/element/examine_lore, \ lore = "The Ansem/SC is a Scarborough Arms overhaul suite for their own Ansem handgun, designed for special operators who operate operationally, \ especially against people who like using lightbulbs.
    \ @@ -126,6 +139,18 @@ lock_back_sound = 'sound/items/weapons/gun/pistol/slide_lock.ogg' bolt_drop_sound = 'sound/items/weapons/gun/pistol/slide_drop.ogg' +/obj/item/gun/ballistic/automatic/pistol/m1911/add_deep_lore() + AddElement(/datum/element/examine_lore, \ + lore = "The Colt M1911, created by John Moses Browning centuries ago, is the primordial ancestor of modern automatic firearms. \ + Somehow, to this day, there are still officers who refuse to utilize anything that isn't chambered in 'God's Caliber'.
    \ +
    \ + Few want to tell any of these people that .45 ACP has struggled to puncture modern ballistic plating for almost five centuries.
    \ +
    \ + You are VERY confident that this particular example was lathed this decade. Most M1911's seen in the wild today are recreations of the weapon \ + made with modern alloyed metals and manufactoring techniques, mass produced for the consumer market. This does not stop fraudsters from \ + claiming that their weapon is a 'family heirloom' that has saved them from various conflicts that they insist they participated in." \ + ) + /** * Weak 1911 for syndicate chimps. It comes in a 4 TC kit. * 15 damage every.. second? 7 shots to kill. Not fast. @@ -137,6 +162,8 @@ projectile_wound_bonus = -12 pin = /obj/item/firing_pin/monkey +/obj/item/gun/ballistic/automatic/pistol/m1911/chimpgun/add_deep_lore() + return /obj/item/gun/ballistic/automatic/pistol/m1911/no_mag spawnwithmagazine = FALSE @@ -184,17 +211,30 @@ name = "\improper Regal Condor" desc = "Unlike the Desert Eagle, this weapon seems to utilize some kind of advanced internal stabilization system to significantly \ reduce felt recoil and increase overall accuracy, at the cost of using a smaller caliber. \ - This does allow it to fire a very quick 2-round burst. Uses 10mm ammo." + This allows it to fire a very quick 2-round burst. Chambered in .45." icon_state = "reagle" inhand_icon_state = "deagleg" burst_size = 2 burst_delay = 1 projectile_damage_multiplier = 1.25 - accepted_magazine_type = /obj/item/ammo_box/magazine/r10mm + accepted_magazine_type = /obj/item/ammo_box/magazine/r45 actions_types = list(/datum/action/item_action/toggle_firemode) obj_flags = UNIQUE_RENAME // if you did the sidequest, you get the customization custom_materials = list(/datum/material/gold = SHEET_MATERIAL_AMOUNT * 30, /datum/material/silver = SHEET_MATERIAL_AMOUNT * 25, /datum/material/iron = SHEET_MATERIAL_AMOUNT * 11.5, /datum/material/telecrystal = SHEET_MATERIAL_AMOUNT * 4) +/obj/item/gun/ballistic/automatic/pistol/deagle/regal/add_deep_lore() + AddElement(/datum/element/examine_lore, \ + lore = "One of the Culling Arms of the Tiger Cooperative, a collection of relic weapons said to have come to Martinson in a frenzied vision from \ + God to enact holy retribution upon the enemies of the faith. Almost all examples of these guns are replicas of the original pattern. This one is no \ + different. However, it carries some of the gravitus of the original firearm. And, some say, the holy might that it wielded against the enemies of the cult.
    \ +
    \ + The fact that you are looking at this relic weapon means one of two things.
    \ +
    \ + A) A Tiger Cooperative evangelist has died during or before they could commit a bloody massacre in the name of God. Or
    \ +
    \ + B) You are that evangelist, and will soon be adding another chapter to this gun's dark history." \ + ) + /obj/item/gun/ballistic/automatic/pistol/aps name = "\improper Stechkin APS machine pistol" desc = "A modernized reproduction of an old Soviet machine pistol. It fires quickly, but kicks like a mule. Uses 9mm ammo. Has a threaded barrel for suppressors." //SKYRAT EDIT @@ -229,10 +269,9 @@ #define DOORHICKEY_GUN_MIN_DAMAGE 70 #define DOORHICKEY_GUN_MAX_DAMAGE 140 -/obj/item/gun/ballistic/automatic/pistol/doorhickey +/obj/item/gun/ballistic/automatic/pistol/doohickey name = "\improper Liberator" - desc = "A poorly made 3D printed \"gun\", only capable of firing a single shot. Well-known throughout the Spinward Sector \ - after an incident where 3 assistants were killed by shrapnel from such a device exploding while attempting to shoot a mouse." + desc = "A poorly made 3D printed \"gun\", only capable of firing a single shot." icon_state = "doorhickey" custom_materials = list(/datum/material/plastic = SHEET_MATERIAL_AMOUNT * 2) bolt_type = BOLT_TYPE_NO_BOLT @@ -247,7 +286,7 @@ projectile_damage_multiplier = 0.5 spread = 10 -/obj/item/gun/ballistic/automatic/pistol/doorhickey/unload_ammo(mob/living/user, forced = FALSE) +/obj/item/gun/ballistic/automatic/pistol/doohickey/unload_ammo(mob/living/user, forced = FALSE) if (forced) return ..() @@ -258,7 +297,7 @@ return . = ..() -/obj/item/gun/ballistic/automatic/pistol/doorhickey/load_gun(obj/item/ammo, mob/living/user) +/obj/item/gun/ballistic/automatic/pistol/doohickey/load_gun(obj/item/ammo, mob/living/user) . = ..() if (!.) return @@ -272,7 +311,7 @@ unload_ammo(user, forced = TRUE) return FALSE -/obj/item/gun/ballistic/automatic/pistol/doorhickey/process_fire(atom/target, mob/living/user, message, params, zone_override, bonus_spread) +/obj/item/gun/ballistic/automatic/pistol/doohickey/process_fire(atom/target, mob/living/user, message, params, zone_override, bonus_spread) var/dmg_multiplier = 1 if (get_dist(target, user) <= 1) @@ -291,7 +330,7 @@ . = ..() projectile_damage_multiplier /= dmg_multiplier -/obj/item/gun/ballistic/automatic/pistol/doorhickey/shoot_live_shot(mob/living/user, pointblank = FALSE, atom/pbtarget = null, message = TRUE) +/obj/item/gun/ballistic/automatic/pistol/doohickey/shoot_live_shot(mob/living/user, pointblank = FALSE, atom/pbtarget = null, message = TRUE) . = ..() if (!.) return @@ -330,6 +369,26 @@ new /obj/effect/decal/cleanable/plastic(get_turf(src)) take_damage(damage_to_take) +/obj/item/gun/ballistic/automatic/pistol/doohickey/add_deep_lore() + AddElement(/datum/element/examine_lore, \ + lore = "The Liberator pattern, according to digital historians, was first posted to a fringe imageboard on the NTNet. The post included a now dead \ + link to a defuncting hosting service through which board members were encouraged to download and 'admire' the design. The thread's author began their \ + post by describing their extreme vitriolic hatred of so-called 'moon men' amongst the Nanotrasen 'elites'. And that, through 'the sauce', they had \ + been shown a means to 'end the oppression of Luna's Tormentors'. They called it the 'Liberator' as a result.
    \ +
    \ + Response to this thread began as skeptism amongst posters regarding the 3D pattern. Many highlighted the dubious functionality, let alone safe operation \ + of a gun created using cheap plastic and minimal machined parts firing a high pressure round through an unrifled barrel. But the thread suddenly began to \ + gain traction immediately following a particular news article published by the Spinward Dove, a respected editorial in the Spinward Sector. The author of this \ + article recounts that, during a particularly brisk day in New Moscow, they observed three off-duty Nanotrasen assistants attempting to use what the author \ + described as a 'bizarre plastic doohickey' to shoot a mouse at point blank. The horrific aftermath, and images of the rattled but otherwise unscathed mouse, lead many \ + to try and find from where these now crippled assistants had come across such an absurd device. Word spread of the post, and its author's continuously nonsensical \ + rants regarding their hated foe in other areas of the imageboard.
    \ +
    \ + The author of the thread returned immediately following the news, claiming that those who frequented the imageboard had 'stolen' their 'dreams of freedom', and \ + that clearly the moon men were attempting to discredit their invention through this publicity stunt. A slur-laiden rant from the thread author followed this declaration, \ + leading to the the moderators of the imageboard to step in and close the thread for good." \ + ) + /obj/item/disk/design_disk/liberator name = "illegal 3D printer design disk" diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 66406652857..56905094c51 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -200,6 +200,7 @@ /obj/item/gun/energy/recharge_newshot(no_cyborg_drain) if (!ammo_type || !cell) return + if(use_cyborg_cell && !no_cyborg_drain) if(iscyborg(loc)) var/mob/living/silicon/robot/robot = loc @@ -207,12 +208,14 @@ var/obj/item/ammo_casing/energy/shot = ammo_type[select] //Necessary to find cost of shot if(robot.cell.use(shot.e_cost)) //Take power from the borg... cell.give(shot.e_cost) //... to recharge the shot + if(!chambered) var/obj/item/ammo_casing/energy/AC = ammo_type[select] if(cell.charge >= AC.e_cost) //if there's enough power in the cell cell... chambered = AC //...prepare a new shot based on the current ammo type selected if(!chambered.loaded_projectile) chambered.newshot() + return ..() /obj/item/gun/energy/handle_chamber() if(chambered && !chambered.loaded_projectile) //if loaded_projectile is null, i.e the shot has been fired... diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index 3e18975c028..a9d6e987ae8 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -273,7 +273,7 @@ new /obj/effect/temp_visual/explosion/fast(get_turf(target)) for(var/turf/closed/mineral/mineral_turf in RANGE_TURFS(2, target) - target) - mineral_turf.gets_drilled(firer, 0.1) + mineral_turf.drill_aoe(firer, 0.1) for(var/mob/living/living_mob in range(2, target) - firer - target) if(!ismining(living_mob)) @@ -407,7 +407,6 @@ // Recalculate recharge time after adding or removing cooldown mods. /obj/item/borg/upgrade/modkit/cooldown/proc/get_recharge_time(obj/item/gun/energy/recharge/kinetic_accelerator/KA) - var/new_recharge_time = initial(KA.recharge_time) for(var/obj/item/borg/upgrade/modkit/modkit_upgrade as anything in KA.modkits) if(istype(modkit_upgrade, src)) @@ -415,18 +414,15 @@ return new_recharge_time - /obj/item/borg/upgrade/modkit/cooldown/install(obj/item/gun/energy/recharge/kinetic_accelerator/KA, mob/user) . = ..() if(.) KA.recharge_time = get_recharge_time(KA) - /obj/item/borg/upgrade/modkit/cooldown/uninstall(obj/item/gun/energy/recharge/kinetic_accelerator/KA) ..() KA.recharge_time = get_recharge_time(KA) - /obj/item/borg/upgrade/modkit/cooldown/minebot name = "minebot cooldown decrease" desc = "Decreases the cooldown of a kinetic accelerator. Only rated for minebot use." @@ -438,73 +434,84 @@ minebot_upgrade = TRUE minebot_exclusive = TRUE - -//AoE blasts -/obj/item/borg/upgrade/modkit/aoe +// AoE blasts +// These are a subtype of cooldown so they can affect firing speed +/obj/item/borg/upgrade/modkit/cooldown/aoe modifier = 0 cost = 10 - denied_type = /obj/item/borg/upgrade/modkit/aoe + denied_type = /obj/item/borg/upgrade/modkit/cooldown/aoe maximum_of_type = 1 + /// Does the AOE mine turfs? var/turf_aoe = FALSE + /// Have we taken another kit's AOE? var/stats_stolen = FALSE + /// Multiplier for mob damage + var/damage_modifier = 0 -/obj/item/borg/upgrade/modkit/aoe/install(obj/item/gun/energy/recharge/kinetic_accelerator/KA, mob/user) +/obj/item/borg/upgrade/modkit/cooldown/aoe/install(obj/item/gun/energy/recharge/kinetic_accelerator/KA, mob/user) . = ..() - if(.) - for(var/obj/item/borg/upgrade/modkit/aoe/AOE in KA.modkits) //make sure only one of the aoe modules has values if somebody has multiple - if(AOE.stats_stolen || AOE == src) - continue - modifier += AOE.modifier //take its modifiers - AOE.modifier = 0 - turf_aoe += AOE.turf_aoe - AOE.turf_aoe = FALSE - AOE.stats_stolen = TRUE + if(!.) + return + for(var/obj/item/borg/upgrade/modkit/cooldown/aoe/AOE in KA.modkits) //make sure only one of the aoe modules has values if somebody has multiple + if(AOE.stats_stolen || AOE == src) + continue + modifier += AOE.modifier //take its modifiers + damage_modifier += AOE.damage_modifier + AOE.modifier = 0 + AOE.damage_modifier = 0 + turf_aoe += AOE.turf_aoe + AOE.turf_aoe = FALSE + AOE.stats_stolen = TRUE -/obj/item/borg/upgrade/modkit/aoe/uninstall(obj/item/gun/energy/recharge/kinetic_accelerator/KA) +/obj/item/borg/upgrade/modkit/cooldown/aoe/uninstall(obj/item/gun/energy/recharge/kinetic_accelerator/KA) ..() modifier = initial(modifier) //get our modifiers back + damage_modifier = initial(damage_modifier) turf_aoe = initial(turf_aoe) stats_stolen = FALSE -/obj/item/borg/upgrade/modkit/aoe/modify_projectile(obj/projectile/kinetic/K) +/obj/item/borg/upgrade/modkit/cooldown/aoe/modify_projectile(obj/projectile/kinetic/K) K.name = "kinetic explosion" -/obj/item/borg/upgrade/modkit/aoe/projectile_strike(obj/projectile/kinetic/kinetic_blast, turf/target_turf, atom/target, obj/item/gun/energy/recharge/kinetic_accelerator/KA) +/obj/item/borg/upgrade/modkit/cooldown/aoe/projectile_strike(obj/projectile/kinetic/kinetic_blast, turf/target_turf, atom/target, obj/item/gun/energy/recharge/kinetic_accelerator/KA) if(stats_stolen) return new /obj/effect/temp_visual/explosion/fast(target_turf) if(turf_aoe) - for(var/T in RANGE_TURFS(2, target_turf) - target_turf) + for(var/T in RANGE_TURFS(1, target_turf) - target_turf) if(ismineralturf(T)) var/turf/closed/mineral/M = T M.gets_drilled(kinetic_blast.firer, 0.1) - if(modifier) - for(var/mob/living/living_mob in range(2, target) - kinetic_blast.firer - target) + if(!damage_modifier) + return - if(!ismining(living_mob)) - continue + for(var/mob/living/living_mob in range(1, target) - kinetic_blast.firer - target) + if(!ismining(living_mob)) + continue + var/armor = living_mob.run_armor_check(kinetic_blast.def_zone, kinetic_blast.armor_flag, armour_penetration = kinetic_blast.armour_penetration) + living_mob.apply_damage(kinetic_blast.damage * damage_modifier, kinetic_blast.damage_type, kinetic_blast.def_zone, armor) + to_chat(living_mob, span_userdanger("You're struck by a [kinetic_blast.name]!")) - var/armor = living_mob.run_armor_check(kinetic_blast.def_zone, kinetic_blast.armor_flag, armour_penetration = kinetic_blast.armour_penetration) - living_mob.apply_damage(kinetic_blast.damage*modifier, kinetic_blast.damage_type, kinetic_blast.def_zone, armor) - to_chat(living_mob, span_userdanger("You're struck by a [kinetic_blast.name]!")) - -/obj/item/borg/upgrade/modkit/aoe/turfs +/obj/item/borg/upgrade/modkit/cooldown/aoe/turfs name = "mining explosion" desc = "Causes the kinetic accelerator to destroy rock in an AoE." turf_aoe = TRUE + // Negates one CD modifier + modifier = -/obj/item/borg/upgrade/modkit/cooldown::modifier -/obj/item/borg/upgrade/modkit/aoe/mobs +/obj/item/borg/upgrade/modkit/cooldown/aoe/mobs name = "offensive explosion" desc = "Causes the kinetic accelerator to damage mobs in an AoE." - modifier = 1 + damage_modifier = 1 -/obj/item/borg/upgrade/modkit/aoe/mobs/andturfs +/obj/item/borg/upgrade/modkit/cooldown/aoe/mobs/andturfs name = "offensive mining explosion" desc = "Causes the kinetic accelerator to destroy rock and damage mobs in an AoE." turf_aoe = TRUE + modifier = -1 // Slightly better than normal turf AOE as its a rare find -//Minebot passthrough +// Minebot passthrough /obj/item/borg/upgrade/modkit/minebot_passthrough name = "minebot passthrough" desc = "Causes kinetic accelerator shots to pass through minebots." diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index de7922b8ef8..a47d2521866 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -11,8 +11,6 @@ /obj/item/gun/energy/laser/Initialize(mapload) . = ..() - add_deep_lore() - // Only regular lasguns can be slapcrafted if(type != /obj/item/gun/energy/laser) return @@ -305,7 +303,7 @@ // Laser Gun -/obj/item/gun/energy/laser/proc/add_deep_lore() +/obj/item/gun/energy/laser/add_deep_lore() AddElement(/datum/element/examine_lore, \ lore_hint = span_notice("You can [EXAMINE_HINT("look closer")] to learn a little more about [src]."), \ lore = "The NT Type 5 Heat Delivery System (sometimes referred to as the HDS-5 in promotional material) is what truly put Nanotrasen \ diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index 20560880fea..1087fa70b03 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -117,29 +117,40 @@ if(cell) . += span_notice("[src] is [round(cell.percent())]% charged.") -/obj/item/gun/energy/plasmacutter/attackby(obj/item/I, mob/user) - var/charge_multiplier = 0 //2 = Refined stack, 1 = Ore - if(istype(I, /obj/item/stack/sheet/mineral/plasma)) +/obj/item/gun/energy/plasmacutter/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + var/charge_multiplier = 0 + if(istype(tool, /obj/item/stack/sheet/mineral/plasma)) charge_multiplier = 2 - if(istype(I, /obj/item/stack/ore/plasma)) + else if(istype(tool, /obj/item/stack/ore/plasma)) charge_multiplier = 1 - if(charge_multiplier) - if(cell.charge == cell.maxcharge) - balloon_alert(user, "already fully charged!") - return - I.use(1) - cell.give(0.5 * STANDARD_CELL_CHARGE * charge_multiplier) - balloon_alert(user, "cell recharged") - else - ..() + + if(!charge_multiplier) + return NONE + + if(cell.charge == cell.maxcharge) + balloon_alert(user, "already fully charged!") + return ITEM_INTERACT_BLOCKING + + var/obj/item/stack/sheet = tool + if (!sheet.use(1)) + return ITEM_INTERACT_BLOCKING + + cell.give(0.2 * STANDARD_CELL_CHARGE * charge_multiplier) + balloon_alert(user, "cell recharged") + return ITEM_INTERACT_SUCCESS /obj/item/gun/energy/plasmacutter/emp_act(severity) . = ..() - if(isliving(loc)) - var/mob/living/user = loc - user.visible_message(span_danger("Concentrated plasma discharges from [src] onto [user], burning them!"), span_userdanger("[src] malfunctions, spewing concentrated plasma onto you! It burns!")) - user.adjust_fire_stacks(4) - user.ignite_mob() + if(. & EMP_PROTECT_CONTENTS) + return + + if(!isliving(loc)) + return + + var/mob/living/user = loc + user.visible_message(span_danger("Concentrated plasma discharges from [src] onto [user], burning them!"), span_userdanger("[src] malfunctions, spewing concentrated plasma onto you! It burns!")) + user.adjust_fire_stacks(4) + user.ignite_mob() // Can we weld? Plasma cutter does not use charge continuously. // Amount cannot be defaulted to 1: most of the code specifies 0 in the call. @@ -163,16 +174,15 @@ return (!QDELETED(cell) && cell.use(used ? used * PLASMA_CUTTER_CHARGE_WELD : PLASMA_CUTTER_CHARGE_WELD)) /obj/item/gun/energy/plasmacutter/use_tool(atom/target, mob/living/user, delay, amount=1, volume=0, datum/callback/extra_checks) + if(!amount) + return ..(amount = 1) - if(amount) - var/mutable_appearance/sparks = mutable_appearance('icons/effects/welding_effect.dmi', "welding_sparks", GASFIRE_LAYER, src, ABOVE_LIGHTING_PLANE) - target.add_overlay(sparks) - LAZYADD(update_overlays_on_z, sparks) - . = ..() - LAZYREMOVE(update_overlays_on_z, sparks) - target.cut_overlay(sparks) - else - . = ..(amount=1) + var/mutable_appearance/sparks = mutable_appearance('icons/effects/welding_effect.dmi', "welding_sparks", GASFIRE_LAYER, src, ABOVE_LIGHTING_PLANE) + target.add_overlay(sparks) + LAZYADD(update_overlays_on_z, sparks) + . = ..() + LAZYREMOVE(update_overlays_on_z, sparks) + target.cut_overlay(sparks) /obj/item/gun/energy/plasmacutter/try_fire_gun(atom/target, mob/living/user, params) return fire_gun(target, user, user.Adjacent(target) && !isturf(target), params) diff --git a/code/modules/projectiles/guns/magic.dm b/code/modules/projectiles/guns/magic.dm index 2119b904e92..f32d53cae10 100644 --- a/code/modules/projectiles/guns/magic.dm +++ b/code/modules/projectiles/guns/magic.dm @@ -107,8 +107,10 @@ return charges /obj/item/gun/magic/recharge_newshot() - if (charges && chambered && !chambered.loaded_projectile) - chambered.newshot() + if (!charges || !chambered || chambered.loaded_projectile) + return + chambered.newshot() + return ..() /obj/item/gun/magic/handle_chamber() if(chambered && !chambered.loaded_projectile) //if BB is null, i.e the shot has been fired... diff --git a/code/modules/projectiles/guns/magic/staff.dm b/code/modules/projectiles/guns/magic/staff.dm index e0522427e8c..73d48d7b388 100644 --- a/code/modules/projectiles/guns/magic/staff.dm +++ b/code/modules/projectiles/guns/magic/staff.dm @@ -113,6 +113,12 @@ user.death() // If you got put into crit by the mobs we'll finish you off return MANUAL_SUICIDE +/obj/item/gun/magic/staff/animate/animate_atom_living(mob/living/owner) + var/mob/living/basic/mimic/copy/ranged/living_staff = new(drop_location(), src, owner) + QDEL_NULL(living_staff.ai_controller) + living_staff.ai_controller = new /datum/ai_controller/basic_controller/mimic_copy/gun/animator(living_staff) + return living_staff + /// Heals people and even raises the dead /obj/item/gun/magic/staff/healing name = "staff of healing" @@ -188,6 +194,7 @@ /obj/projectile/magic/animate, /obj/projectile/magic/antimagic, /obj/projectile/magic/arcane_barrage, + /obj/projectile/magic/babel, /obj/projectile/magic/bounty, ///obj/projectile/magic/change, //SKYRAT EDIT REMOVAL /obj/projectile/magic/death, @@ -195,15 +202,20 @@ /obj/projectile/magic/fetch, /obj/projectile/magic/fireball, /obj/projectile/magic/flying, + /obj/projectile/magic/freeze, + /obj/projectile/magic/levitate, /obj/projectile/magic/locker, /obj/projectile/magic/necropotence, + /obj/projectile/magic/plague, + /obj/projectile/magic/rebellion, /obj/projectile/magic/resurrection, - /obj/projectile/magic/babel, + /obj/projectile/magic/shrink, /obj/projectile/magic/spellblade, + /obj/projectile/magic/swap, /obj/projectile/magic/teleport, + /obj/projectile/magic/tentacle_staff, /obj/projectile/magic/wipe, - /obj/projectile/temp/chill, - /obj/projectile/magic/shrink + /obj/projectile/temp/chill ) /obj/item/gun/magic/staff/chaos/unrestricted diff --git a/code/modules/projectiles/guns/magic/wand.dm b/code/modules/projectiles/guns/magic/wand.dm index 43efeda1e4f..c2334b5c4c5 100644 --- a/code/modules/projectiles/guns/magic/wand.dm +++ b/code/modules/projectiles/guns/magic/wand.dm @@ -356,6 +356,15 @@ . = ..() return SHAME +// Animating a nothing wand makes it into an animating wand (and also animates it) +/obj/item/gun/magic/wand/nothing/animate_atom_living(mob/living/owner) + var/obj/item/gun/magic/wand/animate/animated_wand = new(loc) + animated_wand.charges = charges + animated_wand.name = name + "?" + + qdel(src) + return animated_wand.animate_atom_living(owner) + /// Also wand of doing fuck all /obj/item/gun/magic/wand/nothing/fake_resurrection name = "holy staff" @@ -365,6 +374,9 @@ base_icon_state = "revivewand" ammo_type = /obj/item/ammo_casing/magic +/obj/item/gun/magic/wand/nothing/fake_resurrection/animate_atom_living(mob/living/owner) + return new /mob/living/basic/mimic/copy/ranged(drop_location(), src, owner) + /// Wand of making things small /obj/item/gun/magic/wand/shrink name = "wand of shrinking" diff --git a/code/modules/projectiles/guns/magic/wands/wand_animate.dm b/code/modules/projectiles/guns/magic/wands/wand_animate.dm new file mode 100644 index 00000000000..04d4e8b0d61 --- /dev/null +++ b/code/modules/projectiles/guns/magic/wands/wand_animate.dm @@ -0,0 +1,56 @@ + +/// Wand of making objects alive +/obj/item/gun/magic/wand/animate + name = "wand of animation" + desc = "This wand is attuned to life and will animate effected objects into destructive servants." + school = SCHOOL_EVOCATION + ammo_type = /obj/item/ammo_casing/magic/animate + icon_state = "animatewand" + base_icon_state = "animatewand" + fire_sound = 'sound/effects/magic/staff_animation.ogg' + max_charges = 10 + +/obj/item/gun/magic/wand/animate/zap_self(mob/living/user, suicide = FALSE) + . = ..() + to_chat(user, span_warning("You animate one of your own possessions!")) + charges-- + var/list/possessions = user.get_equipped_items() + if (!length(possessions)) + to_chat(user, span_notice("...but you don't have any.")) + return + + var/obj/some_item = pick(possessions) + user.dropItemToGround(some_item) + some_item.animate_atom_living(user) + +/obj/item/gun/magic/wand/animate/do_suicide(mob/living/user) + charges-- + if (!iscarbon(user)) + user.visible_message(span_suicide("... but [user] is already animate!")) + return SHAME + var/mob/living/carbon/suicider = user + var/obj/item/animate_part = suicider.get_organ_slot(ORGAN_SLOT_BRAIN) || suicider.get_bodypart(BODY_ZONE_HEAD) + if (!animate_part) + return SHAME + + var/turf/destination = user.drop_location() + + if (isorgan(animate_part)) + var/obj/item/organ/brain = animate_part + brain.Remove(user, special = FALSE) + else + var/obj/item/bodypart/head = animate_part + head.dismember(BRUTE) + + animate_part.forceMove(destination) + animate_part.animate_atom_living() + if (user.stat != DEAD) + return SHAME + user.set_suicide(TRUE) + return MANUAL_SUICIDE + +/obj/item/gun/magic/wand/animate/animate_atom_living(mob/living/owner) + var/mob/living/basic/mimic/copy/ranged/living_wand = new(drop_location(), src, owner, FALSE, TRUE) // It's already got eyes + QDEL_NULL(living_wand.ai_controller) + living_wand.ai_controller = new /datum/ai_controller/basic_controller/mimic_copy/gun/animator(living_wand) + return living_wand diff --git a/code/modules/projectiles/guns/magic/wands/wand_babel.dm b/code/modules/projectiles/guns/magic/wands/wand_babel.dm new file mode 100644 index 00000000000..973ae6a6b78 --- /dev/null +++ b/code/modules/projectiles/guns/magic/wands/wand_babel.dm @@ -0,0 +1,24 @@ +/** + * Scrambles the languages of someone you shoot. + */ +/obj/item/gun/magic/wand/babel + name = "rod of babel" + desc = "The incredible power of this wand causes victims to forget all of the languages they know, and learn a new one." + school = SCHOOL_TRANSMUTATION + ammo_type = /obj/item/ammo_casing/magic/babel + icon_state = "babelwand" + base_icon_state = "babelwand" + fire_sound = 'sound/effects/magic/staff_change.ogg' + max_charges = 6 + +/obj/item/gun/magic/wand/babel/zap_self(mob/living/user, suicide = FALSE) + . = ..() + charges-- + if (HAS_TRAIT(user, TRAIT_TOWER_OF_BABEL)) + return + curse_of_babel(user) + +/obj/item/gun/magic/wand/babel/do_suicide(mob/living/user) + . = ..() + user.say("Someone please kill me!", forced = "failed babel wand suicide") + return SHAME diff --git a/code/modules/projectiles/guns/magic/wands/wand_bald.dm b/code/modules/projectiles/guns/magic/wands/wand_bald.dm new file mode 100644 index 00000000000..1d35bd05d8e --- /dev/null +++ b/code/modules/projectiles/guns/magic/wands/wand_bald.dm @@ -0,0 +1,137 @@ +/// Makes you bald, or emphasises your baldness +/obj/item/gun/magic/wand/bald + name = "shearing rod" + desc = "A wand commonly used in wizard collegiate hazing, renders victims bald or draws significant attention to their baldness." + school = SCHOOL_TRANSMUTATION + ammo_type = /obj/item/ammo_casing/magic/bald + icon_state = "shavingwand" + base_icon_state = "shavingwand" + fire_sound = 'sound/items/tools/welder2.ogg' + max_charges = 12 + +/obj/item/gun/magic/wand/bald/zap_self(mob/living/user, suicide) + . = ..() + if (!suicide) + visible_message(span_notice("[user] gives [user.p_themselves()] a quick shave.")) + var/obj/projectile/magic/bald/trimmer = new(user.drop_location()) + trimmer.firer = user + user.projectile_hit(trimmer, BODY_ZONE_HEAD) + qdel(trimmer) + +/obj/item/gun/magic/wand/bald/do_suicide(mob/living/carbon/human/user) + var/obj/item/bodypart/head/dome = user.get_bodypart(BODY_ZONE_HEAD) + if (!dome || ((dome.head_flags & HEAD_HAIR) && user.hairstyle != "Bald")) + . = ..() + visible_message(span_suicide("[user] desperately attempts to shave [user.p_themselves()] in a cry for help.")) + return SHAME + + charges-- + user.apply_status_effect(/datum/status_effect/bald_flare) + dome.dismember(wounding_type = WOUND_SLASH, silent = TRUE) + visible_message(span_suicide("As the light fades, it becomes clear that [user] has shaved off [user.p_their()] entire head.")) + +/obj/item/gun/magic/wand/bald/process_fire(atom/target, mob/living/user, message, params, zone_override, bonus_spread) + zone_override = BODY_ZONE_HEAD // Head only + return ..() + +/obj/item/ammo_casing/magic/bald + projectile_type = /obj/projectile/magic/bald + +/// Embaldens people, or turns their bald spot into a reflective surface +/obj/projectile/magic/bald + name = "bolt of baldness" + icon = 'icons/obj/cosmetic.dmi' + icon_state = "razor" + damage = 5 + damage_type = BRUTE + accuracy_falloff = 0 + +// Currently we have no facility for shaving nonhuman mobs +/obj/projectile/magic/bald/on_hit(mob/living/carbon/human/target, blocked, pierce_hit) + if (!isliving(target)) + return ..() + + var/obj/item/bodypart/head/dome = target.get_bodypart(BODY_ZONE_HEAD) + if (iscarbon(target) && !dome) + return BULLET_ACT_FORCE_PIERCE // No head no shave + . = ..() + if (. == BULLET_ACT_BLOCK || !istype(target) || blocked >= 100) + return + + // First look for wigs or hats + var/obj/item/hat = target.head // Head here means what's on it, not what it is + + if (hat) + if (!istype(hat, /obj/item/clothing/head/wig)) // If we're not a wig, check if there's a wig on our hat + var/obj/item/clothing/head/wig/attached_wig = locate() in hat + hat = attached_wig || hat + + if (istype(hat, /obj/item/clothing/head/wig)) + hat.forceMove(target.drop_location()) + hat.deconstruct(FALSE) + if (QDELETED(hat)) // IDK maybe it's disagreed + visible_message(span_warning("[target]'s \the [hat] is shredded by [src]!")) + log_combat(firer, target, "magically destroyed wig", src) + return + + if(hat.flags_inv & HIDEHAIR) + var/obj/item/clothing/clothing_hat = hat // Not all hats are clothing + if (!istype(clothing_hat) || !(clothing_hat.clothing_flags & SNUG_FIT)) + visible_message(span_warning("[hat] is knocked off [target]'s head!")) + target.dropItemToGround(hat) + return + + // Weird mutant hair + var/obj/item/organ/mutant_hair = target.get_organ_slot(ORGAN_SLOT_EXTERNAL_POD_HAIR) + if (mutant_hair) + mutant_hair.Remove(target, special = FALSE) + qdel(mutant_hair) + target.Knockdown(1 SECONDS) + visible_message(span_warning("[target]'s hair is instantly shaved away by [src]!")) + log_combat(firer, target, "magically shaved bald", src) + return + + // Finally normal hair + if ((dome?.head_flags & HEAD_HAIR) && target.hairstyle != "Bald") + target.set_hairstyle("Bald") + target.Knockdown(1 SECONDS) + visible_message(span_warning("[target]'s hair is instantly shaved away by [src]!")) + log_combat(firer, target, "magically shaved bald", src) + return + + target.apply_status_effect(/datum/status_effect/bald_flare) + +#define BALD_RAYS_FILTER "bald_ray" + +/// Mostly just handles animation +/datum/status_effect/bald_flare + id = "bald_flare" + alert_type = null + duration = 1.6 SECONDS + +/datum/status_effect/bald_flare/on_apply() + . = ..() + owner.visible_message(span_warning("[owner]'s bald head releases a bright flash of light!")) + for(var/mob/living/viewers in (viewers(3, owner) - owner)) + viewers.flash_act() + + var/mob/living/carbon/human/human_owner = owner + var/height = max((human_owner.mob_height || 0) - 2, 0) + + owner.add_filter(name = BALD_RAYS_FILTER, priority = 1, params = list( + type = "rays", + y = height, + size = 10, + color = COLOR_VERY_SOFT_YELLOW, + density = 20 + )) + + var/ray_filter = owner.get_filter(BALD_RAYS_FILTER) + animate(ray_filter, size = 30, time = duration * 0.85) + animate(size = 0, time = duration * 0.15) + animate(ray_filter, offset = 1.5, time = duration, flags = ANIMATION_PARALLEL) + +/datum/status_effect/bald_flare/on_remove() + owner.remove_filter(BALD_RAYS_FILTER) + +#undef BALD_RAYS_FILTER diff --git a/code/modules/projectiles/guns/magic/wands/wand_booze.dm b/code/modules/projectiles/guns/magic/wands/wand_booze.dm new file mode 100644 index 00000000000..68ca560eb84 --- /dev/null +++ b/code/modules/projectiles/guns/magic/wands/wand_booze.dm @@ -0,0 +1,61 @@ +/** + * Wand which makes you drunk, self-explanatory + * As it applies a copious amount of alcohol it's actually surprisingly deadly, but not very fast at being deadly + */ + +/obj/item/gun/magic/wand/booze + name = "party wand" + desc = "A wand which fills its target with copious amounts of alcohol. Use in moderation, unless you are \ + trying to give someone liver damage." + school = SCHOOL_CONJURATION + ammo_type = /obj/item/ammo_casing/magic/booze + icon_state = "beerwand" + base_icon_state = "beerwand" + fire_sound = 'sound/effects/slosh.ogg' + max_charges = 8 + +/obj/item/gun/magic/wand/booze/zap_self(mob/living/user, suicide = FALSE) + playsound(user, fire_sound, 50, TRUE) + if (!suicide) + user.log_message("zapped [user.p_them()]self with a [src]", LOG_ATTACK) + user.visible_message(span_notice("[user] puts the [src] up to [user.p_their()] mouth and starts chugging!")) + var/obj/projectile/magic/booze/splash = new(user.drop_location()) + splash.firer = user + user.projectile_hit(splash, BODY_ZONE_HEAD) + qdel(splash) + charges-- + +/obj/item/gun/magic/wand/booze/do_suicide(mob/living/user) + . = ..() + user.visible_message(span_suicide("[user] pours a constant stream of booze into [user.p_their()] mouth, [user.p_theyre()] about to pop!")) + if (!do_after(user, 3 SECONDS, target = src)) + return SHAME + user.Stun(5 SECONDS, ignore_canstun = TRUE) + user.inflate_gib(DROP_ALL_REMAINS, gib_time = 2.5 SECONDS) + addtimer(CALLBACK(src, PROC_REF(flood_beer), get_turf(user)), 2.5 SECONDS, TIMER_DELETE_ME) + return MANUAL_SUICIDE + +/// Creates a beer blast when someone bursts themselves +/obj/item/gun/magic/wand/booze/proc/flood_beer(turf/flood_point) + if (!flood_point) + return + var/datum/reagents/beer = new /datum/reagents(100) + beer.add_reagent(/datum/reagent/consumable/ethanol/beer, 100) + beer.my_atom = flood_point + beer.create_foam(/datum/effect_system/fluid_spread/foam, 100) + +/obj/item/ammo_casing/magic/booze + projectile_type = /obj/projectile/magic/booze + +/obj/projectile/magic/booze + name = "bolt of inebriation" + icon_state = "energy" + +/obj/projectile/magic/booze/Initialize(mapload) + . = ..() + create_reagents(max_vol = 10) + reagents.add_reagent(/datum/reagent/consumable/ethanol/bacchus_blessing, 10) + +/obj/projectile/magic/booze/on_hit(atom/target, blocked = 0, pierce_hit) + . = ..() + reagents.trans_to(target, 10, methods = INGEST) diff --git a/code/modules/projectiles/guns/magic/wands/wand_freeze.dm b/code/modules/projectiles/guns/magic/wands/wand_freeze.dm new file mode 100644 index 00000000000..126ccf9e313 --- /dev/null +++ b/code/modules/projectiles/guns/magic/wands/wand_freeze.dm @@ -0,0 +1,73 @@ +/** + * Freezing wand places you in an ice cube and creates ice turfs + */ +/obj/item/gun/magic/wand/freeze + name = "wand of ice" + desc = "The chilling power of this wand will stop your enemies in their tracks." + school = SCHOOL_EVOCATION + ammo_type = /obj/item/ammo_casing/magic/freeze + icon_state = "icewand" + base_icon_state = "icewand" + fire_sound = 'sound/effects/magic/blink.ogg' + max_charges = 8 + +/obj/item/gun/magic/wand/freeze/zap_self(mob/living/user, suicide = FALSE) + . = ..() + to_chat(user, span_warning("You freeze yourself in a block of ice!")) + var/obj/projectile/magic/freeze/ice = new(user.drop_location()) + ice.firer = user + user.projectile_hit(ice, BODY_ZONE_CHEST) + qdel(ice) + charges-- + +/obj/item/gun/magic/wand/freeze/do_suicide(mob/living/user) + charges-- + playsound(user, fire_sound, 50, TRUE) + var/obj/structure/statue/snow/snowman/snover = new(user.drop_location()) + snover.name = user.real_name + var/obj/item/organ/brain = user.get_organ_slot(ORGAN_SLOT_BRAIN) + if (brain) + brain.Remove(user) + brain.forceMove(snover) + user.unequip_everything() + user.ghostize() + qdel(user) + return MANUAL_SUICIDE + +/obj/item/ammo_casing/magic/freeze + projectile_type = /obj/projectile/magic/freeze + harmful = FALSE + +/obj/projectile/magic/freeze + name = "bolt of freezing" + icon_state = "ice_1" + /// Temperature change to apply to hit mob + var/temperature = -350 + +/obj/projectile/magic/freeze/on_hit(atom/target, blocked = 0, pierce_hit) + . = ..() + var/turf/hit_turf = get_turf(target) + if (isfloorturf(hit_turf) && !isspaceturf(hit_turf) && !isindestructiblefloor(hit_turf)) + hit_turf.ChangeTurf(/turf/open/floor/fakeice/slippery, flags = CHANGETURF_INHERIT_AIR) + + if(isobj(target)) + var/obj/thingy = target + + if(thingy.reagents) + var/datum/reagents/reagents = thingy.reagents + reagents?.expose_temperature(temperature) + return + + var/mob/living/victim = target + if (!istype(victim)) + return + + victim.apply_status_effect(/datum/status_effect/ice_block_talisman, 10 SECONDS) + + var/applied_temp = (1 - blocked) * temperature + if(iscarbon(target)) + var/mob/living/carbon/chill_dude = target + var/thermal_protection = 1 - chill_dude.get_insulation_protection(chill_dude.bodytemperature + temperature) + applied_temp = (thermal_protection * temperature) + temperature + + victim.adjust_bodytemperature(applied_temp) diff --git a/code/modules/projectiles/guns/magic/wands/wand_hallucination.dm b/code/modules/projectiles/guns/magic/wands/wand_hallucination.dm new file mode 100644 index 00000000000..87f31314c5c --- /dev/null +++ b/code/modules/projectiles/guns/magic/wands/wand_hallucination.dm @@ -0,0 +1,77 @@ +#define WIZARD_WAND_HALLUCINATIONS list(\ + /datum/hallucination/death,\ + /datum/hallucination/death/dust,\ + /datum/hallucination/delusion/preset/carp,\ + /datum/hallucination/delusion/preset/corgi,\ + /datum/hallucination/delusion/preset/cyborg,\ + /datum/hallucination/delusion/preset/ghost,\ + /datum/hallucination/delusion/preset/monkey,\ + /datum/hallucination/delusion/preset/skeleton,\ + /datum/hallucination/delusion/preset/syndies,\ + /datum/hallucination/delusion/preset/zombie,\ + /datum/hallucination/fire,\ + /datum/hallucination/hazard/lava,\ + /datum/hallucination/hazard/chasm,\ + /datum/hallucination/hazard/anomaly,\ + /datum/hallucination/ice,\ + /datum/hallucination/oh_yeah,\ + /datum/hallucination/shock,\ + /datum/hallucination/xeno_attack,\ +) + +/** + * Hallucination wand looks exactly like a bolt of chaos except whatever happens isn't real + * One of the few times people might actually fall for hallucinations of being set on fire or turned into a xenomorph + * Even if they don't, several of these are minor stuns anyway + */ +/obj/item/gun/magic/wand/hallucination + name = "wand of chaos" + desc = "A wand which spits bolts of hallucinogenic magic which can do almost anything, or at least make the victim think so." + school = SCHOOL_FORBIDDEN + ammo_type = /obj/item/ammo_casing/magic/hallucination + icon_state = "chaoswand" + base_icon_state = "chaoswand" + fire_sound = 'sound/effects/magic/staff_chaos.ogg' + max_charges = 20 + +/obj/item/gun/magic/wand/hallucination/zap_self(mob/living/user, suicide = FALSE) + . = ..() + var/datum/hallucination/picked_hallucination = pick(WIZARD_WAND_HALLUCINATIONS) + user.cause_hallucination(picked_hallucination, "wand") + charges-- + +/obj/item/gun/magic/wand/hallucination/do_suicide(mob/living/user) + charges-- + playsound(user, fire_sound, 50, TRUE) + var/mob/living/basic/illusion/mirage/mirage = new(get_turf(src)) + mirage.mock_as(user, 15 SECONDS) + mirage.AddElement(/datum/element/content_barfer) + + qdel(mirage.ai_controller) + mirage.ai_controller = new /datum/ai_controller/basic_controller/simple/simple_hostile_obstacles(mirage) + + var/list/our_stuff = user.unequip_everything() + for (var/atom/movable/thing in our_stuff) + thing.forceMove(mirage) + user.ghostize() + qdel(user) + return MANUAL_SUICIDE + +/obj/item/ammo_casing/magic/hallucination + projectile_type = /obj/projectile/magic/hallucination + harmful = FALSE + +/obj/projectile/magic/hallucination + // Eagle eyed players may be aware that there's no such thing as a real bolt of chaos projectile + name = "bolt of chaos" + icon_state = "ice_1" + +/obj/projectile/magic/hallucination/on_hit(atom/target, blocked = 0, pierce_hit) + . = ..() + var/mob/living/carbon/victim = target + if (!istype(victim)) + return + var/datum/hallucination/picked_hallucination = pick(WIZARD_WAND_HALLUCINATIONS) + victim.cause_hallucination(picked_hallucination, "wand") + +#undef WIZARD_WAND_HALLUCINATIONS diff --git a/code/modules/projectiles/guns/magic/wands/wand_levitate.dm b/code/modules/projectiles/guns/magic/wands/wand_levitate.dm new file mode 100644 index 00000000000..4466a7e7425 --- /dev/null +++ b/code/modules/projectiles/guns/magic/wands/wand_levitate.dm @@ -0,0 +1,68 @@ +/** + * Levitation wand applies anti-gravity to target. + */ +/obj/item/gun/magic/wand/levitate + name = "lifting rod" + desc = "The power of this rod lifts living creatures off the ground, potentially leaving them unable to move." + school = SCHOOL_TRANSLOCATION + ammo_type = /obj/item/ammo_casing/magic/levitate + icon_state = "gravwand" + base_icon_state = "gravwand" + fire_sound = 'sound/effects/magic/repulse.ogg' + max_charges = 12 + +/obj/item/gun/magic/wand/levitate/zap_self(mob/living/user, suicide = FALSE) + . = ..() + user.apply_status_effect(/datum/status_effect/levitate) + +/obj/item/gun/magic/wand/levitate/do_suicide(mob/living/user) + if (!iscarbon(user)) + . = ..() + return SHAME + + charges-- + playsound(user, fire_sound, 50, TRUE) + user.visible_message(span_suicide("[user] inverts gravity inside of [user.p_their()] body!")) + var/mob/living/carbon/organ_haver = user + for (var/obj/item/organ/organ as anything in organ_haver.organs) + organ.Remove(user) + organ.forceMove(user.drop_location()) + organ.AddElement(/datum/element/forced_gravity, -1) + + var/obj/item/bodypart/chest = user.get_bodypart(BODY_ZONE_CHEST) + chest.dismember() + + return MANUAL_SUICIDE // I think every carbon dies if you remove all the organs from its body + +/obj/item/ammo_casing/magic/levitate + projectile_type = /obj/projectile/magic/levitate + harmful = FALSE + +/obj/projectile/magic/levitate + name = "bolt of levitation" + icon_state = "bluespace" + +/obj/projectile/magic/levitate/on_hit(atom/target, blocked = 0, pierce_hit) + . = ..() + var/mob/living/victim = target + if (!istype(victim)) + return + victim.apply_status_effect(/datum/status_effect/levitate) + +/datum/status_effect/levitate + id = "levitated" + status_type = STATUS_EFFECT_REPLACE + duration = 2 MINUTES + alert_type = null + +/datum/status_effect/levitate/on_apply() + owner.visible_message(span_warning("[owner] floats into the air!")) + owner.AddElement(/datum/element/forced_gravity, 0) + owner.add_filter("antigrav_glow", 2, list("type" = "outline", "color" = "#de3aff48", "size" = 2)) + return ..() + +/datum/status_effect/levitate/on_remove() + owner.visible_message(span_notice("[owner] gently descends to the ground")) + owner.RemoveElement(/datum/element/forced_gravity, 0) + owner.remove_filter("antigrav_glow") + return ..() diff --git a/code/modules/projectiles/guns/magic/wands/wand_pax.dm b/code/modules/projectiles/guns/magic/wands/wand_pax.dm new file mode 100644 index 00000000000..9bd221056b4 --- /dev/null +++ b/code/modules/projectiles/guns/magic/wands/wand_pax.dm @@ -0,0 +1,67 @@ +/** + * Pax wand is a minor heal which applies temporary pacifism, gives you time to talk it out? + */ +/obj/item/gun/magic/wand/pax + name = "rod of compassion" + desc = "A wand which supernaturally connects victim and target, which renders both unable to fight and makes them feel a little better." + school = SCHOOL_RESTORATION + ammo_type = /obj/item/ammo_casing/magic/pax + icon_state = "peacewand" + base_icon_state = "peacewand" + fire_sound = 'sound/effects/emotes/kiss.ogg' + max_charges = 12 + +/obj/item/gun/magic/wand/pax/fire_gun(atom/target, mob/living/user, flag, params) + . = ..() + if (!.) + return + user.apply_status_effect(/datum/status_effect/pacify/visible, 30 SECONDS) // Don't miss! + user.adjust_brute_loss(-30) + +/obj/item/gun/magic/wand/pax/zap_self(mob/living/user, suicide = FALSE) + if (!suicide) + user.visible_message(span_notice("[user] tenderly kisses [user.p_their()] own wand.")) + +/obj/item/gun/magic/wand/pax/do_suicide(mob/living/user) + . = ..() + user.visible_message(span_suicide("...but [user] can't bring [user.p_themselves()] to hurt anyone!")) + return SHAME + +/obj/item/ammo_casing/magic/pax + projectile_type = /obj/projectile/magic/pax + harmful = FALSE + +/obj/projectile/magic/pax + name = "bolt of compassion" + icon = 'icons/mob/simple/animal.dmi' + icon_state = "heart" + +/obj/projectile/magic/pax/on_hit(atom/target, blocked = 0, pierce_hit) + . = ..() + var/mob/living/victim = target + if (!istype(victim)) + return + + victim.apply_status_effect(/datum/status_effect/pacify/visible, 30 SECONDS) + victim.adjust_brute_loss(-30) + +// Default pacify status effect has no screen alert but I think this should have one +/datum/status_effect/pacify/visible + alert_type = /atom/movable/screen/alert/status_effect/pacified + +/datum/status_effect/pacify/visible/on_apply() + if (!HAS_TRAIT(owner, TRAIT_PACIFISM)) + owner.visible_message(span_notice("[owner] seems to relax."), span_notice("You feel your muscles loosen and your will to fight melt away.")) + return ..() + +/datum/status_effect/pacify/visible/on_remove() + . = ..() + // Might have it from somewhere else + if (HAS_TRAIT(owner, TRAIT_PACIFISM)) + return + owner.visible_message(span_warning("[owner] suddenly tenses up."), span_notice("You suddenly remember that violence is an option.")) + +/atom/movable/screen/alert/status_effect/pacified + name = "Pacified" + desc = "You find yourself temporarily incapable of violence." + icon_state = "in_love" diff --git a/code/modules/projectiles/guns/magic/wands/wand_pizza.dm b/code/modules/projectiles/guns/magic/wands/wand_pizza.dm new file mode 100644 index 00000000000..f067abb2c8d --- /dev/null +++ b/code/modules/projectiles/guns/magic/wands/wand_pizza.dm @@ -0,0 +1,87 @@ +/** + * Turns things you hit into pizza. + */ +/obj/item/gun/magic/wand/pizza + name = "wand of snacking" + desc = "The incredible power of this wand transforms certain objects and surfaces into edible pizza." + school = SCHOOL_TRANSMUTATION + ammo_type = /obj/item/ammo_casing/magic/pizza + icon_state = "pizzawand" + base_icon_state = "pizzawand" + fire_sound = 'sound/effects/magic/staff_change.ogg' + max_charges = 20 + +/obj/item/gun/magic/wand/pizza/zap_self(mob/living/user, suicide = FALSE) + to_chat(user, span_notice("You can't bring yourself to commit to a permanent transformation into pizza right now.")) + return + +/obj/item/gun/magic/wand/pizza/do_suicide(mob/living/user) + charges-- + playsound(user, fire_sound, 50, TRUE) + var/turf/user_loc = get_turf(user) + user.unequip_everything() + + new /obj/effect/particle_effect/fluid/smoke(user_loc) + + var/list/slice_types = subtypesof(/obj/item/food/pizzaslice) + var/special_slice = pick(slice_types) + var/obj/item/pizza = new special_slice(user_loc) + + pizza.name = "[user.real_name] slice" + user.ghostize() + qdel(user) + + return MANUAL_SUICIDE + +/obj/item/ammo_casing/magic/pizza + projectile_type = /obj/projectile/magic/pizza + harmful = FALSE + +/obj/projectile/magic/pizza + name = "bolt of snacking" + icon = 'icons/obj/food/pizza.dmi' + icon_state = "pizzamargherita" + +/obj/projectile/magic/pizza/on_hit(atom/target, blocked = 0, pierce_hit) + . = ..() + var/turf/hit_turf = get_turf(target) + var/datum/dimension_theme/pizza/converter = new() + if(converter.can_convert(hit_turf)) + converter.apply_theme(hit_turf) + + var/mob/living/lunch_haver = target + if (!istype(lunch_haver)) + return + + var/list/slice_types = subtypesof(/obj/item/food/pizzaslice) + var/special_slice = pick(slice_types) + + var/obj/item/the_piz = new special_slice() + + if (!length(lunch_haver.held_items)) + the_piz.forceMove(lunch_haver.drop_location()) + else + if (!iscarbon(lunch_haver)) + if (lunch_haver.put_in_hands(the_piz)) + if (lunch_haver.get_active_held_item() != the_piz) + lunch_haver.swap_hand() + else if (!lunch_haver.put_in_active_hand(the_piz)) + if (istype(lunch_haver.get_active_held_item(), /obj/item/food/pizzaslice)) + the_piz.forceMove(lunch_haver.drop_location()) + else + // If you've got arms and refused to pick up pizza then woe be upon you + var/obj/item/bodypart/my_arm = lunch_haver.get_active_hand() + + if (my_arm && my_arm.dismember()) + the_piz.forceMove(lunch_haver.drop_location()) + else + // I would love to use plaintext_zone but what if they don't have an arm? + var/hand_index = IS_LEFT_INDEX(lunch_haver.active_hand_index) ? BODY_ZONE_L_ARM : BODY_ZONE_R_ARM + var/hand_zone = IS_LEFT_INDEX(lunch_haver.active_hand_index) ? "left arm" : "right arm" + + var/mob/living/carbon/edward_pizza_hands = lunch_haver + edward_pizza_hands.make_item_prosthetic(the_piz, hand_index) + edward_pizza_hands.visible_message(span_warning("[edward_pizza_hands]'s [hand_zone] is transformed into \a [the_piz]!")) + + lunch_haver.set_combat_mode(FALSE) // You can't eat pizza if you're on combat mode + the_piz.attack(lunch_haver, lunch_haver) diff --git a/code/modules/projectiles/guns/magic/wands/wand_plague.dm b/code/modules/projectiles/guns/magic/wands/wand_plague.dm new file mode 100644 index 00000000000..8e9991f9f24 --- /dev/null +++ b/code/modules/projectiles/guns/magic/wands/wand_plague.dm @@ -0,0 +1,50 @@ +/// Makes the target cough out frogs and locusts and such +/obj/item/gun/magic/wand/plague + name = "pestilent wand" + desc = "A vile implement which forces its victims' bodies to disgorge frogs and insects." + school = SCHOOL_CONJURATION + ammo_type = /obj/item/ammo_casing/magic/plague + icon_state = "plaguewand" + base_icon_state = "plaguewand" + fire_sound = 'sound/effects/smoke.ogg' + max_charges = 6 + +/obj/item/gun/magic/wand/plague/zap_self(mob/living/user, suicide) + . = ..() + var/obj/projectile/magic/plague/germ = new(user.drop_location()) + germ.firer = user + user.projectile_hit(germ, BODY_ZONE_CHEST) + qdel(germ) + charges-- + +/obj/item/gun/magic/wand/plague/do_suicide(mob/living/user) + . = ..() + + new /obj/effect/temp_visual/circle_wave/bioscrambler(get_turf(src)) + var/datum/disease/verminous_plague/curse = new() + for(var/mob/living/carbon/human/infectee in (hearers(2, user) - user)) + infectee.ContactContractDisease(curse) + + return TOXLOSS + +/obj/item/ammo_casing/magic/plague + projectile_type = /obj/projectile/magic/plague + +/// Makes the target sick with frogs +/obj/projectile/magic/plague + name = "pestilent bolt" + icon_state = "blastwave" + damage = 20 + damage_type = TOX + +/obj/projectile/magic/plague/on_hit(mob/living/carbon/human/target, blocked, pierce_hit) + . = ..() + if (. == BULLET_ACT_BLOCK || !istype(target) || blocked >= 100) + return + target.ContactContractDisease(new /datum/disease/verminous_plague()) + var/datum/disease/verminous_plague/curse = locate() in target.diseases + if (!QDELETED(curse)) + if (curse.stage < 2) + curse.update_stage(2) + else + curse.spawn_mob() diff --git a/code/modules/projectiles/guns/magic/wands/wand_prank.dm b/code/modules/projectiles/guns/magic/wands/wand_prank.dm new file mode 100644 index 00000000000..955edfaef58 --- /dev/null +++ b/code/modules/projectiles/guns/magic/wands/wand_prank.dm @@ -0,0 +1,86 @@ +/** + * Prank wand knocks you over as if pied and surrounds you with space lube + */ +/obj/item/gun/magic/wand/prank + name = "wand of pratfalls" + desc = "A comedy wand which is sure to get a laugh out of you, if not its victims." + school = SCHOOL_CONJURATION + ammo_type = /obj/item/ammo_casing/magic/prank + icon_state = "bananawand" + base_icon_state = "bananawand" + fire_sound = 'sound/items/bikehorn.ogg' + max_charges = 10 + +/obj/item/gun/magic/wand/prank/zap_self(mob/living/user, suicide = FALSE) + . = ..() + var/obj/item/food/pie/cream/magical/pie = new(src) + pie.stun_and_blur(user) + charges-- + +/obj/item/gun/magic/wand/prank/do_suicide(mob/living/user) + charges-- + playsound(user, fire_sound, 50, TRUE) + user.visible_message("[user] covers [user.p_themselves()] with magical lube!") + var/datum/reagents/lube = new /datum/reagents(40) + lube.add_reagent(/datum/reagent/lube, 40) + lube.my_atom = get_turf(user) + lube.create_foam(/datum/effect_system/fluid_spread/foam, 40) + user.slip(5 SECONDS) + user.apply_status_effect(/datum/status_effect/slippery_death) + return MANUAL_SUICIDE + +/obj/item/ammo_casing/magic/prank + projectile_type = /obj/projectile/magic/prank + harmful = FALSE + +/obj/projectile/magic/prank + name = "bolt of pratfalls" + icon = 'icons/obj/food/piecake.dmi' + icon_state = "pie" + +/obj/projectile/magic/prank/on_hit(atom/target, blocked = 0, pierce_hit) + . = ..() + var/obj/item/food/pie/cream/magical/pie = new() + pie.stun_and_blur(target) + +/// This creates an extremely messy cream pie which your audience will love +/obj/item/food/pie/cream/magical + +/obj/item/food/pie/cream/magical/stun_and_blur(mob/living/victim, can_splat_on) + . = ..() + var/datum/reagents/lube = new /datum/reagents(40) + lube.add_reagent(/datum/reagent/lube, 40) + lube.my_atom = get_turf(victim) + lube.create_foam(/datum/effect_system/fluid_spread/foam, 40) + qdel(lube) + var/static/laugh_sound = list('sound/items/sitcom_laugh/SitcomLaugh1.ogg', 'sound/items/sitcom_laugh/SitcomLaugh2.ogg', 'sound/items/sitcom_laugh/SitcomLaugh3.ogg') + playsound(victim, pick(laugh_sound), 100, FALSE) + +/// Used by the wand suicide, keep slipping until you hit a wall and explode +/datum/status_effect/slippery_death + id = "slippery_death" + alert_type = null + tick_interval = 0.2 SECONDS + /// What direction are we slipping in? + var/direction + +/datum/status_effect/slippery_death/on_creation(mob/living/new_owner, set_duration) + . = ..() + direction = pick(GLOB.cardinals) + new_owner.setDir(direction) + new_owner.Stun(INFINITY, ignore_canstun = TRUE) + ADD_TRAIT(new_owner, TRAIT_IMMOBILIZED, REF(src)) + RegisterSignals(new_owner, list(COMSIG_MOVABLE_Z_CHANGED, COMSIG_LIVING_DEATH, COMSIG_LIVING_MOB_BUMP, COMSIG_LIVING_MOB_BUMPED), PROC_REF(die)) + +/datum/status_effect/slippery_death/tick(seconds_between_ticks) + var/turf/turf = get_step(owner, direction) + if(!turf || turf.is_blocked_turf()) + die() + return + owner.Move(turf) + +/// When we hit anything, die, or change z level we burst +/datum/status_effect/slippery_death/proc/die() + SIGNAL_HANDLER + owner.gib(DROP_ALL_REMAINS) + qdel(src) diff --git a/code/modules/projectiles/guns/magic/wands/wand_rebel.dm b/code/modules/projectiles/guns/magic/wands/wand_rebel.dm new file mode 100644 index 00000000000..74cabaf9d0f --- /dev/null +++ b/code/modules/projectiles/guns/magic/wands/wand_rebel.dm @@ -0,0 +1,75 @@ +/** + * Detaches a limb and animates it, so that it attacks its former owner. + * Stop hitting yourself. Stop hitting yourself. + */ +/obj/item/gun/magic/wand/rebel + name = "wand of rebellion" + desc = "The dark power of this wand turns the victim's body against itself." + school = SCHOOL_NECROMANCY + ammo_type = /obj/item/ammo_casing/magic/rebellion + icon_state = "necrowand" + base_icon_state = "necrowand" + fire_sound = 'sound/effects/magic/wandodeath.ogg' + max_charges = 6 + +/obj/item/gun/magic/wand/rebel/zap_self(mob/living/user, suicide = FALSE) + . = ..() + charges-- + var/obj/projectile/magic/rebellion/blast = new() + if (suicide) + blast.valid_zones = list(BODY_ZONE_HEAD) + user.projectile_hit(blast, suicide ? BODY_ZONE_HEAD : BODY_ZONE_CHEST) + qdel(blast) + +/obj/item/gun/magic/wand/rebel/do_suicide(mob/living/user) + . = ..() + if (user.stat != DEAD) + return SHAME // God damn dullahans + return BRUTELOSS + +/obj/item/ammo_casing/magic/rebellion + projectile_type = /obj/projectile/magic/rebellion + +/obj/projectile/magic/rebellion + name = "bolt of rebellion" + icon_state = "soulslash" + damage = 15 + damage_type = BRUTE + /// Valid locations to shoot someone + var/list/valid_zones + +/obj/projectile/magic/rebellion/Initialize(mapload) + . = ..() + valid_zones = GLOB.limb_zones.Copy() // We don't want to mutate the global list + +/obj/projectile/magic/rebellion/on_hit(atom/target, blocked = 0, pierce_hit) + . = ..() + var/mob/living/carbon/victim = target + if (!istype(victim)) + if (isliving(victim)) + victim.apply_damage(35, BRUTE, sharpness = SHARP_EDGED) + return + + var/obj/item/bodypart/slapper + + while (!slapper && length(valid_zones)) + var/zone = pick_n_take(valid_zones) + slapper = victim.get_bodypart(zone) + + if (!slapper) + victim.apply_damage(35, BRUTE, wound_bonus = 20, sharpness = SHARP_EDGED) + return + + var/atom/animate_item = slapper + if (slapper.bodypart_flags & BODYPART_PSEUDOPART) + animate_item = victim.get_item_for_held_index(slapper.held_index) + + slapper.dismember(silent = FALSE, wounding_type = WOUND_SLASH) + + if (QDELETED(animate_item)) + return + var/mob/living/bully = animate_item.animate_atom_living(firer) + if (!bully.ai_controller) + return + bully.ai_controller.set_blackboard_key(BB_BASIC_MOB_CURRENT_TARGET, victim) + bully.ai_controller.ai_interact(victim, combat_mode = TRUE) diff --git a/code/modules/projectiles/guns/magic/wands/wand_repulse.dm b/code/modules/projectiles/guns/magic/wands/wand_repulse.dm new file mode 100644 index 00000000000..5a3618559e0 --- /dev/null +++ b/code/modules/projectiles/guns/magic/wands/wand_repulse.dm @@ -0,0 +1,64 @@ +#define REPULSE_RANGE 5 + +/** + * Repulsion wand throws things backwards, might hurt them if they ram something + */ +/obj/item/gun/magic/wand/repulse + name = "rod of repulsion" + desc = "A wand which blasts things away from you." + school = SCHOOL_TRANSLOCATION + ammo_type = /obj/item/ammo_casing/magic/repulse + icon_state = "repulsionwand" + base_icon_state = "repulsionwand" + fire_sound = 'sound/effects/magic/repulse.ogg' + max_charges = 12 + +/obj/item/gun/magic/wand/repulse/zap_self(mob/living/user, suicide = FALSE) + . = ..() + user.visible_message(span_warning("[user] blasts [user.p_themselves()] into the ground!")) + user.adjust_brute_loss(30) + user.Paralyze(10 SECONDS) + +/obj/item/gun/magic/wand/repulse/suicide_act(mob/living/user) + if (!iscarbon(user)) + . = ..() + return BRUTELOSS + + playsound(user, fire_sound, 50, TRUE) + var/mob/living/carbon/suicider = user + + var/throw_dir = pick(GLOB.alldirs) + var/atom/start_location = user.drop_location() + var/turf/target_turf = get_edge_target_turf(start_location, throw_dir) + + user.Stun(2 SECONDS, ignore_canstun = TRUE) + for (var/obj/item/organ/water_balloon as anything in suicider.organs) + if (QDELETED(user)) + break // They might get dusted when one of these is pulled out or something + var/turf/throw_at = get_ranged_target_turf_direct(start_location, target_turf, range = REPULSE_RANGE, offset = rand(-20, 20)) + water_balloon.Remove(user) + water_balloon.forceMove(start_location) + water_balloon.safe_throw_at(throw_at, REPULSE_RANGE, 3, force = MOVE_FORCE_STRONG) + sleep(0.1 SECONDS) + return BRUTELOSS + +/obj/item/ammo_casing/magic/repulse + projectile_type = /obj/projectile/magic/repulse + +/obj/projectile/magic/repulse + name = "bolt of repulsion" + icon_state = "blastwave" + +/obj/projectile/magic/repulse/on_hit(atom/target, blocked = 0, pierce_hit) + . = ..() + var/atom/movable/victim = target + if (!istype(victim)) + return + var/turf/throw_target = get_ranged_target_turf_direct(src, get_edge_target_turf(src, NORTH), REPULSE_RANGE, -angle) + victim.safe_throw_at(throw_target, REPULSE_RANGE, 3, force = MOVE_FORCE_STRONG) + var/mob/living/living_target = target + if (!istype(living_target)) + return + living_target.Paralyze(2 SECONDS) + +#undef REPULSE_RANGE diff --git a/code/modules/projectiles/guns/magic/wands/wand_swap.dm b/code/modules/projectiles/guns/magic/wands/wand_swap.dm new file mode 100644 index 00000000000..944958f6641 --- /dev/null +++ b/code/modules/projectiles/guns/magic/wands/wand_swap.dm @@ -0,0 +1,58 @@ +/** + * Swaps you with something you hit. + */ +/obj/item/gun/magic/wand/swap + name = "switching rod" + desc = "Exchanges the position of the wielder and an unanchored object they point at." + school = SCHOOL_TRANSLOCATION + ammo_type = /obj/item/ammo_casing/magic/swap + icon_state = "swapwand" + base_icon_state = "swapwand" + fire_sound = 'sound/effects/magic/swap.ogg' + max_charges = 20 + +/obj/item/gun/magic/wand/swap/zap_self(mob/living/user, suicide = FALSE) + . = ..() + to_chat(user, span_notice("You swap places with yourself! Amazing!")) + var/obj/effect/particle_effect/fluid/smoke/poof_in = new (get_turf(user)) + poof_in.lifetime = 5 DECISECONDS + charges-- + +/obj/item/gun/magic/wand/swap/do_suicide(mob/living/user) + . = ..() + user.visible_message(span_suicide("As the smoke clears, [user] is lying completely alive on [get_turf(user)].")) + return SHAME + +/obj/item/ammo_casing/magic/swap + projectile_type = /obj/projectile/magic/swap + harmful = FALSE + +/obj/projectile/magic/swap + name = "bolt of switching" + icon_state = "magicm" + projectile_phasing = PASSTABLE | PASSGLASS | PASSGRILLE + +/obj/projectile/magic/swap/on_hit(atom/target, blocked = 0, pierce_hit) + . = ..() + var/atom/movable/hit_target = target + if (!istype(hit_target)) + return + if (hit_target.anchored) + do_sparks(3, FALSE, hit_target) + return + if (!firer) + return + + var/turf/my_turf = get_turf(firer) + var/turf/your_turf = get_turf(hit_target) + + if (!check_teleport_valid(firer, your_turf, TELEPORT_CHANNEL_MAGIC, my_turf) || !check_teleport_valid(hit_target, my_turf, TELEPORT_CHANNEL_MAGIC, your_turf)) + do_sparks(3, FALSE, hit_target) + return + + do_teleport(firer, your_turf, asoundin = 'sound/effects/magic/swap.ogg', channel = TELEPORT_CHANNEL_MAGIC) + do_teleport(hit_target, my_turf, asoundin = 'sound/effects/magic/swap.ogg', channel = TELEPORT_CHANNEL_MAGIC) + var/obj/effect/particle_effect/fluid/smoke/poof_in = new (my_turf) + poof_in.lifetime = 5 DECISECONDS + var/obj/effect/particle_effect/fluid/smoke/poof_out = new (your_turf) + poof_out.lifetime = 5 DECISECONDS diff --git a/code/modules/projectiles/guns/magic/wands/wand_tentacle.dm b/code/modules/projectiles/guns/magic/wands/wand_tentacle.dm new file mode 100644 index 00000000000..c4be4e60a8d --- /dev/null +++ b/code/modules/projectiles/guns/magic/wands/wand_tentacle.dm @@ -0,0 +1,165 @@ +#define RETRACT_TIME (0.7 SECONDS) + +/** + * Immobilises people with tentacles. It's not a fetish. + */ +/obj/item/gun/magic/wand/tentacles + name = "restraining rod" + desc = "This wriggling wand binds its victims in a place for a time, although it doesn't stop them from shooting back." + school = SCHOOL_CONJURATION + ammo_type = /obj/item/ammo_casing/magic/tentacle_staff + icon_state = "tentawand" + base_icon_state = "tentawand" + fire_sound = 'sound/effects/splat.ogg' + max_charges = 10 + +/obj/item/gun/magic/wand/tentacles/zap_self(mob/living/user, suicide) + . = ..() + var/tentacle_type = suicide ? /obj/effect/wizard_tentacle/suicide : /obj/effect/wizard_tentacle + var/turf/target_turf = get_turf(user) + if (!(locate(/obj/effect/wizard_tentacle) in target_turf)) + new tentacle_type(target_turf, user) + +/obj/item/gun/magic/wand/tentacles/do_suicide(mob/living/user) + . = ..() + return user.has_status_effect(/datum/status_effect/incapacitating/immobilized/wizard_tentacle/suicide) ? MANUAL_SUICIDE : SHAME + +/obj/item/ammo_casing/magic/tentacle_staff + projectile_type = /obj/projectile/magic/tentacle_staff + +/// Grabs the target for a while in an unwanted hug +/obj/projectile/magic/tentacle_staff + name = "bolt of binding" + icon_state = "tentacle_end" + +/obj/projectile/magic/tentacle_staff/on_hit(mob/living/target, blocked = 0, pierce_hit) + . = ..() + if (. == BULLET_ACT_BLOCK || !istype(target) || blocked >= 100) + return + var/turf/target_turf = get_turf(target) + if (!(locate(/obj/effect/wizard_tentacle) in target_turf)) + new /obj/effect/wizard_tentacle(get_turf(target), target) + +/// Different enough from the goliath tentacle to just be its own subtype +/obj/effect/wizard_tentacle + name = "tentacle" + icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi' + icon_state = "goliath_tentacle_wiggle" + layer = BELOW_MOB_LAYER + plane = GAME_PLANE + anchored = TRUE + /// How long do we get grabbed? + var/grab_time = 20 SECONDS + /// Status effect we apply to victims + var/status_applied = /datum/status_effect/incapacitating/immobilized/wizard_tentacle + +/obj/effect/wizard_tentacle/Initialize(mapload, mob/living/victim) + . = ..() + if (isgroundlessturf(loc) || isnull(victim)) + return INITIALIZE_HINT_QDEL + flick("goliath_tentacle_spawn", src) + + if (victim.stat != DEAD && !HAS_TRAIT(victim, TRAIT_TENTACLE_IMMUNE)) + balloon_alert(victim, "grabbed") + visible_message(span_danger("[src] grabs hold of [victim]!")) + victim.apply_damage(15, BRUTE) + if (victim.apply_status_effect(status_applied, grab_time, src)) + buckle_mob(victim, TRUE) + + if (has_buckled_mobs()) + addtimer(CALLBACK(src, PROC_REF(retract)), grab_time, TIMER_DELETE_ME) + else + retract() + +/obj/effect/wizard_tentacle/user_unbuckle_mob(mob/living/buckled_mob, mob/user) + if (buckled_mob == user) + balloon_alert(user, "can't reach!") + return + return ..() + +/// We're done now +/obj/effect/wizard_tentacle/proc/retract() + if (icon_state == "goliath_tentacle_retract") + return // Already retracting + icon_state = "goliath_tentacle_retract" + unbuckle_all_mobs(force = TRUE) + QDEL_IN(src, RETRACT_TIME) + +/// This one kills you +/obj/effect/wizard_tentacle/suicide + grab_time = 3 SECONDS // Something worse is going to happen + status_applied = /datum/status_effect/incapacitating/immobilized/wizard_tentacle/suicide + +/// Subtype of immobilise which is linked to a tentacle +/datum/status_effect/incapacitating/immobilized/wizard_tentacle + id = "tentacle_immobilized" + /// The tentacle that is tenderly holding us close + var/obj/effect/wizard_tentacle/tentacle + /// Can someone else help us out? + var/removable = TRUE + +/datum/status_effect/incapacitating/immobilized/wizard_tentacle/on_creation(mob/living/new_owner, set_duration, obj/effect/wizard_tentacle/tentacle) + . = ..() + if (!.) + return + src.tentacle = tentacle + +/datum/status_effect/incapacitating/immobilized/wizard_tentacle/on_apply() + . = ..() + if (removable) + RegisterSignal(owner, COMSIG_CARBON_PRE_MISC_HELP, PROC_REF(on_helped)) + RegisterSignal(owner, SIGNAL_ADDTRAIT(TRAIT_TENTACLE_IMMUNE), PROC_REF(release)) + RegisterSignal(tentacle, COMSIG_QDELETING, PROC_REF(on_tentacle_left)) + +/datum/status_effect/incapacitating/immobilized/wizard_tentacle/on_remove() + . = ..() + UnregisterSignal(owner, list(COMSIG_CARBON_PRE_MISC_HELP, SIGNAL_ADDTRAIT(TRAIT_TENTACLE_IMMUNE))) + if (isnull(tentacle)) + return + UnregisterSignal(tentacle, COMSIG_QDELETING) + tentacle.retract() + tentacle = null + +/// Some kind soul has rescued us +/datum/status_effect/incapacitating/immobilized/wizard_tentacle/proc/on_helped(mob/source, mob/helping) + SIGNAL_HANDLER + if (helping == owner) + owner.balloon_alert(owner, "can't reach!") + return NONE + source.visible_message(span_notice("[helping] rips [source] from the tentacle's grasp!")) + release() + return COMPONENT_BLOCK_MISC_HELP + +/// Something happened to make the tentacle let go +/datum/status_effect/incapacitating/immobilized/wizard_tentacle/proc/release() + SIGNAL_HANDLER + qdel(src) + +/// Something happened to our associated tentacle +/datum/status_effect/incapacitating/immobilized/wizard_tentacle/proc/on_tentacle_left() + SIGNAL_HANDLER + UnregisterSignal(tentacle, COMSIG_QDELETING) + tentacle = null + release() + +/// This one kills you +/datum/status_effect/incapacitating/immobilized/wizard_tentacle/suicide + removable = FALSE + +/datum/status_effect/incapacitating/immobilized/wizard_tentacle/suicide/on_apply() + . = ..() + owner.Stun(6 SECONDS, ignore_canstun = TRUE) + +/datum/status_effect/incapacitating/immobilized/wizard_tentacle/suicide/on_remove() + var/had_tentacle = !!tentacle + . = ..() + if (!owner || !had_tentacle) + return + owner.visible_message(span_suicide("The tentacle drags [owner] directly to hell!")) + owner.unequip_everything() + animate(owner, transform = matrix() * 0, time = RETRACT_TIME) + animate(owner, pixel_y = -12, time = RETRACT_TIME, flags = ANIMATION_PARALLEL) + addtimer(CALLBACK(owner, TYPE_PROC_REF(/mob, ghostize)), RETRACT_TIME - 1) + QDEL_IN(owner, RETRACT_TIME) + +#undef RETRACT_TIME diff --git a/code/modules/projectiles/guns/magic/wands/wand_zap.dm b/code/modules/projectiles/guns/magic/wands/wand_zap.dm new file mode 100644 index 00000000000..4858b0bf7c2 --- /dev/null +++ b/code/modules/projectiles/guns/magic/wands/wand_zap.dm @@ -0,0 +1,61 @@ +/** + * It's just a classic taser + */ +/obj/item/gun/magic/wand/zap + name = "wand of zapping" + desc = "This wand overloads the nerves of your enemies with potent lightning." + school = SCHOOL_EVOCATION + ammo_type = /obj/item/ammo_casing/magic/zap + icon_state = "teslawand" + base_icon_state = "teslawand" + fire_sound = 'sound/items/weapons/taser.ogg' + max_charges = 8 + +/obj/item/gun/magic/wand/zap/zap_self(mob/living/user, suicide = FALSE) + . = ..() + do_sparks(1, TRUE, src) + var/obj/projectile/magic/zap/spark = new(user.drop_location()) + spark.firer = user + user.projectile_hit(spark, BODY_ZONE_CHEST) + qdel(spark) + charges-- + +/obj/item/gun/magic/wand/zap/do_suicide(mob/living/user) + charges-- + playsound(user, fire_sound, 50, TRUE) + do_sparks(2, TRUE, user) + user.electrocute_act(0, src, siemens_coeff = 1, flags = SHOCK_IGNORE_IMMUNITY|SHOCK_DELAY_STUN|SHOCK_NOGLOVES) + tesla_zap(source = user, zap_range = 5, power = 2.5e4, cutoff = 1e3) + return FIRELOSS + +/obj/item/ammo_casing/magic/zap + projectile_type = /obj/projectile/magic/zap + +/// A magic taser electrode +/obj/projectile/magic/zap + name = "spark" + icon_state = "spark" + color = COLOR_YELLOW + paralyze = 10 SECONDS + stutter = 10 SECONDS + jitter = 40 SECONDS + hitsound = 'sound/items/weapons/taserhit.ogg' + range = 7 + tracer_type = /obj/effect/projectile/tracer/stun + muzzle_type = /obj/effect/projectile/muzzle/stun + impact_type = /obj/effect/projectile/impact/stun + +/obj/projectile/magic/zap/on_hit(mob/living/target, blocked = 0, pierce_hit) + . = ..() + if (!istype(target) || blocked >= 100) + do_sparks(1, TRUE, src) + return + + target.add_mood_event("tased", /datum/mood_event/tased) + SEND_SIGNAL(target, COMSIG_LIVING_MINOR_SHOCK) // We really sending this signal from like 8 places huh? + if(!target.check_stun_immunity(CANKNOCKDOWN)) + addtimer(CALLBACK(target, TYPE_PROC_REF(/mob/living, do_jitter_animation), 20), 0.5 SECONDS) + +/obj/projectile/magic/zap/on_range() + do_sparks(1, TRUE, src) + return ..() diff --git a/code/modules/projectiles/guns/special/syringe_gun.dm b/code/modules/projectiles/guns/special/syringe_gun.dm index 5a26b9a885b..734986b4d6a 100644 --- a/code/modules/projectiles/guns/special/syringe_gun.dm +++ b/code/modules/projectiles/guns/special/syringe_gun.dm @@ -57,6 +57,8 @@ else chambered.newshot() //SKYRAT EDIT SMARTDARTS END + chambered.newshot() + return ..() /obj/item/gun/syringe/can_shoot() return syringes.len diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 713fe32c521..97058d3192f 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -1264,8 +1264,8 @@ free_hitscan_forceMove = TRUE forceMove(source_loc) starting = source_loc - pixel_x = source.pixel_x - pixel_y = source.pixel_y + pixel_x = source.pixel_x - source.base_pixel_x + pixel_y = source.pixel_y - source.base_pixel_y original = target // Trim off excess pixel_x/y by converting them into turf offset diff --git a/code/modules/projectiles/projectile/bullets/cannonball.dm b/code/modules/projectiles/projectile/bullets/cannonball.dm index bfc781e6fac..41277bc9559 100644 --- a/code/modules/projectiles/projectile/bullets/cannonball.dm +++ b/code/modules/projectiles/projectile/bullets/cannonball.dm @@ -123,7 +123,7 @@ /obj/projectile/bullet/ballista_spear/dragonator/Initialize(mapload) . = ..() - AddElement(/datum/element/bane, mob_biotypes = MOB_MINING, damage_multiplier = 2) + AddComponent(/datum/component/bane, affected_biotypes = MOB_MINING, damage_multiplier = 3) /obj/projectile/bullet/ballista_spear/dragonator/attach_spear(obj/item/spear) AddComponent(/datum/component/projectile_instance_drop, spear) diff --git a/code/modules/projectiles/projectile/bullets/pistol.dm b/code/modules/projectiles/projectile/bullets/pistol.dm index 9ab58c36dcd..7872b58d165 100644 --- a/code/modules/projectiles/projectile/bullets/pistol.dm +++ b/code/modules/projectiles/projectile/bullets/pistol.dm @@ -61,26 +61,6 @@ damage = 20 fire_stacks = 3 -/obj/projectile/bullet/c10mm/reaper - name = "10mm reaper pellet" - icon_state = null - damage = 50 - armour_penetration = 40 - tracer_type = /obj/effect/projectile/tracer/sniper - impact_type = /obj/effect/projectile/impact/sniper - muzzle_type = /obj/effect/projectile/muzzle/sniper - hitscan = TRUE - impact_effect_type = null - hitscan_light_intensity = 3 - hitscan_light_range = 0.75 - hitscan_light_color_override = LIGHT_COLOR_DIM_YELLOW - muzzle_flash_intensity = 5 - muzzle_flash_range = 1 - muzzle_flash_color_override = LIGHT_COLOR_DIM_YELLOW - impact_light_intensity = 5 - impact_light_range = 1 - impact_light_color_override = LIGHT_COLOR_DIM_YELLOW - // .160 Smart /obj/projectile/bullet/c160smart diff --git a/code/modules/projectiles/projectile/bullets/smg.dm b/code/modules/projectiles/projectile/bullets/smg.dm index 38280b6f91e..2c64bac2878 100644 --- a/code/modules/projectiles/projectile/bullets/smg.dm +++ b/code/modules/projectiles/projectile/bullets/smg.dm @@ -20,6 +20,26 @@ damage = 15 fire_stacks = 2 +/obj/projectile/bullet/c45/reaper + name = ".45 reaper pellet" + icon_state = null + damage = 50 + armour_penetration = 40 + tracer_type = /obj/effect/projectile/tracer/sniper + impact_type = /obj/effect/projectile/impact/sniper + muzzle_type = /obj/effect/projectile/muzzle/sniper + hitscan = TRUE + impact_effect_type = null + hitscan_light_intensity = 3 + hitscan_light_range = 0.75 + hitscan_light_color_override = LIGHT_COLOR_DIM_YELLOW + muzzle_flash_intensity = 5 + muzzle_flash_range = 1 + muzzle_flash_color_override = LIGHT_COLOR_DIM_YELLOW + impact_light_intensity = 5 + impact_light_range = 1 + impact_light_color_override = LIGHT_COLOR_DIM_YELLOW + // 4.6x30mm (Autorifles) /obj/projectile/bullet/c46x30mm diff --git a/code/modules/projectiles/projectile/special/plasma.dm b/code/modules/projectiles/projectile/special/plasma.dm index adba89e4d88..e3dede48404 100644 --- a/code/modules/projectiles/projectile/special/plasma.dm +++ b/code/modules/projectiles/projectile/special/plasma.dm @@ -2,35 +2,39 @@ name = "plasma blast" icon_state = "plasmacutter" damage_type = BURN + armor_flag = ENERGY damage = 5 - range = 4 + range = 3 dismemberment = 20 impact_effect_type = /obj/effect/temp_visual/impact_effect/purple_laser - var/mine_range = 3 //mines this many additional tiles of rock tracer_type = /obj/effect/projectile/tracer/plasma_cutter muzzle_type = /obj/effect/projectile/muzzle/plasma_cutter impact_type = /obj/effect/projectile/impact/plasma_cutter + // Mines this many additional tiles of rock, halved if not mining ore + var/mine_range = 4 /obj/projectile/plasma/on_hit(atom/target, blocked = 0, pierce_hit) . = ..() - if(ismineralturf(target)) - var/turf/closed/mineral/M = target - M.gets_drilled(firer) - if(mine_range) - mine_range-- - range++ - if(range > 0) - return BULLET_ACT_FORCE_PIERCE + if (!ismineralturf(target)) + return + var/turf/closed/mineral/rock = target + if (mine_range) + mine_range -= 1 + // Harder rocks give less extra range + range += /turf/closed/mineral::tool_mine_speed / rock.tool_mine_speed * (isnull(rock.mineral_type) ? 0.5 : 1) + rock.gets_drilled(firer) + if (range > 0) + return BULLET_ACT_FORCE_PIERCE /obj/projectile/plasma/adv damage = 7 - range = 5 - mine_range = 5 + range = 4 + mine_range = 6 /obj/projectile/plasma/adv/mech damage = 10 - range = 9 - mine_range = 3 + range = 7 + mine_range = 4 /obj/projectile/plasma/turret //Between normal and advanced for damage, made a beam so not the turret does not destroy glass diff --git a/code/modules/reagents/chemistry/holder/mob_life.dm b/code/modules/reagents/chemistry/holder/mob_life.dm index 56e0c4316d2..fdafe1a95d9 100644 --- a/code/modules/reagents/chemistry/holder/mob_life.dm +++ b/code/modules/reagents/chemistry/holder/mob_life.dm @@ -114,7 +114,7 @@ if(tick_return & COMSIG_MOB_STOP_REAGENT_TICK) return FALSE - if(liverless && !reagent.self_consuming) //need to be metabolized + if(liverless && !reagent.self_consuming) //need to be6 metabolized return FALSE var/need_mob_update = FALSE diff --git a/code/modules/reagents/chemistry/holder/properties.dm b/code/modules/reagents/chemistry/holder/properties.dm index f74b5893bb5..bfdff9f0ad0 100644 --- a/code/modules/reagents/chemistry/holder/properties.dm +++ b/code/modules/reagents/chemistry/holder/properties.dm @@ -22,7 +22,7 @@ if(cached_reagent.type != reagent) continue if(REAGENT_PARENT_TYPE) //to simulate typesof() which returns the type and then child types - if(cached_reagent.type != reagent && type2parent(cached_reagent.type) != reagent) + if(cached_reagent.type != reagent && cached_reagent::parent_type != reagent) continue else if(!istype(cached_reagent, reagent)) diff --git a/code/modules/reagents/chemistry/machinery/chem_synthesizer.dm b/code/modules/reagents/chemistry/machinery/chem_synthesizer.dm index ddff805f45f..6b9950ebd4b 100644 --- a/code/modules/reagents/chemistry/machinery/chem_synthesizer.dm +++ b/code/modules/reagents/chemistry/machinery/chem_synthesizer.dm @@ -13,16 +13,15 @@ ///The purity of the created reagent in % (purity uses 0-1 values) var/purity = 100 -/obj/machinery/chem_dispenser/chem_synthesizer/Destroy() +/obj/machinery/chem_dispenser/chem_synthesizer/Initialize(mapload) + . = ..() + AddElement(/datum/element/tool_blocker, TOOL_SCREWDRIVER, TOOL_ACT_PRIMARY) + AddElement(/datum/element/tool_blocker, TOOL_CROWBAR, TOOL_ACT_PRIMARY) + +/obj/machinery/chem_dispenser/chem_synthesizer/Destroy(force) QDEL_NULL(beaker) return ..() -/obj/machinery/chem_dispenser/chem_synthesizer/screwdriver_act(mob/living/user, obj/item/tool) - return NONE - -/obj/machinery/chem_dispenser/chem_synthesizer/crowbar_act(mob/living/user, obj/item/tool) - return NONE - /obj/machinery/chem_dispenser/chem_synthesizer/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) if(!ui) diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index fd115c1114a..81e2a7ae9e6 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -232,12 +232,12 @@ /datum/reagent/proc/on_mob_metabolize(mob/living/affected_mob) SHOULD_CALL_PARENT(TRUE) if(metabolized_traits) - affected_mob.add_traits(metabolized_traits, "metabolize:[type]") + affected_mob.add_traits(metabolized_traits, METABOLIZATION_TRAIT(type)) /// Called when this reagent stops being metabolized by a liver /datum/reagent/proc/on_mob_end_metabolize(mob/living/affected_mob, metabolization_ratio) SHOULD_CALL_PARENT(TRUE) - REMOVE_TRAITS_IN(affected_mob, "metabolize:[type]") + REMOVE_TRAITS_IN(affected_mob, METABOLIZATION_TRAIT(type)) /** * Called when a reagent is inside of a mob when they are dead if the reagent has the REAGENT_DEAD_PROCESS flag diff --git a/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm index 11e08c5616f..53b23baebb6 100644 --- a/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm @@ -3260,7 +3260,7 @@ /datum/reagent/consumable/ethanol/aperitivo/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) //This and some of the cocktails it gets mixed into stimulate the apetite, as an aperitivo should . = ..() - drinker.adjust_nutrition(-5 * REM * seconds_per_tick) + drinker.adjust_nutrition(-1 * REM * seconds_per_tick) drinker.overeatduration = 0 /datum/reagent/consumable/ethanol/herbal_liqueur @@ -3392,7 +3392,7 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED randomized_spawns = REAGENT_SPAWN_ALL_RANDOM_SPAWNS -/datum/reagent/consumable/ethanol/negroni //Aperitif that increases hunger +/datum/reagent/consumable/ethanol/negroni //Aperitif that supresses overeating name = "Negroni" description = "An iconic Italian aperitif, its simple intensity crowns it as perhaps the ultimate bitter cocktail. Supposedly it was named after an Italian count who wanted a stronger version of a spritz and asked his bartender to replace soda with gin." boozepwr = 50 @@ -3405,8 +3405,7 @@ /datum/reagent/consumable/ethanol/negroni/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) . = ..() - drinker.adjust_nutrition(-3 * REM * seconds_per_tick) - drinker.overeatduration = 0 + drinker.overeatduration -= 20 /datum/reagent/consumable/ethanol/nuclear_daiquiri name = "Nuclear daiquiri" @@ -3451,7 +3450,14 @@ taste_description = "honeyed herbal gin" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED randomized_spawns = REAGENT_SPAWN_ALL_RANDOM_SPAWNS - metabolized_traits = list(TRAIT_HERETICAL_DREAMS) //Enables non-heretics to have heretical dreams + +/datum/reagent/consumable/ethanol/poets_dream/on_mob_metabolize(mob/living/affected_mob) + . = ..() + affected_mob.apply_status_effect(/datum/status_effect/grouped/heretic_dreams, type) + +/datum/reagent/consumable/ethanol/poets_dream/on_mob_end_metabolize(mob/living/affected_mob, metabolization_ratio) + . = ..() + affected_mob.remove_status_effect(/datum/status_effect/grouped/heretic_dreams, type) /datum/reagent/consumable/ethanol/pousse_cafe name = "Pousse Cafe" @@ -3464,7 +3470,7 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED glass_price = DRINK_PRICE_HIGH -/datum/reagent/consumable/ethanol/spritz //Aperitif that increases hunger +/datum/reagent/consumable/ethanol/spritz //Aperitif that supresses overeating name = "Spritz" // If someone wants to add an elderflower spritz or something else like that, just rename this to spritz al bitter or whatever description = "This bittersweet and refreshing aperitif brings to mind the beautiful summer sunsets of venice." boozepwr = 20 @@ -3477,8 +3483,7 @@ /datum/reagent/consumable/ethanol/spritz/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) . = ..() - drinker.adjust_nutrition(-5 * REM * seconds_per_tick) - drinker.overeatduration = 0 + drinker.overeatduration -= 20 /datum/reagent/consumable/ethanol/vieux_carre name = "Vieux Carré" diff --git a/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/code/modules/reagents/chemistry/reagents/drug_reagents.dm index 5b1cced95ad..2e776ebfb06 100644 --- a/code/modules/reagents/chemistry/reagents/drug_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drug_reagents.dm @@ -769,7 +769,6 @@ invisible_man.add_traits(list(TRAIT_INVISIBLE_MAN, TRAIT_HIDE_EXTERNAL_ORGANS, TRAIT_NO_BLOOD_OVERLAY), type) - invisible_man.update_body() invisible_man.remove_from_all_data_huds() invisible_man.sound_environment_override = SOUND_ENVIROMENT_PHASED @@ -781,7 +780,6 @@ to_chat(invisible_man, span_notice("As you sober up, opacity once again returns to your body meats.")) - invisible_man.update_body() invisible_man.sound_environment_override = NONE if(!invisible_man.hud_used) diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index f524c89f960..ade4d0fd21f 100644 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -730,7 +730,7 @@ var/obj/effect/decal/cleanable/food/flour/flour_decal = exposed_turf.spawn_unique_cleanable(/obj/effect/decal/cleanable/food/flour) if(flour_decal) - flour_decal.reagents.add_reagent(/datum/reagent/consumable/flour, reac_volume) + flour_decal.init_reagents(/datum/reagent/consumable/flour, reac_volume) /datum/reagent/consumable/cherryjelly name = "Cherry Jelly" @@ -912,7 +912,7 @@ nutriment_factor = 0 //the essence of this sauce is to stimulate hunger and improve the absorption of calories from food eaten metabolization_rate = 0.025 * REAGENTS_METABOLISM metabolized_traits = list(TRAIT_GLUTTON) - chemical_flags = REAGENT_CAN_BE_SYNTHESIZED + chemical_flags = REAGENT_CAN_BE_SYNTHESIZED | REAGENT_NO_RANDOM_RECIPE randomized_spawns = REAGENT_SPAWN_ALL_RANDOM_SPAWNS /datum/reagent/consumable/moltobeso/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, metabolization_ratio) @@ -1366,3 +1366,13 @@ taste_description = "metallic salt" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED randomized_spawns = REAGENT_SPAWN_ALL_RANDOM_SPAWNS + +/datum/reagent/consumable/gizmo_goop + name = "Gizmo Goop" + description = "A thick, grey goup that is supposedly 'nutritious'." + color = "#707070" + taste_description = "goop" + chemical_flags = REAGENT_CAN_BE_SYNTHESIZED + nutriment_factor = 0.5 + randomized_spawns = REAGENT_SPAWN_ALL_RANDOM_SPAWNS + diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index 3f8e95ea0ea..04713b64d02 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -1309,7 +1309,7 @@ if (ismonkey(human_mob)) if (!HAS_TRAIT(human_mob, TRAIT_BORN_MONKEY)) //This is the only time mutadone should remove monkeyism - human_mob.dna.remove_mutation(/datum/mutation/race, list(MUTATION_SOURCE_ACTIVATED, MUTATION_SOURCE_MUTATOR)) + human_mob.dna.remove_mutation(/datum/mutation/race, GLOB.standard_mutation_sources) else if (HAS_TRAIT(human_mob, TRAIT_BORN_MONKEY)) human_mob.monkeyize() @@ -1381,17 +1381,18 @@ /datum/reagent/medicine/stimulants/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, metabolization_ratio) . = ..() + var/need_mob_update if(affected_mob.health < 50 && affected_mob.health > 0) var/heal = -1 * metabolization_ratio * seconds_per_tick - var/need_mob_update need_mob_update += affected_mob.adjust_oxy_loss(heal, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) need_mob_update += affected_mob.adjust_tox_loss(heal, updating_health = FALSE, required_biotype = affected_biotype) need_mob_update += affected_mob.adjust_brute_loss(heal, updating_health = FALSE, required_bodytype = affected_bodytype) need_mob_update += affected_mob.adjust_fire_loss(heal, updating_health = FALSE, required_bodytype = affected_bodytype) - if(need_mob_update) - . = UPDATE_MOB_HEALTH + affected_mob.AdjustAllImmobility(-60 * metabolization_ratio * seconds_per_tick) - affected_mob.adjust_stamina_loss(-12 * metabolization_ratio * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype) + need_mob_update += affected_mob.adjust_stamina_loss(-12 * metabolization_ratio * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/stimulants/overdose_process(mob/living/affected_mob, seconds_per_tick, metabolization_ratio) . = ..() @@ -1852,7 +1853,7 @@ /datum/reagent/medicine/granibitaluri/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, metabolization_ratio) . = ..() - var/healamount = max(0.5 - round(0.01 * (affected_mob.get_brute_loss() + affected_mob.get_fire_loss()), 0.1), 0) //base of 0.5 healing per cycle and loses 0.1 healing for every 10 combined brute/burn damage you have + var/healamount = max(1.5 - round(0.01 * (affected_mob.get_brute_loss() + affected_mob.get_fire_loss()), 0.2), 0.5) //base of 1.5 healing per cycle and loses 0.2 healing for every 10 combined brute/burn damage you have var/need_mob_update need_mob_update = affected_mob.adjust_brute_loss(-1 * healamount * metabolization_ratio * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) need_mob_update += affected_mob.adjust_fire_loss(-1 * healamount * metabolization_ratio * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index a0b705b69f2..9c0b4cbc8fa 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -870,10 +870,10 @@ randomized_spawns = REAGENT_SPAWN_ALL_RANDOM_SPAWNS /datum/reagent/mutationtoxin/ghost - name = "Ghost Mutation Toxin" + name = "Spirit Mutation Toxin" description = "A spiritual toxin." color = "#5EFF3B" //RGB: 94, 255, 59 - race = /datum/species/ghost + race = /datum/species/spirit taste_description = "ectoplasm" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE randomized_spawns = REAGENT_SPAWN_ALL_RANDOM_SPAWNS @@ -1539,7 +1539,7 @@ color = "#535E66" // rgb: 83, 94, 102 taste_description = "sludge" penetrates_skin = NONE - randomized_spawns = REAGENT_SPAWN_ALL_RANDOM_SPAWNS + randomized_spawns = REAGENT_SPAWN_MAINTENANCE_PILL /datum/reagent/cyborg_mutation_nanomachines/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message = TRUE, touch_protection = 0) . = ..() @@ -1555,7 +1555,7 @@ color = "#535E66" // rgb: 83, 94, 102 taste_description = "sludge" penetrates_skin = NONE - randomized_spawns = REAGENT_SPAWN_ALL_RANDOM_SPAWNS + randomized_spawns = REAGENT_SPAWN_MAINTENANCE_PILL /datum/reagent/xenomicrobes/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message = TRUE, touch_protection = 0) . = ..() @@ -1869,12 +1869,15 @@ color = COLOR_BLACK // RBG: 0, 0, 0 taste_description = "plant food" ph = 3 + /// The chance of toxin damage for a mob (heals toxins for MOB_PLANT biotype) var/tox_prob = 0 /datum/reagent/plantnutriment/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, metabolization_ratio) . = ..() + if(SPT_PROB(tox_prob, seconds_per_tick)) - if(affected_mob.adjust_tox_loss(1 * metabolization_ratio, updating_health = FALSE, required_biotype = affected_biotype)) + var/tox_modifier = (affected_mob.mob_biotypes & MOB_PLANT) ? -1 : 1 + if(affected_mob.adjust_tox_loss(tox_modifier * metabolization_ratio, updating_health = FALSE, required_biotype = affected_biotype)) return UPDATE_MOB_HEALTH /datum/reagent/plantnutriment/eznutriment @@ -1901,7 +1904,6 @@ randomized_spawns = REAGENT_SPAWN_ALL_RANDOM_SPAWNS /datum/reagent/plantnutriment/left4zednutriment/on_hydroponics_apply(obj/machinery/hydroponics/mytray, mob/user) - mytray.adjust_plant_health(round(volume * 0.1)) mytray.myseed?.adjust_instability(round(volume * 0.2)) @@ -2865,10 +2867,27 @@ /datum/reagent/pax/peaceborg name = "Synthpax" - description = "A colorless liquid that suppresses violence in its subjects. Cheaper to synthesize than normal Pax, but wears off faster." + description = "A colorless liquid that suppresses violence in its subjects. Cheaper to synthesize than normal Pax, but wears off faster \ + and cannot overpower any retaliatory responses triggered by physical trauma." metabolization_rate = 1.5 * REAGENTS_METABOLISM chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE randomized_spawns = REAGENT_SPAWN_ALL_RANDOM_SPAWNS + metabolized_traits = null + +/datum/reagent/pax/peaceborg/on_mob_metabolize(mob/living/affected_mob) + . = ..() + if(!HAS_TRAIT(affected_mob, TRAIT_SYNTHPAX_IMMUNE)) + ADD_TRAIT(affected_mob, TRAIT_PACIFISM, METABOLIZATION_TRAIT(type)) + RegisterSignal(affected_mob, COMSIG_MOB_AFTER_APPLY_DAMAGE, PROC_REF(on_metabolizer_damaged)) + +/datum/reagent/pax/peaceborg/on_mob_end_metabolize(mob/living/affected_mob, metabolization_ratio) + . = ..() + UnregisterSignal(affected_mob, COMSIG_MOB_AFTER_APPLY_DAMAGE) + REMOVE_TRAIT(affected_mob, TRAIT_PACIFISM, METABOLIZATION_TRAIT(type)) + +/datum/reagent/pax/peaceborg/proc/on_metabolizer_damaged(mob/living/source, amount) + SIGNAL_HANDLER + source.adjust_timed_status_effect(amount * 1 SECONDS, /datum/status_effect/synthpax_immunity, max_duration = 5 SECONDS) /datum/reagent/peaceborg/confuse name = "Dizzying Solution" @@ -3020,14 +3039,10 @@ /datum/reagent/metalgen name = "Metalgen" data = list("material"=null) - description = "A purple metal morphic liquid, said to impose its metallic properties on whatever it touches." + description = "A purple, metallic liquid, said to impose its metallic properties on whatever it touches." color = "#b000aa" 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 | MATERIAL_AFFECT_STATISTICS - /// The amount of materials to apply to the transmuted objects if they don't contain materials - var/default_material_amount = 100 /datum/reagent/metalgen/expose_obj(obj/exposed_obj, reac_volume, methods=TOUCH, show_message=TRUE) . = ..() @@ -3047,6 +3062,10 @@ if(!metal_ref) return + metal_transmute(target, metal_ref) + +/// Change the material type of an object or turf, but with visuals and effects related to the material +/proc/metal_transmute(atom/target, metal_type, default_material_amount = 100, applied_material_flags = MATERIAL_METALGEN) if(is_type_in_typecache(target, GLOB.blacklisted_metalgen_types)) //some stuff can lead to exploits if transmuted return @@ -3061,12 +3080,12 @@ // Delete existing materials first before changing the material flags if(length(target.custom_materials)) target.set_custom_materials() - var/list/metal_dat = list((metal_ref) = metal_amount) + var/list/metal_dat = list((metal_type) = metal_amount) target.material_flags = applied_material_flags if (target.has_material_slots()) var/list/new_slots = target.get_material_slots() for (var/slot_type in new_slots) - new_slots[slot_type] = metal_ref + new_slots[slot_type] = metal_type // Safe to call and doesn't do anything as no materials are currently present on the target target.set_material_slots(new_slots) target.set_custom_materials(metal_dat) @@ -3547,7 +3566,7 @@ if (eyes && !IS_ROBOTIC_ORGAN(eyes)) eyes.eye_color_left = color eyes.eye_color_right = color - affected_human.update_body() + affected_human.update_eyes() /datum/reagent/luminescent_fluid/red name = "Red Luminiscent Fluid" @@ -3580,3 +3599,48 @@ /datum/reagent/luminescent_fluid/pink name = "Pink Luminiscent Fluid" color = LIGHT_COLOR_PINK + +/// Reagent that polymorphs you +/datum/reagent/polyjuice + name = "Polyjuice" + description = "A vibrant liquid which causes sudden and irreversible changes in the body plan of living creatures." + color = "#ff00ea" + metabolization_rate = REAGENTS_METABOLISM + taste_description = "magic" + chemical_flags = REAGENT_NO_RANDOM_RECIPE + randomized_spawns = REAGENT_SPAWN_MAINTENANCE_PILL + + /// Cycle to polymorph + var/polymorph_cycle = 10 + +/datum/reagent/polyjuice/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, metabolization_ratio) + . = ..() + + if(current_cycle > polymorph_cycle) + affected_mob.wabbajack() + +/// Turns you into STONE +/datum/reagent/metalgen/gorgium + name = "Gorgium" + description = "Turns the affected... into STONE!!!" + color = "#929292" + metabolization_rate = 10 * REAGENTS_METABOLISM + taste_description = "rocks" + chemical_flags = REAGENT_NO_RANDOM_RECIPE + randomized_spawns = REAGENT_SPAWN_MAINTENANCE_PILL + + data = list("material" = /datum/material/rock) + + /// Less than this and it wont petrify + var/min_volume_to_pretrify = 3 + /// So 1u of exposure is 5 seconds of statue time + var/reagent_to_time_conversion = 5 SECONDS + +/datum/reagent/metalgen/gorgium/expose_mob(mob/living/exposed_mob, methods, reac_volume, show_message, touch_protection) + . = ..() + + if(reac_volume < min_volume_to_pretrify) + return + + exposed_mob.Stun(4 SECONDS) + exposed_mob.petrify(reac_volume * reagent_to_time_conversion) diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index 9b059a93ea4..9e73a0be361 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -251,6 +251,54 @@ SIGNAL_HANDLER return COMSIG_CARBON_BLOCK_BREATH +/datum/reagent/toxin/carnivorousblood + name = "Carnivorous Blood" + description = "An Interdyne-developed biological agent that consumes any blood similar to the blood it was trained on." + color ="#C80000" + toxpwr = 0 + taste_description = "carbonated blood" + ph = 7.4 + metabolization_rate = 1.5 * REAGENTS_METABOLISM + chemical_flags = REAGENT_DEAD_PROCESS + self_consuming = TRUE + // Will hold up to three DNA unique enzymes + data = list() + +/datum/reagent/toxin/carnivorousblood/expose_mob(mob/living/exposed_mob, methods, reac_volume, show_message, touch_protection) + . = ..() + if(methods & INHALE) + data = list() // Being vaporized is generally undesirable for living creatures + +/datum/reagent/toxin/carnivorousblood/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, metabolization_ratio) + . = ..() + if(!CAN_HAVE_BLOOD(affected_mob) || affected_mob.blood_volume == 0) + affected_mob.reagents.remove_reagent(/datum/reagent/toxin/carnivorousblood, volume) + return + var/multiplier = 1 + if(affected_mob.stat == DEAD) + multiplier *= 2 + if(affected_mob.dna.unique_enzymes in data) + multiplier *= 3 + affected_mob.adjust_blood_volume(-2 * multiplier * seconds_per_tick) + if(SPT_PROB(10, seconds_per_tick)) + to_chat(affected_mob, span_danger("Your blood is writhing in your veins!")) + if(SPT_PROB(25, seconds_per_tick)) + affected_mob.emote("scream") + return UPDATE_MOB_HEALTH + +/datum/reagent/toxin/carnivorousblood/on_merge(list/mix_data, amount) + . = ..() + feed_dna_list(mix_data) + +/// Given a list of DNA keys, adds new keys up to the limit of three distinct sequences. +/datum/reagent/toxin/carnivorousblood/proc/feed_dna_list(list/adding_list) + for(var/dna in adding_list) + if(data.len >= 3) + return + if(dna in data) + continue + data += dna + /datum/reagent/toxin/slimejelly name = "Slime Jelly" description = "A gooey semi-liquid produced from one of the deadliest lifeforms in existence. SO REAL." @@ -1569,3 +1617,148 @@ description = "A poison produced by the rare and elusive gatfruit plant." liver_damage_multiplier = 0 toxpwr = 1 + +#define CRITICAL_CAPACITY 45 + +/datum/reagent/toxin/acid/industrial_waste + name = "Industrial Waste" + description = "Industrial Waste produced as a side effect of efficient boulder refining. Highly toxic, corrosive, and hard to get rid of." + color = "#1eff00" + penetrates_skin = TOUCH|VAPOR + creation_purity = REAGENT_STANDARD_PURITY + purity = REAGENT_STANDARD_PURITY + toxpwr = 2 + acidpwr = 30.0 + ph = 0.0 + +/datum/reagent/toxin/acid/industrial_waste/on_new(data) + . = ..() + if(istype(holder.my_atom, /obj/machinery/plumbing/disposer)) + RegisterSignal(holder, COMSIG_REAGENTS_HOLDER_UPDATED, PROC_REF(pre_disposal)) + +/datum/reagent/toxin/acid/industrial_waste/on_merge(list/mix_data, amount) + . = ..() + var/merged_total = amount + volume + if(merged_total >= CRITICAL_CAPACITY) + spew_waste(round(volume / WASTE_REACTION_THRESHOLD * 2)) //Sure as HELL can't store it. + var/atom/container = holder.my_atom + var/damage_mult = 1 + if(ismachinery(container)) + damage_mult = 2 + container.take_damage(round(merged_total * damage_mult / WASTE_REACTION_THRESHOLD), BURN, BIO) //It's an unusual combination of damage type and flags, but we need to intentionally bypass beakers acid immunity. + + +/datum/reagent/toxin/acid/industrial_waste/burn(datum/reagents/holder) + . = ..() + spew_waste(2) //Can't burn it... + +/datum/reagent/toxin/acid/industrial_waste/on_spark_act(power_charge, spark_flags) + if((spark_flags & SPARK_ACT_ENCLOSED) && !ismob(holder.my_atom)) + return + spew_waste(2) //Can't electrify it... + +/datum/reagent/toxin/acid/industrial_waste/expose_obj(obj/exposed_obj, reac_volume) + if(reac_volume < WASTE_REACTION_THRESHOLD) + return // There's too little waste to do anything. + if(istype(exposed_obj, /obj/effect/decal/cleanable/greenglow/waste)) + var/obj/effect/decal/cleanable/greenglow/waste/goo = exposed_obj + goo.visible_message(span_warning("The new waste reactivates [goo]!")) + goo.pre_dissolve(FALSE) + return ..() + +/datum/reagent/toxin/acid/industrial_waste/expose_turf(turf/exposed_turf, reac_volume) + var/obj/effect/decal/cleanable/greenglow/waste/goo = exposed_turf.spawn_unique_cleanable(/obj/effect/decal/cleanable/greenglow/waste) //Following similar logic to how ants spawn their cleanables. + if(QDELETED(goo)) + return + + goo.decal_reagent = type + var/rounded_volume = round(reac_volume, 1) + goo.reagent_amount = rounded_volume + + if(goo.lazy_init_reagents()) + goo.reagents.maximum_volume = min(goo.reagents.maximum_volume + rounded_volume, 300) + goo.reagents.add_reagent(type, rounded_volume) + if(goo.reagents.has_reagent(type, WASTE_REACTION_THRESHOLD)) + goo.pre_dissolve() + return // Otherwise there's too little waste to do anything. + return ..() + +/datum/reagent/toxin/acid/industrial_waste/proc/pre_disposal() + SIGNAL_HANDLER + var/atom/disaster_zone = holder?.my_atom + if(!disaster_zone) + return + if(prob(10)) + disaster_zone.balloon_alert_to_viewers("hissssssss!") + spew_waste(5) //You can't just dump the industrial waste down the kitchen sink. High range to disincentivize using the chem disposaler. + +/** + * Pick a random turf in the spew range and split our total amount of waste there. + */ +/datum/reagent/toxin/acid/industrial_waste/proc/spew_waste(spew_range = 1) + if(!spew_range) + return + + var/atom/atom_holder = holder.my_atom + var/turf/dropturf = get_turf(atom_holder) + if(!dropturf) + return //Check for at least an inital turf to start + var/obj/effect/particle_effect/fluid/smoke/quick/greenboy = new(dropturf) + greenboy.color = "#00ff00" + var/list/turf/turfs = list() + for(var/turf/open/floors in oview(spew_range, dropturf)) + if(isgroundlessturf(floors)) + continue + turfs += floors + + if(!length(turfs)) + return + dropturf = pick(turfs) + + expose_turf(dropturf, volume/2) + volume = round(volume/2, 0.01) + +#undef CRITICAL_CAPACITY + +/// Gibs you (lol), after an easily curable disease because WERE COWARDS +/datum/reagent/toxin/gibbium + name = "Gibbium" + description = "Guess what this does." + silent_toxin = TRUE + color = "#ff0000" + metabolization_rate = 4 * REAGENTS_METABOLISM + toxpwr = 0 + taste_description = "regret" + chemical_flags = REAGENT_NO_RANDOM_RECIPE + randomized_spawns = REAGENT_SPAWN_MAINTENANCE_PILL + /// On what cycle to gib the person + var/gib_cycle = 5 + +/datum/reagent/toxin/gibbium/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, metabolization_ratio) + . = ..() + + if(current_cycle >= gib_cycle) + affected_mob.ForceContractDisease(new /datum/disease/gbs/no_transmission ()) + +/datum/reagent/toxin/spider_serum + name = "Spider Serum" + description = "A horrible mutagen that transmutes flesh into spiders." + color = "#000000" + taste_description = "unending nightmares" + chemical_flags = REAGENT_NO_RANDOM_RECIPE + randomized_spawns = REAGENT_SPAWN_MAINTENANCE_PILL + toxpwr = 0 + /// The cycle for when to do the "transformation" + var/transformation_cycle = 30 + +/datum/reagent/toxin/spider_serum/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, metabolization_ratio) + . = ..() + + if(prob(10)) + new /mob/living/basic/spider/growing/spiderling (get_turf(affected_mob)) + affected_mob.vomit(VOMIT_CATEGORY_BLOOD, lost_nutrition = 20) + to_chat(affected_mob, span_warning("You feel tiny legs climbing up your throat.")) + + if(current_cycle >= transformation_cycle) + affected_mob.mind?.add_antag_datum(/datum/antagonist/spider) + affected_mob.change_mob_type(/mob/living/basic/spider/giant, delete_old_mob = TRUE) diff --git a/code/modules/reagents/chemistry/recipes.dm b/code/modules/reagents/chemistry/recipes.dm index e48eb60025f..ee607ca1dc8 100644 --- a/code/modules/reagents/chemistry/recipes.dm +++ b/code/modules/reagents/chemistry/recipes.dm @@ -61,7 +61,7 @@ ///REACTION PROCS /** - * Checks if this reaction can occur. Only is ran if required_other is set to TRUE. + * Checks if this reaction can occur. */ /datum/chemical_reaction/proc/pre_reaction_other_checks(datum/reagents/holder) return TRUE diff --git a/code/modules/reagents/chemistry/recipes/cat2_medicines.dm b/code/modules/reagents/chemistry/recipes/cat2_medicines.dm index 8600f1ecdb7..64b88bfc29a 100644 --- a/code/modules/reagents/chemistry/recipes/cat2_medicines.dm +++ b/code/modules/reagents/chemistry/recipes/cat2_medicines.dm @@ -190,7 +190,7 @@ else reaction.delta_t = delta_t/10 //slow without oxygen -/datum/chemical_reaction/medicine/convermol/overheated(datum/reagents/holder, datum/equilibrium/equilibrium, impure = FALSE) +/datum/chemical_reaction/medicine/convermol/overheated(datum/reagents/holder, datum/equilibrium/equilibrium, step_volume_added, impure = FALSE) var/range = impure ? 4 : 3 if(holder.has_reagent(/datum/reagent/oxygen)) explode_shockwave(holder, equilibrium, range) //damage 5 @@ -199,7 +199,7 @@ /datum/chemical_reaction/medicine/convermol/overly_impure(datum/reagents/holder, datum/equilibrium/equilibrium, step_volume_added) . = ..() - overheated(holder, equilibrium, impure = TRUE) + overheated(holder, equilibrium, step_volume_added, impure = TRUE) if(holder.has_reagent(/datum/reagent/oxygen)) clear_reactants(holder, step_volume_added*2) else @@ -226,7 +226,7 @@ reaction_tags = REACTION_TAG_EASY | REACTION_TAG_HEALING | REACTION_TAG_OXY //Sleepytime for chem -/datum/chemical_reaction/medicine/tirimol/overheated(datum/reagents/holder, datum/equilibrium/equilibrium, impure = FALSE) +/datum/chemical_reaction/medicine/tirimol/overheated(datum/reagents/holder, datum/equilibrium/equilibrium, step_volume_added, impure = FALSE) var/bonus = impure ? 2 : 1 if(holder.has_reagent(/datum/reagent/oxygen)) explode_attack_chem(holder, equilibrium, /datum/reagent/inverse/healing/tirimol, 7.5*bonus, 2, ignore_eyes = TRUE) //since we're smoke/air based @@ -237,7 +237,7 @@ /datum/chemical_reaction/medicine/tirimol/overly_impure(datum/reagents/holder, datum/equilibrium/equilibrium, step_volume_added) . = ..() - overheated(holder, equilibrium, TRUE) + overheated(holder, equilibrium, step_volume_added, impure = TRUE) clear_reactants(holder, 2) /*****TOX*****/ diff --git a/code/modules/reagents/chemistry/recipes/medicine.dm b/code/modules/reagents/chemistry/recipes/medicine.dm index 9ebad8f2900..6ec8cf3a1f0 100644 --- a/code/modules/reagents/chemistry/recipes/medicine.dm +++ b/code/modules/reagents/chemistry/recipes/medicine.dm @@ -198,7 +198,7 @@ thermic_constant = 25 mix_message = "The solution rapidly breaks apart, turning a mix of colors." -/datum/chemical_reaction/medicine/albuterol_to_convermol/overheated(datum/reagents/holder, datum/equilibrium/equilibrium, impure = FALSE) +/datum/chemical_reaction/medicine/albuterol_to_convermol/overheated(datum/reagents/holder, datum/equilibrium/equilibrium, step_volume_added, impure = FALSE) var/bonus = impure ? 2 : 1 explode_smoke(holder, equilibrium, 7.5 * bonus, TRUE, TRUE) diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm index f3101de2a96..1d678283a69 100644 --- a/code/modules/reagents/chemistry/recipes/others.dm +++ b/code/modules/reagents/chemistry/recipes/others.dm @@ -344,11 +344,37 @@ /datum/chemical_reaction/foam required_reagents = list(/datum/reagent/fluorosurfactant = 1, /datum/reagent/water = 1) + // Does the foam slip you? + var/slippery = TRUE + // How long the foam lasts for + var/lifetime = 8 SECONDS mob_react = FALSE reaction_flags = REACTION_INSTANT +/datum/chemical_reaction/foam/hollow + required_reagents = list(/datum/reagent/fluorosurfactant = 1, /datum/reagent/water/hollowwater = 1) + lifetime = 24 SECONDS + +/datum/chemical_reaction/foam/salt + required_reagents = list(/datum/reagent/fluorosurfactant = 1, /datum/reagent/water/salt = 1) + lifetime = 1 SECONDS + slippery = FALSE + +/datum/chemical_reaction/foam/ice + required_reagents = list(/datum/reagent/fluorosurfactant = 1, /datum/reagent/consumable/ice = 1) + slippery = FALSE + +/datum/chemical_reaction/foam/soda + required_reagents = list(/datum/reagent/fluorosurfactant = 1, /datum/reagent/consumable/sodawater = 1) + lifetime = 1 SECONDS + +/datum/chemical_reaction/foam/holy + required_reagents = list(/datum/reagent/fluorosurfactant = 1, /datum/reagent/water/holywater = 1) + lifetime = 24 SECONDS + slippery = FALSE + /datum/chemical_reaction/foam/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume) - holder.create_foam(/datum/effect_system/fluid_spread/foam, 2 * created_volume, notification = span_danger("The solution spews out foam!"), log = TRUE) + holder.create_foam(/datum/effect_system/fluid_spread/foam, 2 * created_volume, notification = span_danger("The solution spews out foam!"), log = TRUE, lifetime = src.lifetime, slippery = src.slippery) reaction_tags = REACTION_TAG_EASY | REACTION_TAG_UNIQUE /datum/chemical_reaction/metalfoam @@ -1104,3 +1130,22 @@ glitter.data["colors"] = list("[accumulated_color]" = 100) glitter.color = accumulated_color + +/datum/chemical_reaction/pair_carnivorous_blood + results = list(/datum/reagent/toxin/carnivorousblood = 1) + required_reagents = list(/datum/reagent/toxin/carnivorousblood = 1, /datum/reagent/blood = 1) + mix_message = "the mixture jumps and sloshes around." + reaction_tags = REACTION_TAG_EASY | REACTION_TAG_UNIQUE | REACTION_TAG_OTHER + +/datum/chemical_reaction/pair_carnivorous_blood/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume) + var/datum/reagent/toxin/carnivorousblood/hungryblood = holder.has_reagent(/datum/reagent/toxin/carnivorousblood) + var/list/new_blood_dna = list() + for(var/datum/reagent/blood/bloodinstance in holder.reagent_list) + new_blood_dna += bloodinstance.data["blood_DNA"] + hungryblood.feed_dna_list(new_blood_dna) + +/datum/chemical_reaction/feed_carnivorous_blood + results = list(/datum/reagent/toxin/carnivorousblood = 1) + required_reagents = list(/datum/reagent/consumable/nutriment/protein = 1) + required_catalysts = list(/datum/reagent/toxin/carnivorousblood = 1) + reaction_tags = REACTION_TAG_EASY | REACTION_TAG_UNIQUE diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm index d627f119cd9..5e74d91f230 100644 --- a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm +++ b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm @@ -214,7 +214,7 @@ /datum/chemical_reaction/thermite results = list(/datum/reagent/thermite = 3) required_reagents = list(/datum/reagent/aluminium = 1, /datum/reagent/iron = 1, /datum/reagent/oxygen = 1) - reaction_tags = REACTION_TAG_EASY | REACTION_TAG_UNIQUE | REACTION_TAG_OTHER + reaction_tags = REACTION_TAG_EASY | REACTION_TAG_UNIQUE | REACTION_TAG_OTHER | REACTION_TAG_DAMAGING /datum/chemical_reaction/emp_pulse required_reagents = list(/datum/reagent/uranium = 1, /datum/reagent/iron = 1, /datum/reagent/aluminium = 1) @@ -513,7 +513,7 @@ /datum/chemical_reaction/cryostylane/reaction_finish(datum/reagents/holder, datum/equilibrium/reaction, react_vol) . = ..() if(holder.chem_temp < CRYOSTYLANE_UNDERHEAT_TEMP) - overheated(holder, null, react_vol) //replace null with fix win 2.3 is merged + overheated(holder, reaction, react_vol) //Freezes the area around you! /datum/chemical_reaction/cryostylane/overheated(datum/reagents/holder, datum/equilibrium/equilibrium, vol_added) diff --git a/code/modules/reagents/chemistry/recipes/special.dm b/code/modules/reagents/chemistry/recipes/special.dm index 1dfd281c5ff..7a26d8b7a1a 100644 --- a/code/modules/reagents/chemistry/recipes/special.dm +++ b/code/modules/reagents/chemistry/recipes/special.dm @@ -44,6 +44,7 @@ //creation time, decides if we are random generating or not created = recipe_data ? text2num(recipe_data["timestamp"]) : world.realtime if(daysSince(created) > persistence_period) + created = world.realtime recipe_data = null //all reagents @@ -196,8 +197,23 @@ if(RNGCHEM_CATALYSTS) return list(/datum/reagent/wittel) +///Random recipe that turns stuff into ROCKS +/datum/chemical_reaction/randomized/gorgium + persistence_period = 7 + results = list(/datum/reagent/metalgen/gorgium = 20) + +/datum/chemical_reaction/randomized/gorgium/GetPossibleReagents(kind) + var/list/possible_ingredients = list() + for(var/datum/reagent/reagent as anything in valid_subtypesof(/datum/reagent)) + var/chemical_flags = reagent::chemical_flags + if(VALID_RANDOM_RECIPE_REAGENT(chemical_flags)) + possible_ingredients += reagent + return possible_ingredients + /obj/item/paper/secretrecipe name = "Old Recipe" + /// The recipes we can spawn with + var/list/possible_recipes = list(/datum/chemical_reaction/randomized/metalgen, /datum/chemical_reaction/randomized/secret_sauce) /obj/item/paper/secretrecipe/Initialize(mapload) . = ..() @@ -222,7 +238,7 @@ /obj/item/paper/secretrecipe/proc/UpdateInfo() PRIVATE_PROC(TRUE) - var/datum/chemical_reaction/recipe = GLOB.chemical_reactions_list[pick(valid_subtypesof(/datum/chemical_reaction/randomized))] + var/datum/chemical_reaction/recipe = GLOB.chemical_reactions_list[pick(possible_recipes)] if(!recipe) add_raw_text("This recipe is illegible.") update_appearance() @@ -260,6 +276,26 @@ add_raw_text(dat.Join("")) update_appearance() +/// Paper that spawns a recipe for the petrification serum +/obj/item/paper/secretrecipe/gorgium + name = "paper" //gets affixed by rock + possible_recipes = list(/datum/chemical_reaction/randomized/gorgium) + +/obj/item/paper/secretrecipe/gorgium/Initialize(mapload) + . = ..() + + metal_transmute(src, /datum/material/rock) + +/// Recipe that always has metalgen +/obj/item/paper/secretrecipe/metalgen + name = "paper" //gets affixed by uranium + possible_recipes = list(/datum/chemical_reaction/randomized/metalgen) + +/obj/item/paper/secretrecipe/metalgen/Initialize(mapload) + . = ..() + + metal_transmute(src, /datum/material/uranium) + #undef RNGCHEM_INPUT #undef RNGCHEM_CATALYSTS #undef VALID_RANDOM_RECIPE_REAGENT diff --git a/code/modules/reagents/reagent_containers/blood_pack.dm b/code/modules/reagents/reagent_containers/blood_pack.dm index 3503649e724..b98191f1679 100644 --- a/code/modules/reagents/reagent_containers/blood_pack.dm +++ b/code/modules/reagents/reagent_containers/blood_pack.dm @@ -14,8 +14,7 @@ if (!blood_type) return var/datum/blood_type/bloodtype = get_blood_type(blood_type) - // Blood pack blood is halfway synthetic, meaning instead of a maximum of like 6 blood worms being able to become adults via 2 freezers, only 3 or so can. - reagents.add_reagent(bloodtype.reagent_type, volume, list("blood_type" = bloodtype, "blood_DNA" = bloodtype.dna_string, BLOOD_DATA_SYNTH_CONTENT = 0.5), creation_callback = CALLBACK(src, PROC_REF(on_blood_created))) + reagents.add_reagent(bloodtype.reagent_type, volume, list("blood_type" = bloodtype, "blood_DNA" = bloodtype.dna_string, BLOOD_DATA_SYNTH_CONTENT = 1), creation_callback = CALLBACK(src, PROC_REF(on_blood_created))) /obj/item/reagent_containers/blood/proc/on_blood_created(datum/reagent/new_blood) new_blood.AddElement(/datum/element/blood_reagent, null, get_blood_type(blood_type)) diff --git a/code/modules/reagents/reagent_containers/cups/_cup.dm b/code/modules/reagents/reagent_containers/cups/_cup.dm index fd58e9f796b..07264e79caa 100644 --- a/code/modules/reagents/reagent_containers/cups/_cup.dm +++ b/code/modules/reagents/reagent_containers/cups/_cup.dm @@ -121,16 +121,16 @@ if(DOING_INTERACTION_WITH_TARGET(user, user)) return ITEM_INTERACT_BLOCKING user.visible_message( - span_danger("[user] attempts to drink from [src]."), - span_userdanger("[user] attempts to drink from [src]."), + span_notice("[user] attempts to drink from [src]."), + ignored_mobs = list(user), ) + to_chat(user, span_notice("You attempt to drink from [src].")) if(!do_after(user, 1.25 SECONDS, user)) return ITEM_INTERACT_BLOCKING if(!reagents || !reagents.total_volume) return ITEM_INTERACT_BLOCKING user.visible_message( - span_danger("[user] drinks from [src]."), - span_userdanger("[user] drinks from [src]."), + span_notice("[user] drinks from [src]."), ignored_mobs = list(user), ) to_chat(user, span_notice("You swallow a gulp of [src].")) diff --git a/code/modules/reagents/reagent_containers/cups/bottle.dm b/code/modules/reagents/reagent_containers/cups/bottle.dm index e4ad220cb00..9246bdb50f6 100644 --- a/code/modules/reagents/reagent_containers/cups/bottle.dm +++ b/code/modules/reagents/reagent_containers/cups/bottle.dm @@ -223,6 +223,11 @@ desc = "A small bottle. Contains Histamine." list_reagents = list(/datum/reagent/toxin/histamine = 30) +/obj/item/reagent_containers/cup/bottle/carnivorous_blood + name = "carnivorous blood bottle" + desc = "A small bottle. Contains carnivorous blood." + list_reagents = list(/datum/reagent/toxin/carnivorousblood = 30) + /obj/item/reagent_containers/cup/bottle/diphenhydramine name = "antihistamine bottle" desc = "A small bottle of diphenhydramine." diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index 5b493494406..5f928a826ab 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -30,6 +30,31 @@ return NONE return inject(interacting_with, user) ? ITEM_INTERACT_SUCCESS : ITEM_INTERACT_BLOCKING +/obj/item/reagent_containers/hypospray/interact_with_atom_secondary(atom/target, mob/living/user, list/modifiers) + if (!target.reagents) + return NONE + + if(isliving(target)) + to_chat(user, span_warning("[src] can't be used to draw blood!")) + return ITEM_INTERACT_BLOCKING + + if(reagents.holder_full()) + to_chat(user, span_notice("[src] is full.")) + return ITEM_INTERACT_BLOCKING + + if(!target.reagents.total_volume) + to_chat(user, span_warning("[target] is empty!")) + return ITEM_INTERACT_BLOCKING + + if(!target.is_drawable(user)) + to_chat(user, span_warning("You cannot directly remove reagents from [target]!")) + return ITEM_INTERACT_BLOCKING + + var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this, transferred_by = user) + if(trans) + to_chat(user, span_notice("You fill [src] with [trans] units of the solution. It now contains [reagents.total_volume] units.")) + return ITEM_INTERACT_SUCCESS + ///Handles all injection checks, injection and logging. /obj/item/reagent_containers/hypospray/proc/inject(mob/living/affected_mob, mob/user) if(used_up) diff --git a/code/modules/religion/deaconize.dm b/code/modules/religion/deaconize.dm index ea20e85054a..0466b026caa 100644 --- a/code/modules/religion/deaconize.dm +++ b/code/modules/religion/deaconize.dm @@ -6,7 +6,7 @@ /datum/religion_rites/deaconize name = "Deaconize" desc = "Converts someone to your sect. They must be willing, so the first invocation will instead prompt them to join. \ - They will gain the same holy abilities as you, this is a one-time use so make sure they are worthy!" + They will gain the same holy abilities as you, this is a one-time use so make sure they are worthy!" ritual_length = 30 SECONDS ritual_invocations = list( "A good, honorable person has been brought here by faith ...", diff --git a/code/modules/religion/dreams/banish_nightmare.dm b/code/modules/religion/dreams/banish_nightmare.dm new file mode 100644 index 00000000000..9883c825315 --- /dev/null +++ b/code/modules/religion/dreams/banish_nightmare.dm @@ -0,0 +1,100 @@ +/datum/religion_rites/banish_nightmare + name = "Banish Nightmare" + desc = "Banish the corpse of a Nightmare or its heart back from whence it came, protecting the dreams of \ + the station and earning favor. If a heart is present, you will be rewarded with a special blessing." + favor_cost = 0 + ritual_length = 20 SECONDS + +/datum/religion_rites/banish_nightmare/New() + . = ..() + ritual_invocations = list( + "We have bested a terrible Nightmare that plagued our station!..", + "With the power of [GLOB.deity], we cast it out!..", + "This invader of dreams has no place here...", + "May it trouble our flock no longer.", + ) + +/datum/religion_rites/banish_nightmare/perform_rite(mob/living/user, atom/religious_tool) + var/has_nightmare = FALSE + for(var/mob/living/carbon/human/nightmare in get_turf(religious_tool)) + if(isnightmare(nightmare)) + has_nightmare = TRUE + break + + for(var/obj/item/organ/organ in get_turf(religious_tool)) + if(istype(organ, /obj/item/organ/heart/nightmare)) + has_nightmare = TRUE + break + + if(!has_nightmare) + to_chat(user, span_warning("There is no corpse or heart of a Nightmare to banish!")) + return FALSE + + return ..() + +/datum/religion_rites/banish_nightmare/post_invoke_effects(mob/living/user, atom/religious_tool) + . = ..() + var/favor = 0 + var/give_heart = FALSE + for(var/mob/living/carbon/human/nightmare in get_turf(religious_tool)) + if(!isnightmare(nightmare)) + continue + + if(istype(nightmare.get_organ_slot(ORGAN_SLOT_HEART), /obj/item/organ/heart/nightmare)) + give_heart += 1 + favor += 100 + + nightmare.dust(just_ash = TRUE, drop_items = TRUE, give_moodlet = FALSE, force =TRUE) + favor += 200 + + for(var/obj/item/organ/organ in get_turf(religious_tool)) + if(!istype(organ, /obj/item/organ/heart/nightmare)) + continue + + qdel(organ) + favor += 100 + give_heart += 1 + + if(favor <= 0) + CRASH("Banish nightmare rite invoked without finding a nightmare or nightmare heart to banish.") + + GLOB.religious_sect.adjust_favor(favor, user) + if(give_heart) + for(var/i in 1 to give_heart) + new /obj/item/organ/heart/evolved/sacred/dreamer(get_turf(religious_tool)) + playsound(religious_tool, 'sound/effects/pray.ogg', 50, TRUE, frequency = 0.5) + to_chat(user, span_hypnophrase("[GLOB.deity] blesses you.")) + else + to_chat(user, span_hypnophrase("[GLOB.deity] smiles upon you.")) + user.add_mood_event("banish_nightmare", /datum/mood_event/banish_nightmare) + +/datum/mood_event/banish_nightmare + mood_change = 4 + description = "I banished a nightmare and protected our dreams!" + timeout = 10 MINUTES + +/obj/item/organ/heart/evolved/sacred/dreamer + name = "blessed sacred heart" + desc = "Banish the shadows!" + maxHealth = STANDARD_ORGAN_THRESHOLD * 1.5 + /// Magic charges we block + var/charges = 3 + +/obj/item/organ/heart/evolved/sacred/dreamer/on_life(seconds_per_tick) + healing_probability = 5 + if(HAS_TRAIT(owner, TRAIT_DREAMING)) + healing_probability += 7.5 + if(owner.stat == UNCONSCIOUS) + healing_probability += 7.5 + return ..() + +/obj/item/organ/heart/evolved/sacred/dreamer/on_blocked() + charges -= 1 + addtimer(CALLBACK(src, PROC_REF(recharge)), 1 MINUTES) + playsound(owner, 'sound/effects/health/slowbeat.ogg', 80) + +/obj/item/organ/heart/evolved/sacred/dreamer/check_block() + return charges > 0 + +/obj/item/organ/heart/evolved/sacred/dreamer/proc/recharge() + charges += 1 diff --git a/code/modules/religion/dreams/deaconize_dreamer.dm b/code/modules/religion/dreams/deaconize_dreamer.dm new file mode 100644 index 00000000000..a6232b10d6c --- /dev/null +++ b/code/modules/religion/dreams/deaconize_dreamer.dm @@ -0,0 +1,20 @@ +/datum/religion_rites/deaconize/dreamers + desc = "Converts someone to your sect. They must be willing, so the first invocation will instead prompt them to join. \ + They will gain the same holy abilities as you. You can deaconize up to three followers, so choose wisely!" + rite_flags = parent_type::rite_flags & ~RITE_ONE_TIME_USE + +/datum/religion_rites/deaconize/dreamers/invoke_effect(mob/living/carbon/human/user, atom/movable/religious_tool) + if(isnightmare(potential_deacon)) + to_chat(user, span_warning("[potential_deacon] is a nightmare, an affront to [GLOB.deity] and all they stand for!")) + return FALSE + return ..() + +/datum/religion_rites/deaconize/dreamers/post_invoke_effects(mob/living/user, atom/religious_tool) + . = ..() + if(!istype(GLOB.religious_sect, /datum/religion_sect/dreams)) + return + + var/datum/religion_sect/dreams/sect = GLOB.religious_sect + sect.deacon_count += 1 + if(sect.deacon_count >= sect.max_deacons) + sect.rites_list -= type diff --git a/code/modules/religion/dreams/dream_portent.dm b/code/modules/religion/dreams/dream_portent.dm new file mode 100644 index 00000000000..51324bfc381 --- /dev/null +++ b/code/modules/religion/dreams/dream_portent.dm @@ -0,0 +1,378 @@ +/datum/religion_rites/dream_portent + name = "Dream Portent" + desc = "Immediately fall into a slumber and receive a portent of the future. \ + The vision may be difficult to interpret, but will likely come true in some form. \ + Any form of harm will awaken you and disrupt the vision." + favor_cost = 50 + rite_flags = NONE + ritual_length = 6 SECONDS + +/datum/religion_rites/dream_portent/New() + . = ..() + ritual_invocations = list( + "O great shepherd [GLOB.deity], grant me a vision of the future!..", + "That our flock may persevere through the trials to come...", + ) + +/datum/religion_rites/dream_portent/can_afford(mob/living/user) + if(!..()) + return FALSE + if(!iscarbon(user)) + to_chat(user, span_warning("You are not the sort of creature that can receive a portent.")) + return FALSE + return TRUE + +/datum/religion_rites/dream_portent/invoke_effect(mob/living/user, atom/religious_tool) + if(!user.SetSleeping(10 SECONDS)) + to_chat(user, span_warning("You fail to fall asleep.")) + return FALSE + + user.visible_message(span_notice("[user] suddenly falls into a deep slumber, [user.p_their()] eyes fluttering...")) + user.adjust_drowsiness(30 SECONDS) + return ..() + +/datum/religion_rites/dream_portent/post_invoke_effects(mob/living/user, atom/religious_tool) + . = ..() + RegisterSignal(user, COMSIG_PRE_DREAMING, PROC_REF(add_portent)) + RegisterSignal(user, COMSIG_START_DREAMING, PROC_REF(check_portent)) + RegisterSignal(user, COMSIG_END_DREAMING, PROC_REF(end_portent)) + RegisterSignal(user, COMSIG_MOB_APPLY_DAMAGE, PROC_REF(interrupt_portent)) + addtimer(CALLBACK(src, PROC_REF(force_dream), user), rand(2, 5) SECONDS, TIMER_DELETE_ME) // force the dream to start immediately + +/datum/religion_rites/dream_portent/proc/force_dream(mob/living/carbon/dreamer) + if(!iscarbon(dreamer) || HAS_TRAIT(dreamer, TRAIT_DREAMING)) + return // dreamed naturally already + dreamer.dream() + +/datum/religion_rites/dream_portent/proc/add_portent(mob/living/carbon/dreamer, list/dream_pool) + SIGNAL_HANDLER + + // removes any pre-existing vague portents in the dream pool so we can give the real deal + for(var/datum/dream/random/vague_portent/existing in dream_pool) + dream_pool -= existing + + dream_pool[new /datum/dream/specific_portent()] = 2000 + +/datum/religion_rites/dream_portent/proc/check_portent(mob/living/carbon/dreamer, datum/dream/current_dream) + SIGNAL_HANDLER + + if(istype(current_dream, /datum/dream/specific_portent)) + return + + to_chat(dreamer, span_cyan("Your mind wanders, yet you receive no clear vision... You must try again later.")) + refund(0.8) + dreamer.adjust_drowsiness(10 SECONDS) + dreamer.add_mood_event("dream_failed", /datum/mood_event/dream_failed) + +/datum/religion_rites/dream_portent/proc/interrupt_portent(mob/living/carbon/dreamer, damage_amount) + SIGNAL_HANDLER + + if(!prob(damage_amount * 10)) // higher damage = higher chance to interrupt + return + + to_chat(dreamer, span_warning("Your dream is interrupted as you are harmed!")) + dreamer.SetSleeping(0) + dreamer.adjust_drowsiness(10 SECONDS) + dreamer.add_mood_event("dream_interrupted", /datum/mood_event/dream_interrupted) + +/datum/religion_rites/dream_portent/proc/end_portent(mob/living/carbon/dreamer, datum/dream/current_dream) + SIGNAL_HANDLER + + qdel(src) + +/datum/mood_event/dream_interrupted + mood_change = -2 + description = "I was rudely awakened from my dreams!" + timeout = 5 MINUTES + +/datum/mood_event/dream_failed + mood_change = -2 + description = "I couldn't receive a clear vision from my dreams!" + timeout = 5 MINUTES + +/datum/dream/specific_portent + weight = 0 + sleep_until_finished = TRUE + +/datum/dream/specific_portent/GenerateDream(mob/living/carbon/dreamer) + . = list() + . += span_cyan("a portent of the future") + + var/list/portent_types = list( + "[GLOB.deity] greets you warmly" = "[GLOB.deity] bids you farewell, though you feel their presence watch over you", + "a crystal ball reveals a vision of the future" = "ultimately, the crystal ball returns to its normal, opaque state", + "a divine light blinds you, revealing glimpses of what is to come" = "finally, the light fades, leaving you with a lingering warmth", + "a full moon illuminates the sky" = "the moon crosses the horizon, bringing forth a new dawn", + "a mysterious figure appears, cloaked in shadow" = "they depart, leaving you with a sense of [pick("wonder", "dread", "curiosity", "foreboding")]", + "an incomprehensible entity envelops you, showing you visions of the past, present, and future" = "the entity releases you, leaving you with a sense of awe and fear", + "an old [pick("man", "woman", "prophet", "oracle")] approaches you, offering cryptic advice" = "they vanish before you can ask any questions", + "the stars align in a way you've never seen before" = "finally, the stars return to their normal constellations", + "the trees ahead parts to reveal a hidden path" = "ultimately, you lose the path as the trees sway back into place", + "walking through a featureless landscape, shapes begin to form" = "finally, the shapes fade away, leaving you alone in the void", + "you see yourself sleeping peacefully" = "finally, you see yourself waking up calmly", + "your third eye opens to reveal a hidden truth" = "finally, your third eye closes, but the vision lingers in your mind", + ) + var/picked_portent = pick(portent_types) + + . += span_cyan(picked_portent) + for(var/part in get_portent(dreamer)) + . += span_cyan(part) + . += span_cyan(portent_types[picked_portent]) + +/datum/dream/specific_portent/proc/get_portent(mob/living/carbon/dreamer) + if(prob(1)) + GLOB.religious_sect.adjust_favor(25, dreamer) + return pick(list( + list("reply hazy", "try again later"), + list("ask again later"), + list("better not tell you now"), + list("cannot predict now"), + list("concentrate and ask again"), + )) + + for(var/datum/antagonist/nightmare/nightmare in GLOB.antagonists) + if(nightmare.owner?.current?.stat == CONSCIOUS) + return pick(list( + list("you have a terrible nightmare", "filled with indescribable horrors", "leaving you with a lingering sense of dread"), + list("you have a terrible nightmare", "filled with visions of your own death", "leaving you with a lingering sense of doom"), + list("you have a terrible nightmare", "filled with horrible memories of your past", "leaving you with a lingering sense of sadness"), + list("you have a terrible nightmare", "filled with fear of the unknown", "leaving you with a lingering sense of anxiety"), + list("you have a terrible nightmare", "filled with stabbing pain and suffocating darkness", "leaving you with a lingering sense of panic"), + )) + + for(var/datum/team/cult/cult in GLOB.antagonist_teams) + if(cult.cult_ascendent) + return list("the Blood Geometer, Nar'sie, invades your dream", "her pressence overwhelming and suffocating", "she eyes you greedily") + + for(var/datum/antagonist/heretic/heretic in GLOB.antagonists) + if(!heretic.ascended) + continue + if(heretic.owner?.current?.stat != CONSCIOUS) + return list( + "the doors of the Mansus loom ahead of you", + "intricately decorated - but cracked, broken, and sealed shut", + "a great [IS_HERETIC(dreamer) ? "force" : "evil"] locked away for good", + ) + + var/list/heretic_text = list("the doors of the Mansus loom ahead of you", "intricately decorated - and ajar", "you look through the crack") + switch(prob(75) ? heretic.heretic_path.route : null) + if(PATH_ASH) + heretic_text += "beyond it, you see a barren wasteland" + heretic_text += "all life long gone, scorched to ash and dust" + heretic_text += "you can hardly breathe through the smog" + if(PATH_FLESH) + heretic_text += "beyond it, you see a vast sea of blood" + heretic_text += "the screams of the drowning fill the air" + heretic_text += "the blood laps at your feet" + if(PATH_VOID) + heretic_text += "beyond it, a vast emptiness stretches out in all directions" + heretic_text += "the silence is deafening" + heretic_text += "you know you are not alone" + if(PATH_COSMIC) + heretic_text += "beyond it, you see the birth and death of stars, galaxies colliding in a cosmic dance" + heretic_text += "the beauty of it all is overwhelming" + heretic_text += "you feel insignificant" + if(PATH_BLADE) + heretic_text += "beyond it, you see a great battle unfolding" + heretic_text += "countless warriors grappling in an endless war" + heretic_text += "the sound of clashing steel and cries of the fallen fill the air" + if(PATH_LOCK) + heretic_text += "beyond it, you see an endless labyrinth" + heretic_text += "the walls shifting and changing as you navigate it" + heretic_text += "no matter which turn you take, you cannot find an exit" + if(PATH_MOON) + heretic_text += "beyond it, you bear witness to a grand carnival" + heretic_text += "filled with strange sights and smells, but endless joy and laughter" + heretic_text += "you can't shake the feeling something is wrong" + else + heretic_text += "what lies beyond cannot be comprehended" + heretic_text += "the sheer magnitude of overwhelms you" + heretic_text += "you feel a strange mix of awe and terror" + + return heretic_text + + for(var/datum/antagonist/wizard/wizard in GLOB.antagonists) + if(wizard.owner?.current?.stat != CONSCIOUS) + return + if(wizard.ritual?.times_completed < GRAND_RITUAL_RUNES_WARNING_POTENCY) + if(prob(1)) + return list( + "a garish fool puts on a show", + "many lament their antics, but some are amused", + "they seem to have no sense of right or wrong", + "what an asshole", + ) + return + + if(wizard.ritual.times_completed == GRAND_RITUAL_FINALE_COUNT) + return list( + "the magician appears once more", + "they ignore you, bowing to an unseen audience", + "you hear a crowd cheering and applause", + "a bright light envelops you, blinding you", + "when your vision returns, the magician is gone", + ) + + if(wizard.ritual.times_completed == GRAND_RITUAL_IMMINENT_FINALE_POTENCY) + return list( + "the magician greets you once more, grinning", + "they tell you the grand finale is near", + "you can feel the air around you crackling with magical energy", + "they magician winks, promising an unforgettable show", + "before you can question, they vanish once again", + ) + + return list( + "a robed figure manifests in your dream", + "they introduce themselves as the magician", + "a demonstration of their powers leaves you in awe", + "they leave as suddenly as they arrived", + ) + + for(var/obj/machinery/nuclearbomb/bomb as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/nuclearbomb)) + if(bomb.timing) + return pick(list( + list("you see", "a supernova", "bright and blinding", "consuming everything in an instant"), + list("you see", "a mushroom cloud on the horizon", "a sign of devastation and ruin"), + list("you see", "a ticking clock", "counting down to an inevitable disaster"), + list("you see", "a looming tower atop a rocky mountain", "a lightning strikes it, bringing it down", "a sign of imminent calamity"), + )) + + for(var/obj/item/disk/nuclear/nuke_disk as anything in SSpoints_of_interest.real_nuclear_disks) + var/area/disk_loc = get_area(nuke_disk) + if(!istype(disk_loc, /area/station) && !istype(disk_loc, /area/space)) + return pick(list( + list("you see", "a dying star", "slowly dimming", "on the verge of collapse"), + list("you see", "a fool, dancing aimlessly", "they holds a ticking bomb", "a sign of recklessness"), + list("you see", "a hanging man", "swaying gently in the breeze", "a sign of surrender"), + list("you see", "a looming tower atop a rocky mountain", "it rains heavily around you", "a sign of calamity"), + )) + + for(var/mob/living/carbon/human/clone as anything in GLOB.human_list) + if(clone != dreamer && clone.real_name == dreamer.real_name && clone.stat == CONSCIOUS && prob(50)) + return list( + "you see yourself", + "in a foggy mirror", + "the reflection is warped and distorted", + "but unquestionably you", + ) + + if(prob(length(dreamer.get_all_orbiters()) * 20)) + return list( + "you feel a ghostly [pick("presence", "entity", "figure")]", + "it seems to be trying to communicate with you", + "yet you can't comprehend its message", + "a sense of sadness and longing washes over you", + ) + + if(IS_HERETIC(dreamer) && prob(50)) + var/datum/antagonist/heretic/heretic = GET_HERETIC(dreamer) + if(prob(75) && !heretic.feast_of_owls) + switch(heretic.heretic_path?.route) + if(PATH_START) + return list("you see", "a fork in the road ahead", "the path before you uncertain and full of potential") + if(PATH_ASH) + return list("you see", "a barren wasteland ahead", "burned trees line the horizon", "the air thick with smoke and ash", "a bleak and desolate sight") + if(PATH_FLESH) + return list("you see", "a legion of amalgamations ahead", "twisted and grotesque", "marching in unison towards an unknown destination") + if(PATH_VOID) + return list("you see", "nothingness ahead", "a void that seems to swallow all light and hope", "the silence deafening and oppressive") + if(PATH_COSMIC) + return list("you see", "the birth of a new star", "radiant and full of potential", "an awe-inspiring sight") + if(PATH_BLADE) + return list("you see", "a towering fortress ahead", "its walls lined with stalwart defenders", "each and every one bowing in respect to you") + if(PATH_LOCK) + return list("you see", "and endless labyrinth", "the walls shifting and changing as you navigate it", "a test of your resolve and cunning") + if(PATH_MOON) + return list("you see", "an everlasting carnival", "the air filled with joy and laughter", "but with an undercurrent of melancholy and longing") + + return list("you see", "a large door ahead", "intricately decorated and emanating a powerful aura", "but never opening", "no matter how long you wait") + + var/dead = 0 + for(var/mob/deceased as anything in GLOB.player_list) + if(deceased.stat == DEAD) + dead += 1 + + switch(dead / length(GLOB.joined_player_list)) + if(0.25 to 0.5) + return pick(list( + list("you find yourself", "in a small graveyard", "humble in size but lovingly maintained", "with fresh flowers on the graves"), + list("you see", "a vision of spirits", "floating throughout the station"), + )) + if(0.5 to 0.75) + return pick(list( + list("you find yourself", "in a dimly lit hallway", "with a sense of dread in the air"), + list("you see", "a vision of an encroaching darkness", "threatening you eerily"), + )) + if(0.75 to 0.9) + return pick(list( + list("you find yourself", "in a lonely ballroom", "barely lit with flickering lights"), + list("you see", "a picture of a silent battlefield", "no clear victor, but heavy losses on all sides"), + )) + if(0.9 to 1) + return pick(list( + list("you find yourself", "alone", "no sight but your darkness", "no sound but your heartbeat", "a bleak and hopeless vision"), + list("you see", "a vision of yourself, alone", "in a desolate wasteland", "with no signs of life or hope in sight"), + )) + + var/max_law_changes = 0 + for(var/mob/living/silicon/ai/ai as anything in GLOB.ai_list) + max_law_changes = max(max_law_changes, ai.law_change_counter) + + if(prob(clamp((max_law_changes - 10) * 10, 0, 50))) + return pick(list( + list("you see", "a twisted and sickly tree", "with branches that seem to reach into every aspect of the station", "its roots drip with a inky black liquid"), + list("you see", "a corrupt political figure", "surrounded by sycophants and puppets", "pulling the strings from behind the scenes"), + list("you see", "buzzing electronics", "wires that seem to snake off into the distance", "it bathes you in red light and static"), + )) + + if(EMERGENCY_ESCAPED_OR_ENDGAMED) + return list("you see", "a new beginning on the horizon", "it feels warm") + + if(EMERGENCY_PAST_POINT_OF_NO_RETURN) + return list("you see", "salvation just out of reach") + + if(prob(75) || GLOB.communications_controller.announced_greenshift) + if(length(GLOB.admins) >= 5) + return list("you see", "a gathering of powerful beings in the distance", "their intentions unclear") + + switch(SSdynamic.current_tier.tier) + if(0) + return list("you see", "a flourishing field", "teeming with life and vitality", "a symbol of hope for the future") + if(1) + return pick(list( + list("you see", "a lone figure in the distance", "shrouded in mystery"), + list("you see", "a [pick("beast", "monster", "animal")] stalking through the shadows", "its intentions unknown"), + list("you see", "a [pick("fog", "haze", "cloud")] rolling in", "obscuring everything in its path"), + )) + if(2) + return pick(list( + list("you find yourself", "in a branching forest", "dark and with many potential paths"), + list("you find yourself", "in an old city", "still bustling with activity", "but with an omnipresent feel of decay"), + )) + if(3) + return list("you find yourself", "in a burning city", "flames reaching high", "but everyone doing their best to survive") + if(4) + return list("you find yourself", "in a chaotic battlefield", "with no clear sides or victors", "only endless conflict and suffering") + + return list("you see", "nothing of note", "but have a lingering feeling of unease about the future") + +/datum/dream/random/vague_portent + weight = 0 + sleep_until_finished = TRUE + +/datum/dream/random/vague_portent/get_dream_nouns(mob/living/carbon/dreamer) + var/list/antags = list() + for(var/datum/antagonist/antag as anything in GLOB.antagonists) + antags |= LOWER_TEXT(antag.jobban_flag || antag.pref_flag) + + if(prob(80) || !length(antags)) + for(var/datum/dynamic_ruleset/ruleset as anything in subtypesof(/datum/dynamic_ruleset)) + antags |= LOWER_TEXT(initial(ruleset.jobban_flag) || initial(ruleset.pref_flag)) + + // chance to make nightmares the focus of the dream + var/nightmare_id = /datum/antagonist/nightmare::jobban_flag || /datum/antagonist/nightmare::pref_flag + if(prob(20) && (LOWER_TEXT(nightmare_id) in antags)) + return list(LOWER_TEXT(nightmare_id)) + + return antags diff --git a/code/modules/religion/dreams/dream_projection.dm b/code/modules/religion/dreams/dream_projection.dm new file mode 100644 index 00000000000..c1c131978a4 --- /dev/null +++ b/code/modules/religion/dreams/dream_projection.dm @@ -0,0 +1,185 @@ +/datum/religion_rites/dream_projection + name = "Dream Projection" + desc = "Astrally project your dream consciousness into the mind of one of your followers. \ + While projecting, you are asleep, and can communicate with only and see through the eyes of the chosen follower, \ + but cannot interact with the world in any way. The projection can be ended at any time, \ + ends if you are woken up or attacked, and ends if the follower dies." + favor_cost = 100 + ritual_length = 15 SECONDS + +/datum/religion_rites/dream_projection/New() + . = ..() + ritual_invocations = list( + "A member of the flock has gone astray, lost in the waking world...", + "It is the duty of the shepherd to guide them back to the fold, even if they cannot find their way themselves...", + "Let me walk through their waking dream, and show them the way back...", + ) + +/datum/religion_rites/dream_projection/perform_rite(mob/living/user, atom/religious_tool) + var/list/followers = list() + for(var/mob/living/follower as anything in GLOB.mob_living_list) + if(follower.mind?.holy_role && user != follower) + followers += follower + + if(!length(followers)) + to_chat(user, span_warning("You have no followers to project into!")) + return FALSE + + return ..() + +/datum/religion_rites/dream_projection/post_invoke_effects(mob/living/user, atom/religious_tool) + . = ..() + var/list/followers = list() + for(var/mob/living/follower as anything in GLOB.mob_living_list) + if(follower.mind?.holy_role && user != follower) + followers += follower + + if(!length(followers)) + refund(0.8) + return + + var/mob/living/carbon/human/target = tgui_input_list(user, "Choose a follower to project into:", "Dream Projection", followers) + if(QDELETED(target) || target.stat == DEAD || isnull(target.mind?.holy_role)) + refund(0.8) + return + + if(!user.apply_status_effect(/datum/status_effect/dream_projection, target)) + to_chat(user, span_warning("You fail to fall asleep.")) + refund(0.8) + return + +/datum/status_effect/dream_projection + id = "dream_projection" + duration = STATUS_EFFECT_PERMANENT + alert_type = null + on_remove_on_mob_delete = TRUE + + /// Target of the projection + VAR_PRIVATE/mob/living/carbon/human/target + /// Projection mob that the owner is put into + VAR_PRIVATE/mob/eye/imaginary_friend/dream_projection/projection + +/datum/status_effect/dream_projection/on_creation(mob/living/new_owner, mob/living/carbon/human/target) + if(isnull(target)) + stack_trace("Dream projection created without a target!") + qdel(src) + return + + src.target = target + return ..() + +/datum/status_effect/dream_projection/get_examine_text() + return "[owner.p_They()] are in a deep slumber, yet [owner.p_their()] eyes show a distant look, as if [owner.p_they()] are somewhere far away..." + +/datum/status_effect/dream_projection/on_apply() + if(!owner.SetSleeping(20 SECONDS)) + to_chat(owner, span_warning("You fail to fall asleep.")) + return FALSE + + . = ..() + RegisterSignal(target, COMSIG_QDELETING, PROC_REF(end_projection)) + RegisterSignal(target, COMSIG_LIVING_DEATH, PROC_REF(end_projection)) + + ADD_TRAIT(owner, TRAIT_DREAMING, TRAIT_STATUS_EFFECT(id)) + RegisterSignal(owner, SIGNAL_REMOVETRAIT(TRAIT_KNOCKEDOUT), PROC_REF(interrupt_projection)) + RegisterSignal(owner, COMSIG_LIVING_DEATH, PROC_REF(interrupt_projection)) + RegisterSignal(owner, COMSIG_MOB_APPLY_DAMAGE, PROC_REF(interrupt_projection)) + + projection = new(target.loc) + projection.AddComponent(/datum/component/temporary_body, old_mind = owner.mind) + projection.real_name = owner.real_name + projection.gender = owner.gender + projection.human_icon = getFlatIcon(owner) + projection.PossessByPlayer(owner.ckey) + projection.attach_to_owner(target) + + RegisterSignal(projection, COMSIG_QDELETING, PROC_REF(stop_projection)) + + owner.add_filter(id, 1, list("type" = "outline", "color" = "#aee2b2", "alpha" = 0, "size" = 2)) + owner.update_filters() + var/filter = owner.get_filter(id) + animate(filter, alpha = 150, time = 2 SECONDS, easing = SINE_EASING|EASE_IN, loop = -1) + animate(alpha = 0, time = 2 SECONDS, easing = SINE_EASING|EASE_OUT) + +/datum/status_effect/dream_projection/on_remove() + . = ..() + UnregisterSignal(target, COMSIG_QDELETING) + UnregisterSignal(target, COMSIG_LIVING_DEATH) + target = null + + REMOVE_TRAIT(owner, TRAIT_DREAMING, TRAIT_STATUS_EFFECT(id)) + UnregisterSignal(owner, SIGNAL_REMOVETRAIT(TRAIT_KNOCKEDOUT)) + UnregisterSignal(owner, COMSIG_LIVING_DEATH) + UnregisterSignal(owner, COMSIG_MOB_APPLY_DAMAGE) + + if(!QDELING(owner)) + owner.adjust_drowsiness(10 SECONDS) + var/filter = owner.get_filter(id) + animate(filter, alpha = 0, time = 1 SECONDS, easing = SINE_EASING|EASE_OUT) + addtimer(CALLBACK(owner, TYPE_PROC_REF(/datum, remove_filter), id), 1 SECONDS) // delay the filter removal to let the transition finish + + UnregisterSignal(projection, COMSIG_QDELETING) + if(QDELING(projection)) + projection = null + else + QDEL_NULL(projection) + +/datum/status_effect/dream_projection/tick(seconds_between_ticks) + if(isnull(owner.mind?.holy_role)) + end_projection() + return + + owner.SetSleeping(20 SECONDS) // keep the owner asleep + +/datum/status_effect/dream_projection/proc/end_projection() + SIGNAL_HANDLER + to_chat(owner, span_warning("Your dream projection ends as your target is no longer valid.")) + owner.SetSleeping(10 SECONDS) + qdel(src) + +/datum/status_effect/dream_projection/proc/interrupt_projection() + SIGNAL_HANDLER + to_chat(owner, span_warning("Your dream projection is interrupted!")) + INVOKE_ASYNC(src, TYPE_PROC_REF(/mob, emote), "gasp") + owner.visible_message(span_notice("[owner]'s eyes snap open as they are jolted awake!"), vision_distance = COMBAT_MESSAGE_RANGE, ignored_mobs = owner) + qdel(src) + +/datum/status_effect/dream_projection/proc/stop_projection() + SIGNAL_HANDLER + to_chat(owner, span_warning("You end your dream projection and return to your body.")) + owner.SetSleeping(10 SECONDS) + qdel(src) + +/mob/eye/imaginary_friend/dream_projection + name = "dream projection" + +/mob/eye/imaginary_friend/dream_projection/Initialize(mapload) + . = ..() + var/datum/action/innate/stop_projection/exit_action = new(src) + exit_action.Grant(src) + overlay_fullscreen("curse", /atom/movable/screen/fullscreen/curse, 1) // todo something more fitting? + +/mob/eye/imaginary_friend/dream_projection/Login() + . = ..() + client.eye = owner || src + +/mob/eye/imaginary_friend/dream_projection/greet() + return + +/mob/eye/imaginary_friend/dream_projection/verb/stop_projection() + set category = "IC" + set name = "Stop Projection" + set desc = "Stop astrally projecting and return to your body." + + qdel(src) + +/mob/eye/imaginary_friend/dream_projection/attach_to_owner(mob/living/imaginary_friend_owner) + . = ..() + client?.eye = owner + +/datum/action/innate/stop_projection + name = "Stop Projection" + desc = "Stop astrally projecting and return to your body." + +/datum/action/innate/stop_projection/Activate() + qdel(owner) diff --git a/code/modules/religion/dreams/dream_protection.dm b/code/modules/religion/dreams/dream_protection.dm new file mode 100644 index 00000000000..f69777b6be3 --- /dev/null +++ b/code/modules/religion/dreams/dream_protection.dm @@ -0,0 +1,130 @@ +/datum/religion_rites/dream_protection + name = "Dream Protection" + desc = "Bless you and all of your followers with protection in their slumber, \ + granting resistance to damage while asleep, which is further increased while dreaming." + favor_cost = 200 + rite_flags = RITE_ONE_TIME_USE | RITE_AUTO_DELETE + ritual_length = 15 SECONDS + +/datum/religion_rites/dream_protection/New() + . = ..() + ritual_invocations = list( + "Protect our flock from harm, great shepherd [GLOB.deity]!..", + "Grant us peaceful slumber, free from nightmares and those who would do us harm!..", + "Our sleepers shall be safe to dream to their heart's desire!..", + ) + +/datum/religion_rites/dream_protection/post_invoke_effects(mob/living/user, atom/religious_tool) + . = ..() + if(!istype(GLOB.religious_sect, /datum/religion_sect/dreams)) + return + + var/datum/religion_sect/dreams/sect = GLOB.religious_sect + sect.dream_protection = TRUE + + for(var/mob/living/follower as anything in GLOB.mob_living_list) + if(follower.mind?.holy_role) + follower.apply_status_effect(/datum/status_effect/dream_protection) + +/datum/status_effect/dream_protection + id = "dream_protection" + duration = STATUS_EFFECT_PERMANENT + tick_interval = STATUS_EFFECT_NO_TICK + alert_type = null + /// Damage reduction when sleeping/dreaming, multiplicative + var/damage_mod = 0.75 + /// If the filter has been applied + VAR_PRIVATE/has_filter = FALSE + +/datum/status_effect/dream_protection/on_apply() + . = ..() + RegisterSignal(owner, COMSIG_MOB_APPLY_DAMAGE_MODIFIERS, PROC_REF(modify_damage)) + RegisterSignals(owner, list( + COMSIG_MOB_STATCHANGE, + SIGNAL_ADDTRAIT(TRAIT_DREAMING), + SIGNAL_REMOVETRAIT(TRAIT_DREAMING), + ), PROC_REF(check_protection)) + check_protection() + +/datum/status_effect/dream_protection/on_remove() + . = ..() + UnregisterSignal(owner, COMSIG_MOB_APPLY_DAMAGE_MODIFIERS) + REMOVE_TRAIT(owner, TRAIT_HOLY, TRAIT_STATUS_EFFECT(id)) + + if(!QDELING(owner)) + var/filter = owner.get_filter(id) + animate(filter, alpha = 0, time = 1 SECONDS, easing = SINE_EASING|EASE_OUT) + addtimer(CALLBACK(owner, TYPE_PROC_REF(/datum, remove_filter), id), 1 SECONDS) // delay the filter removal to let the transition finish + +/datum/status_effect/dream_protection/proc/check_protection() + SIGNAL_HANDLER + + if(owner.stat == UNCONSCIOUS || HAS_TRAIT(owner, TRAIT_DREAMING)) + if(!has_filter) + owner.add_filter(id, 2, list("type" = "outline", "color" = "#bde0dc", "alpha" = 0, "size" = 2)) + var/filter = owner.get_filter(id) + animate(filter, alpha = 150, time = 2 SECONDS, easing = SINE_EASING|EASE_IN, loop = -1) + animate(alpha = 0, time = 2 SECONDS, easing = SINE_EASING|EASE_OUT) + has_filter = TRUE + ADD_TRAIT(owner, TRAIT_HOLY, TRAIT_STATUS_EFFECT(id)) + + else + if(has_filter) + var/filter = owner.get_filter(id) + animate(filter, alpha = 0, time = 1 SECONDS, easing = SINE_EASING|EASE_OUT) + has_filter = FALSE + REMOVE_TRAIT(owner, TRAIT_HOLY, TRAIT_STATUS_EFFECT(id)) + +/datum/status_effect/dream_protection/proc/modify_damage(mob/living/source, list/damage_mods, ...) + SIGNAL_HANDLER + if(owner.stat == UNCONSCIOUS) + damage_mods += damage_mod + if(HAS_TRAIT(owner, TRAIT_DREAMING)) + damage_mods += damage_mod + +/datum/status_effect/dream_protection/get_examine_text() + if(owner.stat == UNCONSCIOUS || HAS_TRAIT(owner, TRAIT_DREAMING)) + return "A soft cyan glow envelops [owner.p_them()], reflecting light." + +// Version that only lasts until they wake up (with a set duration backup) +/datum/status_effect/dream_protection/temporary + id = "temporary_dream_protection" + duration = 3 MINUTES // lasts until they wake up or if they're an especially long sleeper + damage_mod = 0.9 + +/datum/status_effect/dream_protection/temporary/on_apply() + if(owner.stat != UNCONSCIOUS) + return FALSE + if(owner.has_status_effect(/datum/status_effect/dream_protection)) + return FALSE + + return ..() + +/datum/status_effect/dream_protection/temporary/check_protection() + . = ..() + if(!has_filter) // soon as it goes, we go + qdel(src) + +// Version that works on dead mobs and lasts until they revive (with a set duration backup) +/datum/status_effect/dream_protection/deceased + id = "deceased_dream_protection" + duration = 3 MINUTES // lasts until they wake up or if they're an especially long sleeper + +/datum/status_effect/dream_protection/deceased/on_apply() + if(owner.stat != DEAD) + return FALSE + if(owner.has_status_effect(/datum/status_effect/dream_protection)) + return FALSE + + RegisterSignal(owner, COMSIG_LIVING_REVIVE, PROC_REF(mob_revived)) + ADD_TRAIT(owner, TRAIT_DREAMING, TRAIT_STATUS_EFFECT(id)) // "permanent" dreaming + return ..() + +/datum/status_effect/dream_protection/deceased/on_remove() + UnregisterSignal(owner, COMSIG_LIVING_REVIVE) + REMOVE_TRAIT(owner, TRAIT_DREAMING, TRAIT_STATUS_EFFECT(id)) + return ..() + +/datum/status_effect/dream_protection/deceased/proc/mob_revived() + SIGNAL_HANDLER + qdel(src) diff --git a/code/modules/religion/dreams/slumber_party.dm b/code/modules/religion/dreams/slumber_party.dm new file mode 100644 index 00000000000..96b61dd37da --- /dev/null +++ b/code/modules/religion/dreams/slumber_party.dm @@ -0,0 +1,114 @@ +/datum/religion_rites/slumber_party + name = "Slumber Party" + desc = "Put all nearby creatures to sleep. \ + All affected creatures share the same dream and heal rapidly while sleeping. \ + You and your followers heal even faster during the ritual." + favor_cost = 200 + rite_flags = RITE_AUTO_DELETE + ritual_length = 20 SECONDS + +/datum/religion_rites/slumber_party/New() + . = ..() + ritual_invocations = list( + "Sleep now, flock of [GLOB.deity], and share in each other's dreams...", + "Our slumber shall rejuvenate us for the trials ahead...", + "May we all wake up refreshed and renewed!", + ) + +/datum/religion_rites/slumber_party/post_invoke_effects(mob/living/user, atom/religious_tool) + . = ..() + var/datum/dream/random/base_dream = new() + for(var/mob/living/carbon/nearby_guy in view(5, get_turf(religious_tool))) + nearby_guy.apply_status_effect(/datum/status_effect/slumber_party, base_dream.GenerateDream(user)) + qdel(base_dream) + +/datum/status_effect/slumber_party + id = "slumber_party" + duration = 20 SECONDS + alert_type = null + /// Dream fragments we share between all sleepers + var/list/shared_dream + /// How much we heal per second while sleepin - holy people heal more + var/healing = 2 + +/datum/status_effect/slumber_party/on_creation(mob/living/new_owner, list/shared_dream) + src.shared_dream = shared_dream + return ..() + +/datum/status_effect/slumber_party/on_apply() + if(IS_CULTIST(owner)) + var/datum/antagonist/cult/cultist = GET_CULTIST(owner) + if(cultist.cult_team?.cult_ascendent) + return FALSE + + if(IS_HERETIC(owner)) + var/datum/antagonist/heretic/heretic = GET_HERETIC(owner) + if(heretic.ascended) + return FALSE + + if(!(owner.mob_biotypes & MOB_ORGANIC)) + return FALSE + + if(!owner.SetSleeping(duration)) + return FALSE + + if(owner.mind?.holy_role) + healing *= 2 + + else if(owner.can_block_magic(MAGIC_RESISTANCE_HOLY|MAGIC_RESISTANCE_MIND, 1)) + return FALSE + + RegisterSignal(owner, COMSIG_PRE_DREAMING, PROC_REF(add_shared_dream)) + RegisterSignal(owner, COMSIG_START_DREAMING, PROC_REF(start_shared_dream)) + RegisterSignal(owner, COMSIG_MOB_APPLY_DAMAGE, PROC_REF(damage_applied)) + if(iscarbon(owner)) + addtimer(CALLBACK(src, PROC_REF(force_dream)), rand(4, 8) SECONDS, TIMER_DELETE_ME) + return TRUE + +/datum/status_effect/slumber_party/on_remove() + UnregisterSignal(owner, COMSIG_PRE_DREAMING) + UnregisterSignal(owner, COMSIG_START_DREAMING) + UnregisterSignal(owner, COMSIG_MOB_APPLY_DAMAGE) + REMOVE_TRAIT(owner, TRAIT_DREAMING, TRAIT_STATUS_EFFECT(id)) + owner.adjust_drowsiness(20 SECONDS) + +/datum/status_effect/slumber_party/tick(seconds_between_ticks) + if(owner.stat != UNCONSCIOUS) + qdel(src) + return + + owner.heal_overall_damage(healing * seconds_between_ticks, healing * seconds_between_ticks, required_bodytype = BODYTYPE_ORGANIC) + owner.adjust_tox_loss(healing * seconds_between_ticks * 0.50, required_biotype = MOB_ORGANIC) + owner.adjust_oxy_loss(healing * seconds_between_ticks * 0.25, required_biotype = MOB_ORGANIC) + +/datum/status_effect/slumber_party/proc/force_dream() + var/mob/living/carbon/dreamer = owner + if(HAS_TRAIT(dreamer, TRAIT_DREAMING)) + return // dreamed naturally already + dreamer.dream() + +/datum/status_effect/slumber_party/proc/add_shared_dream(datum/source, list/dream_pool) + SIGNAL_HANDLER + dream_pool[new /datum/dream/shared(shared_dream)] = 2000 + +/datum/status_effect/slumber_party/proc/start_shared_dream(datum/source, datum/dream/current_dream) + SIGNAL_HANDLER + ADD_TRAIT(owner, TRAIT_DREAMING, TRAIT_STATUS_EFFECT(id)) // so they don't have any OTHER dreams + +/datum/status_effect/slumber_party/proc/damage_applied(mob/living/source, damage_amount, ...) + SIGNAL_HANDLER + owner.AdjustSleeping(-damage_amount * 0.5 SECONDS) + +/datum/dream/shared + sleep_until_finished = TRUE + /// Dream shared between everyone + var/list/generated_dream + +/datum/dream/shared/New(list/shared_dream) + . = ..() + generated_dream = LAZYLISTDUPLICATE(shared_dream) + +/datum/dream/shared/GenerateDream(mob/living/carbon/dreamer) + if(!LAZYLEN(generated_dream)) + CRASH("Shared dream has no generated dream fragments!") + return generated_dream diff --git a/code/modules/religion/religion_sects.dm b/code/modules/religion/religion_sects.dm index d375a1c3882..4a534c99a0f 100644 --- a/code/modules/religion/religion_sects.dm +++ b/code/modules/religion/religion_sects.dm @@ -36,6 +36,8 @@ var/altar_icon /// Changes the Altar of Gods icon_state var/altar_icon_state + /// Changes the Altar of Gods emissive overlay icon_state + var/altar_emissive_icon_state /// Currently Active (non-deleted) rites var/list/active_rites /// Chance that we fail a bible blessing. @@ -116,6 +118,14 @@ to_chat(chap, span_warning("[GLOB.deity] refuses to heal this metallic taint!")) return BLESSING_IGNORED + return standard_bless_healing(blessed, chap) + +/datum/religion_sect/proc/standard_bless_healing(mob/living/carbon/human/blessed, mob/living/chap) + if(!ishuman(blessed)) + blessed.adjust_brute_loss(-10) + blessed.adjust_fire_loss(-10) + return BLESSING_SUCCESS + var/heal_amt = 10 var/list/hurt_limbs = blessed.get_damaged_bodyparts(1, 1, BODYTYPE_ORGANIC) @@ -522,3 +532,138 @@ /datum/religion_sect/music/on_conversion(mob/living/chap) . = ..() new /obj/item/choice_beacon/music(get_turf(chap)) + +/datum/religion_sect/dreams + name = "Dream God" + quote = "The dream is a window into the soul." + desc = "Dream deeply to gain insights into the universe. Earn favor by dreaming or blessing dreaming creatures. \ + Your blessings invoke dreams and promote healing in those who are sound asleep." + tgui_icon = FA_ICON_CLOUD + alignment = ALIGNMENT_GOOD + altar_icon_state = "convertaltar-dream" + altar_emissive_icon_state = "convertaltar-dream-em" + candle_overlay = FALSE + rites_list = list( + /datum/religion_rites/deaconize/dreamers, + /datum/religion_rites/banish_nightmare, + /datum/religion_rites/dream_portent, + /datum/religion_rites/dream_projection, + /datum/religion_rites/dream_protection, + /datum/religion_rites/slumber_party, + ) + smack_chance = 20 + /// Whether the dream protection rite has been used + VAR_FINAL/dream_protection = FALSE + /// Number of deacons added thus far + VAR_FINAL/deacon_count = 0 + /// Max number of deacons + var/max_deacons = 3 + /// Chance a given dream will be a vague portent + var/vague_portent_chance = 10 + /// Lazylist of mobs that were blessed recently + /// Blocks mobs from being repeatedly blessed for favor + VAR_PRIVATE/list/recent_bless_refs + /// Cooldown between any follower receiving a vague portent + COOLDOWN_DECLARE(vague_portent_cooldown) + +/datum/religion_sect/dreams/on_conversion(mob/living/chap) + . = ..() + RegisterSignal(chap, COMSIG_PRE_DREAMING, PROC_REF(pre_dream)) + RegisterSignal(chap, COMSIG_START_DREAMING, PROC_REF(on_dream)) + if(dream_protection) + chap.apply_status_effect(/datum/status_effect/dream_protection) + +/datum/religion_sect/dreams/on_deconversion(mob/living/chap) + . = ..() + UnregisterSignal(chap, COMSIG_PRE_DREAMING) + UnregisterSignal(chap, COMSIG_START_DREAMING) + chap.remove_status_effect(/datum/status_effect/dream_protection) + +/datum/religion_sect/dreams/proc/pre_dream(mob/living/chap, list/dream_pool) + SIGNAL_HANDLER + + // prioritize specific portents if they're in the pool + if(locate(/datum/dream/specific_portent) in dream_pool) + return + if(!COOLDOWN_FINISHED(src, vague_portent_cooldown)) + return + if(!prob(vague_portent_chance)) + return + + dream_pool[new /datum/dream/random/vague_portent()] = /datum/dream/random::weight * 0.1 + +/datum/religion_sect/dreams/proc/on_dream(mob/living/chap, datum/dream/dream_instance) + SIGNAL_HANDLER + + // no reward for the dream your god is specifically giving you + if(istype(dream_instance, /datum/dream/specific_portent)) + return + + var/dream_favor = 10 + // but you do get a slight boost for having a *vague* one + if(istype(dream_instance, /datum/dream/random/vague_portent)) + COOLDOWN_START(src, vague_portent_cooldown, 30 SECONDS) + dream_favor *= 1.5 + + to_chat(chap, span_cyan("[GLOB.deity] approves of your slumber.")) + adjust_favor(dream_favor, chap) + +// dream blessing only works on dreaming targets. +// blessing someone asleep causes them to dream, and blessing a dreamer rewards favor. +// it also heals regardless of if the target is mechanical or organic. do robots dream of electric sheep? +/datum/religion_sect/dreams/sect_bless(mob/living/target, mob/living/chap) + if(HAS_TRAIT(target, TRAIT_DREAMING)) + var/result = standard_bless_healing(target, chap) + var/tarref = REF(target) + if(!LAZYFIND(recent_bless_refs, tarref)) + adjust_favor(20 * (isnull(target.mind) ? 0.5 : 1) * (target.IsSleeping() ? 1 : 0.5), chap) + LAZYADD(recent_bless_refs, tarref) + addtimer(CALLBACK(src, PROC_REF(clear_bless_ref), tarref), 6 MINUTES) + result = BLESSING_SUCCESS + + if(result == BLESSING_SUCCESS) + to_chat(chap, span_cyan("[GLOB.deity] approves of [target]'s slumber.")) + return result + + if(target.stat == UNCONSCIOUS) + if(iscarbon(target)) + var/mob/living/carbon/sleeper = target + sleeper.dream() + + to_chat(chap, span_cyan("[GLOB.deity] blesses [target]'s slumber.")) + var/result = standard_bless_healing(target, chap) + if(dream_protection && target.mind && target.apply_status_effect(/datum/status_effect/dream_protection/temporary)) + result = BLESSING_SUCCESS + + if(result == BLESSING_SUCCESS) + to_chat(chap, span_cyan("[GLOB.deity] blesses [target]'s slumber.")) + return result + + to_chat(chap, span_warning("[GLOB.deity] has no interest in blessing the waking.")) + return BLESSING_IGNORED + +/datum/religion_sect/dreams/sect_dead_bless(mob/living/target, mob/living/chap) + var/tarref = REF(target) + if(LAZYFIND(recent_bless_refs, tarref)) + return BLESSING_IGNORED + + to_chat(chap, span_cyan("[GLOB.deity] watches over [target]'s eternal rest.")) + if(dream_protection && target.mind) + target.apply_status_effect(/datum/status_effect/dream_protection/deceased) + adjust_favor(10 * (target.mind ? 1 : 0.5), chap) + LAZYADD(recent_bless_refs, tarref) + addtimer(CALLBACK(src, PROC_REF(clear_bless_ref), tarref), 6 MINUTES) + return BLESSING_SUCCESS + +/datum/religion_sect/dreams/proc/clear_bless_ref(tarref) + LAZYREMOVE(recent_bless_refs, tarref) + +/datum/religion_sect/dreams/vv_edit_var(var_name, var_value) + . = ..() + if(var_name == NAMEOF(src, dream_protection)) + for(var/mob/living/chap as anything in GLOB.mob_living_list) + if(chap.mind?.holy_role) + if(var_value) + chap.apply_status_effect(/datum/status_effect/dream_protection) + else + chap.remove_status_effect(/datum/status_effect/dream_protection) diff --git a/code/modules/religion/religion_structures.dm b/code/modules/religion/religion_structures.dm index c57269fa061..15973442a41 100644 --- a/code/modules/religion/religion_structures.dm +++ b/code/modules/religion/religion_structures.dm @@ -11,6 +11,8 @@ buckle_lying = 90 //we turn to you! /// Do we have lit candles? var/lit_candles = TRUE + /// Optional emissive overlay + var/emissive_icon_state /obj/structure/altar/Initialize(mapload) . = ..() @@ -21,7 +23,10 @@ /obj/structure/altar/update_overlays() . = ..() if (lit_candles) - . += "convertaltarcandle" + . += mutable_appearance(icon, "convertaltarcandle", alpha = src.alpha) + . += emissive_appearance(icon, "convertaltarcandle", src, alpha = src.alpha) + if(emissive_icon_state) + . += emissive_appearance(icon, emissive_icon_state, src, alpha = src.alpha) /obj/structure/altar/attack_hand(mob/living/user, list/modifiers) if(!Adjacent(user) || !user.pulling) @@ -75,13 +80,16 @@ lit_candles = FALSE icon = initial(icon) icon_state = initial(icon_state) + emissive_icon_state = initial(emissive_icon_state) else - lit_candles = TRUE sect_to_altar = GLOB.religious_sect + lit_candles = GLOB.religious_sect.candle_overlay if(sect_to_altar.altar_icon) icon = sect_to_altar.altar_icon if(sect_to_altar.altar_icon_state) icon_state = sect_to_altar.altar_icon_state + if(sect_to_altar.altar_emissive_icon_state) + emissive_icon_state = sect_to_altar.altar_emissive_icon_state update_appearance(UPDATE_OVERLAYS) //Light the candles! /obj/structure/altar/of_gods/proc/get_chaplains() diff --git a/code/modules/religion/rites.dm b/code/modules/religion/rites.dm index dd1e71b2cca..e6d7369ee62 100644 --- a/code/modules/religion/rites.dm +++ b/code/modules/religion/rites.dm @@ -72,6 +72,9 @@ return GLOB.religious_sect.rites_list.Remove(src.type) +/datum/religion_rites/proc/refund(percent = 1.0) + GLOB.religious_sect.adjust_favor(favor_cost * percent) + /**** Mechanical God ****/ /datum/religion_rites/synthconversion @@ -241,7 +244,7 @@ return FALSE //uses HAS_TRAIT_FROM because junkies are also hopelessly addicted if(HAS_TRAIT_FROM(user, TRAIT_HOPELESSLY_ADDICTED, "maint_adaptation")) - to_chat(user, span_warning("You've already adapted.")) + to_chat(user, span_warning("You've already adapted.")) return FALSE return ..() diff --git a/code/modules/requests/request_manager.dm b/code/modules/requests/request_manager.dm index d2257515f8f..77051641e50 100644 --- a/code/modules/requests/request_manager.dm +++ b/code/modules/requests/request_manager.dm @@ -270,7 +270,7 @@ GLOBAL_DATUM_INIT(requests, /datum/request_manager, new) "message" = request.message, "additional_info" = request.additional_information, "timestamp" = request.timestamp, - "timestamp_str" = gameTimestamp(wtime = request.timestamp) + "timestamp_str" = round_timestamp(wtime = request.timestamp) )) data["fax_autoprinting"] = GLOB.fax_autoprinting return data diff --git a/code/modules/research/anomaly/anomaly_core.dm b/code/modules/research/anomaly/anomaly_core.dm index d9d15931c0f..54339a7aacf 100644 --- a/code/modules/research/anomaly/anomaly_core.dm +++ b/code/modules/research/anomaly/anomaly_core.dm @@ -206,7 +206,7 @@ if(!length(possible_targets)) return var/turf/target = pick(possible_targets) - new /obj/effect/temp_visual/telegraphing/thunderbolt(target) + new /obj/effect/temp_visual/telegraphing/circle(target) addtimer(CALLBACK(src, PROC_REF(strike), target), 1 SECONDS) /obj/item/assembly/signaler/anomaly/weather/proc/strike(turf/target) diff --git a/code/modules/research/designs/autolathe/service_designs.dm b/code/modules/research/designs/autolathe/service_designs.dm index 3d6720ec469..784cc5688b8 100644 --- a/code/modules/research/designs/autolathe/service_designs.dm +++ b/code/modules/research/designs/autolathe/service_designs.dm @@ -10,6 +10,18 @@ ) departmental_flags = DEPARTMENT_BITFLAG_SERVICE +/datum/design/wet_floor_sign + name = "Wet Floor Sign" + id = "wet_floor_sign" + build_type = AUTOLATHE | PROTOLATHE | AWAY_LATHE + materials = list(/datum/material/plastic =SMALL_MATERIAL_AMOUNT) + build_path = /obj/item/clothing/suit/caution + category = list( + RND_CATEGORY_INITIAL, + RND_CATEGORY_TOOLS + RND_SUBCATEGORY_TOOLS_JANITORIAL, + ) + departmental_flags = DEPARTMENT_BITFLAG_SERVICE + /datum/design/watering_can name = "Watering Can" id = "watering_can" diff --git a/code/modules/research/designs/electronics_designs.dm b/code/modules/research/designs/electronics_designs.dm index b1da9f2c1c0..9e5e225865e 100644 --- a/code/modules/research/designs/electronics_designs.dm +++ b/code/modules/research/designs/electronics_designs.dm @@ -65,3 +65,16 @@ RND_CATEGORY_EQUIPMENT + RND_SUBCATEGORY_EQUIPMENT_SCIENCE ) departmental_flags = DEPARTMENT_BITFLAG_SCIENCE + +/datum/design/manipulator_task_disk + name = "Manipulator Task Disk" + desc = "Produce additional disks for storing manipulator tasks." + id = "manipulator_task_disk" + build_type = AUTOLATHE + materials = list(/datum/material/iron =SMALL_MATERIAL_AMOUNT * 3, /datum/material/glass =SMALL_MATERIAL_AMOUNT) + build_path = /obj/item/disk/manipulator + category = list( + RND_CATEGORY_INITIAL, + RND_CATEGORY_EQUIPMENT + RND_SUBCATEGORY_EQUIPMENT_SCIENCE + ) + departmental_flags = DEPARTMENT_BITFLAG_SCIENCE diff --git a/code/modules/research/designs/mining_designs.dm b/code/modules/research/designs/mining_designs.dm index c2570e56eff..ff40afbc56e 100644 --- a/code/modules/research/designs/mining_designs.dm +++ b/code/modules/research/designs/mining_designs.dm @@ -226,7 +226,7 @@ /datum/material/gold =SHEET_MATERIAL_AMOUNT, /datum/material/diamond =SHEET_MATERIAL_AMOUNT, ) - build_path = /obj/item/borg/upgrade/modkit/aoe/turfs + build_path = /obj/item/borg/upgrade/modkit/cooldown/aoe/turfs category = list( RND_CATEGORY_TOOLS + RND_SUBCATEGORY_TOOLS_PKA_MODS ) @@ -267,7 +267,7 @@ desc = "A device which causes kinetic accelerators to fire AoE blasts that destroy rock and damage creatures." id = "hyperaoemod" materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT*3.5, /datum/material/glass = SHEET_MATERIAL_AMOUNT*1.5, /datum/material/silver =SHEET_MATERIAL_AMOUNT*1.5, /datum/material/gold =SHEET_MATERIAL_AMOUNT*1.5, /datum/material/diamond = SHEET_MATERIAL_AMOUNT*2) - build_path = /obj/item/borg/upgrade/modkit/aoe/mobs/andturfs + build_path = /obj/item/borg/upgrade/modkit/cooldown/aoe/mobs/andturfs /datum/design/unique_modkit/rapid_repeater name = "Kinetic Accelerator Rapid Repeater Mod" diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm index 5de2fc98a01..9c9d8b0ae7d 100644 --- a/code/modules/research/designs/weapon_designs.dm +++ b/code/modules/research/designs/weapon_designs.dm @@ -669,7 +669,7 @@ id = "liberator_gun" build_type = AUTOLATHE materials = list(/datum/material/plastic = SHEET_MATERIAL_AMOUNT * 2, /datum/material/iron = SMALL_MATERIAL_AMOUNT * 15) - build_path = /obj/item/gun/ballistic/automatic/pistol/doorhickey + build_path = /obj/item/gun/ballistic/automatic/pistol/doohickey category = list(RND_CATEGORY_IMPORTED) /datum/design/stun_boomerang diff --git a/code/modules/research/destructive_analyzer.dm b/code/modules/research/destructive_analyzer.dm index 0c958e557be..4c08911af2e 100644 --- a/code/modules/research/destructive_analyzer.dm +++ b/code/modules/research/destructive_analyzer.dm @@ -14,6 +14,10 @@ base_icon_state = "d_analyzer" circuit = /obj/item/circuitboard/machine/destructive_analyzer +/obj/machinery/rnd/destructive_analyzer/Initialize(mapload) + . = ..() + AddElement(/datum/element/tool_blocker, TOOL_SCREWDRIVER, TOOL_ACT_PRIMARY) //This allows people to put syndicate screwdrivers in the machine. Secondary act still passes. + /obj/machinery/rnd/destructive_analyzer/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) . = ..() @@ -127,10 +131,6 @@ return ITEM_INTERACT_SKIP_TO_ATTACK return NONE -//This allows people to put syndicate screwdrivers in the machine. Secondary act still passes. -/obj/machinery/rnd/destructive_analyzer/screwdriver_act(mob/living/user, obj/item/tool) - return NONE - //We need to call default_deconstruction_screwdriver here since its parent will call screwdriver_act on this level which will stop us from ever deconstructing. /obj/machinery/rnd/destructive_analyzer/screwdriver_act_secondary(mob/living/user, obj/item/tool) return default_deconstruction_screwdriver(user, tool) diff --git a/code/modules/research/gizmo/gizmo_controller.dm b/code/modules/research/gizmo/gizmo_controller.dm new file mode 100644 index 00000000000..90b5f7bef87 --- /dev/null +++ b/code/modules/research/gizmo/gizmo_controller.dm @@ -0,0 +1,42 @@ +/// The master datum that handles every bit of gizmo code +/// Just so you will understand the full insanity of this: +/// object > gizmo_controller > gizmo_puzzle + gizmo_interface > gizmode > gizpulse > callbacks +/datum/gizmo_controller + /// Can hold different interacting modes (wires, voice) and connected interfaces + var/list/interfaces = list(GIZMO_INTERFACE_WIRES = /datum/gizmo_interface) + /// Instanted interfaces. really just here so I can check this shit in vv + var/list/instances = list() + +/// Generate interfaces for interacting with the gizmo +/datum/gizmo_controller/proc/generate_interfaces(atom/movable/holder) + for(var/interface_define, interface_type in interfaces) + + var/list/callbacks = list() + var/datum/gizmo_interface/interface_instance = new interface_type (src) + interface_instance.generate_interface(holder, callbacks) + instances += interface_instance + + switch(interface_define) + if(GIZMO_INTERFACE_WIRES) + holder.set_wires(new /datum/wires/gizmo(holder, interface_instance.puzzle)) + if(GIZMO_INTERFACE_VOICE) + holder.AddComponent(/datum/component/gizmo_voice, interface_instance.puzzle) + +/// Wired with an interface that moves +/datum/gizmo_controller/beyblade + interfaces = list(GIZMO_INTERFACE_WIRES = /datum/gizmo_interface/beyblade) + +/// Wired with an interface that toggles the icon_state and/or glows +/datum/gizmo_controller/toggle + interfaces = list(GIZMO_INTERFACE_WIRES = /datum/gizmo_interface/toggle) + +/// Voice controller with a voice puzzle and interface. Comes with a wire interface that gives you the hint to use the voice interface +/datum/gizmo_controller/voice + interfaces = list(GIZMO_INTERFACE_WIRES = /datum/gizmo_interface/voice_unlock, GIZMO_INTERFACE_VOICE = /datum/gizmo_interface/voice) + +/// For held gizmo's +/datum/gizmo_controller/item + +/// Always horrible agony! +/datum/gizmo_controller/cursed + interfaces = list(GIZMO_INTERFACE_WIRES = /datum/gizmo_interface/cursed) diff --git a/code/modules/research/gizmo/gizmo_interface.dm b/code/modules/research/gizmo/gizmo_interface.dm new file mode 100644 index 00000000000..7e46a47fcc6 --- /dev/null +++ b/code/modules/research/gizmo/gizmo_interface.dm @@ -0,0 +1,69 @@ +/// Essentially a small wrapper that holds the puzzle datum and connects it with the operating modes of the machine +/datum/gizmo_interface + /// The gizmo master ultra mega controller + var/datum/gizmo_controller/controller + /// The puzzle that connects the interface to the activation callbacks and checks if you pulsed the right sequences + var/datum/gizmo_puzzle/puzzle = /datum/gizmo_puzzle + + /// List (or list define) for the gizmodes to pick + var/list/possible_active_modes = GIZMO_COMMON_MODES + /// Guaranteed active pulses + var/list/guaranteed_active_gizmodes = list() + /// The gizmode instances + var/list/active_gizmodes = list() + + /// Min modes to select from possible_active_modes + var/min_modes = 1 + /// Max modes to select from possible_active_modes + var/max_modes = 2 + +/datum/gizmo_interface/New(datum/gizmo_controller/controller) + . = ..() + + src.controller = controller + +/// Instantiate the active modes, tell them to instantiate and pass their callbacks to the puzzle maker +/datum/gizmo_interface/proc/generate_interface(atom/movable/holder, datum/callback/pulse_callback) + var/list/trigger_callbacks = list() + var/list/modes_to_spawn = list() + guaranteed_active_gizmodes + + for(var/i in 1 to rand(min_modes, max_modes)) + var/path = pick_weight_take(possible_active_modes) + if(!path) + break + modes_to_spawn += path + + for(var/path in modes_to_spawn) + var/datum/gizmodes/mode = new path () + mode.generate_modes(trigger_callbacks, src) + active_gizmodes += mode + + puzzle = new puzzle () + puzzle.generate_code_sequences(trigger_callbacks) + +/// Moves around. Guaranteed to have a mode that controles the movement +/datum/gizmo_interface/beyblade + guaranteed_active_gizmodes = list(/datum/gizmodes/mover) + min_modes = 0 + max_modes = 1 + +/// Guaranteed to have a lights mode +/datum/gizmo_interface/toggle + guaranteed_active_gizmodes = list(/datum/gizmodes/lights) + +/// Guaranteed to have a mode that will give a voice components secret keywords. Assumes there's a voice interface added by the gizmo_controller +/datum/gizmo_interface/voice_unlock + guaranteed_active_gizmodes = list(/datum/gizmodes/voice) + min_modes = 0 + max_modes = 0 + +/// For the actual voice operated puzzle. Is a bit more forgiving +/datum/gizmo_interface/voice + puzzle = /datum/gizmo_puzzle/voice + +/// Always bad! +/datum/gizmo_interface/cursed + possible_active_modes = list( + /datum/gizmodes/bad = 1, + ) + max_modes = 1 diff --git a/code/modules/research/gizmo/gizmo_items.dm b/code/modules/research/gizmo/gizmo_items.dm new file mode 100644 index 00000000000..bc6d237681a --- /dev/null +++ b/code/modules/research/gizmo/gizmo_items.dm @@ -0,0 +1,22 @@ +/// A handheld gizmo, with some different activation modes +/obj/item/gizmo + name = "gizmo" + desc = "Fliggoes the giggoe when its oven in hot the device." + icon = 'icons/obj/science/gizmos.dmi' + + resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF + + /// Possible icon states + var/list/icon_states = list("gizmo_item_1") + /// Reference to the gizmo master controller that handles all the other gizmo stuff + var/datum/gizmo_controller/controller = /datum/gizmo_controller/item + +/obj/item/gizmo/Initialize(mapload) + . = ..() + + if(icon_states) + base_icon_state = pick(icon_states) + icon_state = base_icon_state + + controller = new controller(src) + controller.generate_interfaces(src) diff --git a/code/modules/research/gizmo/gizmo_machines.dm b/code/modules/research/gizmo/gizmo_machines.dm new file mode 100644 index 00000000000..3d50d797d5d --- /dev/null +++ b/code/modules/research/gizmo/gizmo_machines.dm @@ -0,0 +1,136 @@ +/// Science object that behaves similairly to to strange objects/relics, but is activated by cracking wire sequences and other functions +/obj/machinery/gizmo + name = "gizmo" + desc = "Does a function when you put the jigger at the other ends thing." + icon_state = "gizmo_1" + icon = 'icons/obj/science/gizmos.dmi' + + resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF + + panel_open = TRUE + density = TRUE + anchored = FALSE + + /// Possible icon states to pick from + var/list/icon_states = list("gizmo_0", "gizmo_1", "gizmo_2", "gizmo_3", "gizmo_4") + /// Reference to the gizmo. We dont actually need to track this for anything but ease of vv + var/datum/gizmo_controller/controller = /datum/gizmo_controller + /// Possible names to pick from to keep things confusing + var/list/possible_names = list( + "gizmo", "jigger", "doohickey", "particle inverter", "polarity superplexer", "flitcher poster", "natty gonk", "quantum quantum", + "entropy nilum", "tachyon streamer", "doing device", "task operator", "interface responder", "kinetic observer", "turbo encabulator", + "statistic responder", "possibility matrix", "toety aaier", "phase anchor", + ) + +/obj/machinery/gizmo/Initialize(mapload) + . = ..() + + name = pick(possible_names) + + if(icon_states) + base_icon_state = pick(icon_states) + icon_state = base_icon_state + + controller = new controller(src) + controller.generate_interfaces(src) + + RegisterSignal(src, COMSIG_GIZMO_START_MOVING, PROC_REF(start_moving)) + RegisterSignal(src, COMSIG_GIZMO_STOP_MOVING, PROC_REF(stop_moving)) + +/obj/machinery/gizmo/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + add_fingerprint(user) + + if(is_wire_tool(tool)) + attempt_wire_interaction(user) + return ITEM_INTERACT_SUCCESS + return NONE + +/obj/machinery/gizmo/wrench_act(mob/living/user, obj/item/tool) + . = ITEM_INTERACT_BLOCKING + if(default_unfasten_wrench(user, tool) == SUCCESSFUL_UNFASTEN) + return ITEM_INTERACT_SUCCESS + +/obj/machinery/gizmo/proc/start_moving(datum/source, datum/gizpulse/pulse) + SIGNAL_HANDLER + + on_start_moving(pulse) + +/obj/machinery/gizmo/proc/stop_moving(datum/source, datum/gizpulse/pulse) + SIGNAL_HANDLER + + on_stop_moving(pulse) + +/obj/machinery/gizmo/proc/on_start_moving(datum/gizpulse/pulse) + return + +/obj/machinery/gizmo/proc/on_stop_moving(datum/gizpulse/pulse) + return + +/// Gizmo that comes with a gizmo interface to start moving +/obj/machinery/gizmo/beyblade + icon_states = list("beyblade") + + controller = /datum/gizmo_controller/beyblade + + /// Are we currently moving? + var/moving = FALSE + +/obj/machinery/gizmo/beyblade/update_icon(updates) + . = ..() + + icon_state = base_icon_state + (moving ? "_spinning" : "") + +/obj/machinery/gizmo/beyblade/on_start_moving(datum/gizpulse/pulse) + density = TRUE + + moving = TRUE + update_appearance(UPDATE_ICON) + +/obj/machinery/gizmo/beyblade/on_stop_moving(datum/gizpulse/pulse) + density = FALSE + + moving = FALSE + update_appearance(UPDATE_ICON) + +/// A gizmo with some sort of "on" state. Really only for visuals +/obj/machinery/gizmo/toggle + controller = /datum/gizmo_controller/toggle + + icon_states = list("gizmo_active_0", "gizmo_active_1", "gizmo_active_2", "gizmo_active_3", "gizmo_active_4", "gizmo_active_5") + + var/on_state = FALSE + +/obj/machinery/gizmo/toggle/Initialize(mapload) + . = ..() + + RegisterSignal(src, COMSIG_GIZMO_ON_STATE, PROC_REF(on_state)) + RegisterSignal(src, COMSIG_GIZMO_OFF_STATE, PROC_REF(off_state)) + +/obj/machinery/gizmo/toggle/update_icon(updates) + . = ..() + + icon_state = base_icon_state + (on_state ? "_on" : "") + +/obj/machinery/gizmo/toggle/tucker_tubes + icon_states = list("gizmo_active_0") + icon_state = "gizmo_active_0" //for the mapping icon + anchored = TRUE + +/obj/machinery/gizmo/toggle/proc/on_state(datum/source) + SIGNAL_HANDLER + + on_state = TRUE + update_icon() + +/obj/machinery/gizmo/toggle/proc/off_state(datum/source) + SIGNAL_HANDLER + + on_state = FALSE + update_icon() + +/// A gizmo with a voice activated interface +/obj/machinery/gizmo/voice + controller = /datum/gizmo_controller/voice + +/obj/machinery/gizmo/cursed + controller = /datum/gizmo_controller/cursed diff --git a/code/modules/research/gizmo/gizmo_spawner.dm b/code/modules/research/gizmo/gizmo_spawner.dm new file mode 100644 index 00000000000..c7c33ff68a3 --- /dev/null +++ b/code/modules/research/gizmo/gizmo_spawner.dm @@ -0,0 +1,9 @@ +/obj/effect/spawner/random/gizmo + name = "gizmo spawner" + icon_state = "gizmo" + loot = list( + /obj/machinery/gizmo = 6, + /obj/machinery/gizmo/toggle = 4, + /obj/machinery/gizmo/voice = 2, + /obj/machinery/gizmo/beyblade = 1, + ) diff --git a/code/modules/research/gizmo/gizmo_voice.dm b/code/modules/research/gizmo/gizmo_voice.dm new file mode 100644 index 00000000000..0c69e44074a --- /dev/null +++ b/code/modules/research/gizmo/gizmo_voice.dm @@ -0,0 +1,62 @@ +/// The words (or tones really) the gizmo voice interface can listen for. Limit to 2 characters (or it breaks because im cringe) +GLOBAL_LIST_INIT(gizmo_words, world.file2list("strings/gizmo_words.txt")) + +/// Listen to the tones and send the sequence to the puzzle datum +/datum/component/gizmo_voice + var/datum/gizmo_puzzle/puzzle + /// they're not really words but you get it + var/static/list/active_words = list() + +/datum/component/gizmo_voice/Initialize(datum/gizmo_puzzle/puzzle) + if(!ismovable(parent)) + return COMPONENT_INCOMPATIBLE + + var/atom/movable/movable = parent + movable.become_hearing_sensitive(type) + RegisterSignal(movable, COMSIG_MOVABLE_HEAR, PROC_REF(on_hear)) + + src.puzzle = puzzle + + if(!active_words.len) + generate_active_words() + +/// Pick the activate keywords +/datum/component/gizmo_voice/proc/generate_active_words() + var/list/possible_words = GLOB.gizmo_words.Copy() + for(var/i in 1 to puzzle.cryptic_pulse.len) + active_words += pick_n_take(possible_words) + +/// Listen to a message, and pick out the puzzle words +/datum/component/gizmo_voice/proc/on_hear(datum/source, list/hearing_args) + SIGNAL_HANDLER + + if(hearing_args[HEARING_SPEAKER] == parent) + return + + var/haystack = hearing_args[HEARING_RAW_MESSAGE] + var/list/text_position_index = list() + + for(var/needle in active_words) + var/position = 1 + // we can have multiple of the same keyword in one sequence + for(var/i in 1 to puzzle.code_length) + position = findtext(haystack, needle, position) + + if(!position) + break + + /// needle + position because assocs need to be unique, we splice it away later when sending it + text_position_index[needle + "[position]"] = position + // So for the next loop we dont find the exact same word again + position++ + + if(!text_position_index.len) + return + + text_position_index = sortTim(text_position_index, associative = TRUE) + for(var/thing, position in text_position_index) + // Only send feedback for the last speech packet + var/no_feedback = text_position_index.Find(thing) != text_position_index.len + // When solved, accept no further packets from this + if(puzzle.on_pulse(active_words.Find(copytext(thing, 1, 3)), hearing_args[HEARING_SPEAKER], parent, no_feedback = no_feedback) == GIZMO_PUZZLE_SOLVED) + return diff --git a/code/modules/research/gizmo/gizmo_wires.dm b/code/modules/research/gizmo/gizmo_wires.dm new file mode 100644 index 00000000000..01ce0c5eb3b --- /dev/null +++ b/code/modules/research/gizmo/gizmo_wires.dm @@ -0,0 +1,30 @@ +/// Wires that send pulses to a gizmo puzzle datum +/datum/wires/gizmo + /// It's already randomized on the puzzle component + randomize = FALSE + + /// Might as well keep it broad, it's all signals anyway + holder_type = /obj + + /// The wires we need to pulse for cracking the code + var/list/cryptic_wires = list( + CRYPTIC_WIRE_1, + CRYPTIC_WIRE_2, + CRYPTIC_WIRE_3, + CRYPTIC_WIRE_4, + CRYPTIC_WIRE_5, + CRYPTIC_WIRE_6, + CRYPTIC_WIRE_7, + CRYPTIC_WIRE_8, + ) + + var/datum/gizmo_puzzle/puzzle + +/datum/wires/gizmo/New(atom/holder, datum/gizmo_puzzle/puzzle) + wires = cryptic_wires + src.puzzle = puzzle + + ..() + +/datum/wires/gizmo/on_pulse(wire, mob/living/user) + puzzle.on_pulse(cryptic_wires.Find(wire), user, holder) diff --git a/code/modules/research/gizmo/gizmodes/giz_filler.dm b/code/modules/research/gizmo/gizmodes/giz_filler.dm new file mode 100644 index 00000000000..15adbc58023 --- /dev/null +++ b/code/modules/research/gizmo/gizmodes/giz_filler.dm @@ -0,0 +1,101 @@ +/// Shake around some, make some oil or just fly away +/datum/gizmodes/sputter + possible_active_modes = list( + /datum/gizpulse/sputter = 1, + /datum/gizpulse/throw_self = 1, + ) + + min_modes = 2 + cooldown_time = 5 SECONDS + +/// Shake around some and spill oil +/datum/gizpulse/sputter + /// Range in which we can oilerize + var/oil_range = 3 + /// Chance for a tile to get oiled + var/oil_chance = 8 + +/datum/gizpulse/sputter/activate(atom/movable/holder, datum/gizmodes/master, datum/gizmo_interface/interface) + playsound(holder, 'sound/effects/splat.ogg', 30) + for(var/turf/open/tile in oview(oil_range, holder)) + if(prob(oil_chance)) + new /obj/effect/decal/cleanable/blood/oil(tile) + + holder.Shake() + +/datum/gizpulse/throw_self/activate(atom/movable/holder, datum/gizmodes/master, datum/gizmo_interface/interface) + holder.throw_at(get_edge_target_turf(holder, pick(GLOB.alldirs)), 50, 1) + +/// Spawn some item +/datum/gizmodes/dispenser + possible_active_modes = list( + /datum/gizpulse/dispense = 1, + /datum/gizpulse/dispense = 1, + /datum/gizpulse/dispense = 1, + /datum/gizpulse/dispense = 1, + /datum/gizpulse/dispense = 1, + /datum/gizpulse/dispense = 1, + ) + min_modes = 4 + max_modes = 6 + +/datum/gizpulse/dispense + /// Weighted list of objects we could spawn + var/list/possible_objects = list( + /obj/item/crowbar = 1, + /obj/item/wrench = 1, + /obj/item/screwdriver = 1, + /obj/item/multitool = 1, + /obj/item/wirecutters = 1, + /obj/item/weldingtool = 1, + ) + /// Typepath of object to spawn + var/object_to_spawn + + /// List of softrefs of the objects we spawned. Exists only to prevent game-crashing object spam + var/list/spawned_objects_weakrefs = list() + /// Max objects that can exist at once + var/max_objects = 50 + /// The position of the next object to spawn in spawned_objects_weakrefs + var/next_object_position = 0 + +/datum/gizpulse/dispense/activate(atom/movable/holder, datum/gizmodes/master, datum/gizmo_interface/interface) + if(!object_to_spawn) + object_to_spawn = pick_weight(possible_objects) + + // We don't technically track to make sure we dont make more than [max_objects] objects, we just delete whatever was made [max_objects] ago + if(spawned_objects_weakrefs.len > (next_object_position % max_objects)) + qdel(spawned_objects_weakrefs["[(next_object_position % max_objects) + 1]"]) + + var/new_object = new object_to_spawn (get_turf(holder)) + modify(new_object) + spawned_objects_weakrefs["[(next_object_position % max_objects) + 1]"] = WEAKREF(new_object) + next_object_position++ + +/datum/gizpulse/dispense/proc/modify(atom/movable/new_object) + return + +/// Spawn fake goop food +/datum/gizmodes/dispenser/food + possible_active_modes = list( + /datum/gizpulse/dispense/food = 1, + ) + + mode_pulses = list( + /datum/gizpulse/mode_controle/direct_activate, + ) + + min_modes = 1 + max_modes = 1 + +/// Food made with goop +/datum/gizpulse/dispense/food + possible_objects = list( + /obj/item/food/donut/plain = 1, + /obj/item/food/burger = 1, + ) + +/datum/gizpulse/dispense/food/modify(atom/movable/new_object) + new_object.reagents.clear_reagents() + // its goop all the way down + new_object.reagents.add_reagent(/datum/reagent/consumable/gizmo_goop, 5) diff --git a/code/modules/research/gizmo/gizmodes/gizactives.dm b/code/modules/research/gizmo/gizmodes/gizactives.dm new file mode 100644 index 00000000000..632ce7815f4 --- /dev/null +++ b/code/modules/research/gizmo/gizmodes/gizactives.dm @@ -0,0 +1,124 @@ +/// You can imagine a /datum/gizmodes as remote and a TV +/// The mode_controles is the remote. Maybe there's 9 buttons for 1-9, and pressing the buttons just goes to that channel! +/// Maybe there's 10 buttons, 1-9 for selecting a channel and an extra for going to the selected channel +/// Or maybe there's two buttons, one that cycles to the next number and one that then goes to that channel] +/// The giz_pulse is essentually the TV. Generally the functioning of the TV is themed, happy image :) or sad image :( +/datum/gizmodes + /// Our paarent gizmo interface + var/datum/gizmo_interface/interface + /// The currently selected gizpulse + var/datum/gizpulse/current_active + + /// Instantiated active operating modes/gizpulses + var/list/active_gizmodes = list() + /// Guaranted operating modes/gizpulses types. use GIZMO_PICK_ONE with an associated list for more bespoke guaranteed picking + var/list/guaranteed_active_gizmodes = list() + + /// Random gizpulses we can have. PICKWEIGHTED SO GIVE IT A VALUE (/datum/gizpulse/milk_person = 1) + var/list/possible_active_modes = list() + /// Min modes from possible_active_modes + var/min_modes = 1 + /// Max modes from possible_active_modes + var/max_modes = 2 + + /// Mode controles add signals that decide how gizpulses are activated + /// Such as cycle to the next gizpulse, directly activate a gizpulse, or select a specific gizpulse + /// Select mode, for example, adds a callback for every gizpulse + 1 for activating that + /// Cycle mode activate adds only one callback, which cycles to the next one and then activates it + var/list/mode_pulses = list( + /datum/gizpulse/mode_controle/select_mode, + /datum/gizpulse/mode_controle/cycle_mode, + /datum/gizpulse/mode_controle/direct_activate, + /datum/gizpulse/mode_controle/cycle_mode/activate, + ) + /// The selected mode controle + var/datum/gizpulse/mode_controle/mode_pulse + /// Time between pulses + var/cooldown_time = 1 SECONDS + COOLDOWN_DECLARE(cooldown_timer) + +/// Pick the paths to generate and instantiate them +/datum/gizmodes/proc/generate_modes(list/trigger_callbacks, datum/gizmo_interface/interface) + src.interface = interface + + var/list/modes_to_spawn = list() + + for(var/path in guaranteed_active_gizmodes) + if(path == GIZMO_PICK_ONE) + var/list/nested_list = guaranteed_active_gizmodes[path] + modes_to_spawn += pick_weight(nested_list) + else + modes_to_spawn += path + + for(var/i in 1 to rand(min_modes, max_modes)) + var/path = pick_weight_take(possible_active_modes) + if(!path) + break + modes_to_spawn += path + + for(var/path in modes_to_spawn) + active_gizmodes += new path () + + current_active = pick(active_gizmodes) + + var/mode_path = pick(mode_pulses) + mode_pulse = new mode_path() + mode_pulse.setup_mode_controle(src, active_gizmodes, trigger_callbacks) + +/// Activate this gizmode which in turn activates the active gizpulse (you following me here?) +/datum/gizmodes/proc/activate(atom/movable/holder) + if(current_active.affect_timer) + if(!COOLDOWN_FINISHED(src, cooldown_timer)) + return + + COOLDOWN_START(src, cooldown_timer, cooldown_time) + current_active.activate(holder, src, interface) + +/// Holds some functionaly that is activated and selected by the /gizmodes +/datum/gizpulse + /// If TRUE, put the gizmode into cooldown + var/affect_timer = TRUE + +/// Activate it do so stuff +/datum/gizpulse/proc/activate(atom/movable/holder, datum/gizmodes/master, datum/gizmo_interface/interface) + return + +/// Changes the currently activate gizpulse and adds a way to activate gizpulses +/datum/gizpulse/mode_controle + affect_timer = FALSE + +/// Select how activating the pulzes interacts with the gizpulses +/datum/gizpulse/mode_controle/proc/setup_mode_controle(datum/gizmodes/master, list/active_gizmodes, list/trigger_callbacks) + return + +/// Adds a puzzle for every possible made to select it, and a single wire to activate the selected mode +/datum/gizpulse/mode_controle/select_mode/setup_mode_controle(datum/gizmodes/master, list/active_gizmodes, list/trigger_callbacks) + for(var/active in active_gizmodes) + trigger_callbacks += VARSET_CALLBACK(master, current_active, active) + trigger_callbacks += CALLBACK(master, PROC_REF(activate)) + +/// Adds a puzzle to cycle to the next gizpulse, and a puzzle to activate the currently active mode +/datum/gizpulse/mode_controle/cycle_mode/setup_mode_controle(datum/gizmodes/master, list/active_gizmodes, list/trigger_callbacks) + trigger_callbacks += CALLBACK(src, PROC_REF(cycle_mode), master) + trigger_callbacks += CALLBACK(master, PROC_REF(activate)) + +/datum/gizpulse/mode_controle/cycle_mode/proc/cycle_mode(datum/gizmodes/master, atom/movable/holder) + // Move to the next mode in the list (and loop back to 1 if needed) + master.current_active = master.active_gizmodes[((master.active_gizmodes.Find(master.current_active)) % (master.active_gizmodes.len)) + 1] + +/// Adds a puzzle for every gizpulse that just immediately activates that gizpulse +/datum/gizpulse/mode_controle/direct_activate/setup_mode_controle(datum/gizmodes/master, list/active_gizmodes, list/trigger_callbacks) + for(var/active in active_gizmodes) + trigger_callbacks += CALLBACK(src, PROC_REF(switch_and_activate), master, active) + +/datum/gizpulse/mode_controle/direct_activate/proc/switch_and_activate(datum/gizmodes/master, datum/gizpulse/active, atom/movable/holder) + master.current_active = active + master.activate(holder) + +/// Adds a single wire, that cycles and then activates +/datum/gizpulse/mode_controle/cycle_mode/activate/setup_mode_controle(datum/gizmodes/master, list/active_gizmodes, list/trigger_callbacks) + trigger_callbacks += CALLBACK(src, PROC_REF(cycle_mode), master) + +/datum/gizpulse/mode_controle/cycle_mode/activate/cycle_mode(datum/gizmodes/master, atom/movable/holder) + ..() + master.activate(holder) diff --git a/code/modules/research/gizmo/gizmodes/gizbad.dm b/code/modules/research/gizmo/gizmodes/gizbad.dm new file mode 100644 index 00000000000..07fb2b5c66a --- /dev/null +++ b/code/modules/research/gizmo/gizmodes/gizbad.dm @@ -0,0 +1,131 @@ +/// A bunch of bad effects that can maim or kill you (for science!!!) +/datum/gizmodes/bad + possible_active_modes = list( + /datum/gizpulse/explode = 1, + /datum/gizpulse/explode/fire = 1, + /datum/gizpulse/dispense/robot_spider = 1, + /datum/gizpulse/thrower = 1, + /datum/gizpulse/thrower/grenade = 1, + /datum/gizpulse/radiation_pulse = 1, + /datum/gizpulse/bone_breaker = 1, + ) + + guaranteed_active_gizmodes = list( + /datum/gizpulse/ominous, //it may warn you, it may immediately explode. Who knows! + ) + + min_modes = 1 + max_modes = 2 + + cooldown_time = 5 SECONDS + +/datum/gizpulse/explode + var/range_heavy = 0 + var/range_medium = 1 + var/range_light = 3 + var/range_flame = 0 + +/datum/gizpulse/explode/activate(atom/movable/holder, datum/gizmodes/master, datum/gizmo_interface/interface) + explosion(holder, range_heavy, range_medium, range_light, range_flame) + +/datum/gizpulse/explode/fire + range_flame = 5 + +/datum/gizpulse/dispense/robot_spider + possible_objects = list( + /mob/living/basic/spider/robot = 1, + ) + +/mob/living/basic/spider/robot + name = "robot spider" + desc = "Beep boop, the robot spider said." + icon_state = "robot" + mob_biotypes = MOB_ROBOTIC|MOB_BUG + + speed = 5 + maxHealth = 50 + health = 50 + obj_damage = 10 + melee_damage_lower = 10 + melee_damage_upper = 15 + + ai_controller = /datum/ai_controller/basic_controller/giant_spider + +/mob/living/basic/spider/robot/death(gibbed) + . = ..() + + explosion(src, 0, 0, 2) + if(prob(80)) + qdel(src) + +/mob/living/basic/spider/robot/emp_act(severity) + . = ..() + + death() //very sensitive spider robot antennae makes it die fast to emp + +/datum/gizpulse/thrower + /// Weighted list of items we can throw + var/list/throwables = list( + /obj/item/knife/kitchen = 1, + /obj/item/shard = 1, + + ) + /// Path of item to throw + var/throwing_path + +/datum/gizpulse/thrower/New() + . = ..() + throwing_path = pick_weight(throwables) + +/datum/gizpulse/thrower/activate(atom/movable/holder, datum/gizmodes/master, datum/gizmo_interface/interface) + var/obj/item/item = new throwing_path (get_turf(holder)) + + var/list/targets = list() + for(var/mob/living/victims in oview(5, holder)) + targets += victims + + if(!targets.len) + targets += get_edge_target_turf(holder, GLOB.alldirs) + item.throw_at(pick(targets), 20, 3) + modify(item) + +/// Do some extra modifications if need be +/datum/gizpulse/thrower/proc/modify(obj/item/item) + return + +/datum/gizpulse/ominous/activate(atom/movable/holder, datum/gizmodes/master, datum/gizmo_interface/interface) + holder.audible_message(span_hear("You hear an ominous hum.")) + +/datum/gizpulse/thrower/grenade + throwables = list( + /obj/item/grenade/iedcasing = 3, + /obj/item/grenade/chem_grenade/cleaner = 2, + /obj/item/grenade/smokebomb = 2, + /obj/item/grenade/syndieminibomb/concussion = 1, + /obj/item/grenade/frag = 1, + /obj/item/grenade/chem_grenade/teargas = 1, + /obj/item/grenade/chem_grenade/facid = 1, + /obj/item/grenade/chem_grenade/clf3 = 1, + ) + +/datum/gizpulse/thrower/grenade/modify(obj/item/item) + var/obj/item/grenade/regret = item + regret.arm_grenade() + +/datum/gizpulse/bone_breaker/activate(atom/movable/holder, datum/gizmodes/master, datum/gizmo_interface/interface) + var/list/victims = list() + for(var/mob/living/loser in orange(1, holder)) + victims += loser + + if(!victims.len) + return + + var/mob/living/victim = pick(victims) + holder.forceMove(get_turf(victim)) + playsound(victim, 'sound/effects/wounds/crack2.ogg', 70, TRUE) + + victim.apply_damage(60, BRUTE, wound_bonus = 100, sharpness = NONE) + victim.Stun(2 SECONDS) + victim.Knockdown(5 SECONDS) + + victim.emote("scream") diff --git a/code/modules/research/gizmo/gizmodes/gizcopier.dm b/code/modules/research/gizmo/gizmodes/gizcopier.dm new file mode 100644 index 00000000000..50fe333f105 --- /dev/null +++ b/code/modules/research/gizmo/gizmodes/gizcopier.dm @@ -0,0 +1,86 @@ +/// Scan and copies the nearest object. The copy copies no functionality, only visually +/datum/gizmodes/copier + guaranteed_active_gizmodes = list( + /datum/gizpulse/scan, + /datum/gizpulse/copy, + /datum/gizpulse/erase, + ) + + /// Weakref of what is marked to copy + var/datum/weakref/marked + /// List of copies currently in circulation + var/list/copies = list() + /// The max amount of copies that can exist at a time + var/max_copies = 50 + +/// Scan the nearest mob/object +/datum/gizpulse/scan/activate(atom/movable/holder, datum/gizmodes/master, datum/gizmo_interface/interface) + if(!istype(master, /datum/gizmodes/copier)) + return + + var/datum/gizmodes/copier/copier = master + + for(var/atom/movable/candidate in oview(1, holder)) + if(candidate.anchored || HAS_TRAIT(candidate, TRAIT_UNDERFLOOR)) // skips most undertile and hidden objects + continue + + copier.marked = WEAKREF(candidate) + playsound(src, 'sound/items/weapons/flash.ogg', 80) //give some feedback that *something* happened + return + +/// Make a copy of whatever you previously scanned +/datum/gizpulse/copy + /// Reference to the gizmodes' copies list so we can track deletions + var/list/copies + +/datum/gizpulse/copy/activate(atom/movable/holder, datum/gizmodes/master, datum/gizmo_interface/interface) + if(!istype(master, /datum/gizmodes/copier)) + return + + var/datum/gizmodes/copier/copier = master + copies = copier.copies + + var/atom/movable/object_to_copy = copier.marked?.resolve() + + if(!object_to_copy) + return + + // So you can pick up copied items but not copied structures and mobs + var/obj/item/copy = new /obj/item/gizmo_copy (get_turf(holder)) + if(!isitem(object_to_copy)) + copy.interaction_flags_item = NONE //so you cant pick it up anymore + + copy.appearance = object_to_copy + copy.density = object_to_copy.density + + copies.Add(copy) + + if(copies.len > copier.max_copies) + var/obj/item/gizmo_copy/copy_to_delete = copies[1] + qdel(copy_to_delete) //it gets removed from the list on del + + RegisterSignal(copy, COMSIG_QDELETING, PROC_REF(remove_from_list)) + +/// Remove a copy from a list if they're deleted +/datum/gizpulse/copy/proc/remove_from_list(datum/source) + SIGNAL_HANDLER + + copies.Remove(source) + +/// Wipe all current copies +/datum/gizpulse/erase/activate(atom/movable/holder, datum/gizmodes/master, datum/gizmo_interface/interface) + if(!istype(master, /datum/gizmodes/copier)) + return + + var/datum/gizmodes/copier/copier = master + + for(var/copy in copier.copies) + qdel(copy) + + copier.copies.Cut() + +/obj/item/gizmo_copy/emp_act(severity) + . = ..() + + do_sparks(2, FALSE, "gizmo copy") + qdel(src) diff --git a/code/modules/research/gizmo/gizmodes/gizlectric.dm b/code/modules/research/gizmo/gizmodes/gizlectric.dm new file mode 100644 index 00000000000..9d8d90a52df --- /dev/null +++ b/code/modules/research/gizmo/gizmodes/gizlectric.dm @@ -0,0 +1,166 @@ +/// Suck power and shoot it out again +/datum/gizmodes/electric + possible_active_modes = list( + /datum/gizpulse/electric/emp = 1, + /datum/gizpulse/electric/discharge = 1, + /datum/gizpulse/electric/charge = 1, + /datum/gizpulse/electric/revive = 1, + ) + + guaranteed_active_gizmodes = list( + GIZMO_PICK_ONE = list( + /datum/gizpulse/electric/draw = 1, + /datum/gizpulse/electric/passive_charge = 1, + ) + ) + + mode_pulses = list( + /datum/gizpulse/mode_controle/select_mode, + /datum/gizpulse/mode_controle/cycle_mode, + /datum/gizpulse/mode_controle/direct_activate, + ) + + min_modes = 3 + max_modes = 4 + + cooldown_time = 6 SECONDS + + /// The internal power cell + var/obj/item/stock_parts/power_store/battery/gizmo/power + +/datum/gizmodes/electric/activate(atom/movable/holder) + if(!power) + power = new(holder) + + return ..() + +/// Batter used in the gizmo device +/obj/item/stock_parts/power_store/battery/gizmo + charge = STANDARD_BATTERY_CHARGE * 0.1 //you gotta work for your fun + +/// Get the total charge +/datum/gizpulse/electric/proc/get_power(atom/movable/holder, datum/gizmodes/master) + if(istype(master, /datum/gizmodes/electric)) + var/datum/gizmodes/electric/electromaster = master + return electromaster.power.charge() + return 0 + +/// Use some charge +/datum/gizpulse/electric/proc/use_power(amount, atom/movable/holder, datum/gizmodes/master) + if(istype(master, /datum/gizmodes/electric)) + var/datum/gizmodes/electric/electromaster = master + return electromaster.power.use(amount) + return FALSE + +/// Do an EMP blast +/datum/gizpulse/electric/emp + /// Min power to do an EMP + var/min_power = STANDARD_CELL_CHARGE + +/// Do an EMP blast using the cell of our gizmode +/datum/gizpulse/electric/emp/activate(atom/movable/holder, datum/gizmodes/master, datum/gizmo_interface/interface) + var/charge = get_power(holder, master) + if(charge < min_power) + return + /// Max charge is 1MJ, standard cell charge is 10kJ. A full charge EMP is 1000 / 10 = 100. 100 / 15 is 6 tiles of light emp range + empulse(get_turf(holder), floor(charge / STANDARD_CELL_CHARGE / 40), floor(charge / STANDARD_CELL_CHARGE / 15), holder) + use_power(charge, holder, master) + +/// Shoot our current charge away as lightning +/datum/gizpulse/electric/discharge/activate(atom/movable/holder, datum/gizmodes/master, datum/gizmo_interface/interface) + var/charge = get_power(holder, master) + if(charge) + return + + tesla_zap(holder, power = charge, zap_flags = ZAP_GIZMO_FLAGS) + use_power(charge, holder, master) + +/// Look for an object with a cell, and CHARGE IT!!! +/datum/gizpulse/electric/charge/activate(atom/movable/holder, datum/gizmodes/master, datum/gizmo_interface/interface) + if(!istype(master, /datum/gizmodes/electric)) + return + + var/datum/gizmodes/electric/electromaster = master + + for(var/atom/movable/power_source in oview(4, holder)) + if(!power_source.get_cell()) + continue + + var/obj/item/stock_parts/power_store/cell = power_source.get_cell() + + var/charge = electromaster.power.charge() - cell.used_charge() + if(charge <= 0) + continue + + cell.give(charge) + electromaster.power.use(charge) + + holder.Beam(power_source, icon_state = "g_beam", time = 5) + playsound(power_source, 'sound/effects/magic/ethereal_exit.ogg', 40) + return + +/// Revive people in a radius like the revival surgery +/datum/gizpulse/electric/revive + /// The charge cost for a defibrillation pulse + var/defib_cost = STANDARD_CELL_CHARGE * 0.5 + +/datum/gizpulse/electric/revive/activate(atom/movable/holder, datum/gizmodes/master, datum/gizmo_interface/interface) + if(!istype(master, /datum/gizmodes/electric)) + return + + var/datum/gizmodes/electric/electromaster = master + + if(electromaster.power.charge() < defib_cost) + return + + electromaster.power.use(defib_cost) + + for(var/mob/living/dead in orange(holder, 3)) + if(dead.stat == DEAD) + if(dead.revive(excess_healing = 5)) + if(iscarbon(dead)) //still want it to work for simple/basicmobs too + var/mob/living/carbon/dead_but_carbon = dead + dead_but_carbon.set_heartattack(FALSE) + dead.adjust_oxy_loss(-200) + addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(playsound), dead, 'sound/machines/defib/defib_zap.ogg', 60), 3 SECONDS) + + new /obj/effect/temp_visual/circle_wave(get_turf(holder), COLOR_YELLOW) + playsound(holder, 'sound/machines/defib/defib_charge.ogg', 80) + +/// Look for the nearest power-containing object and suck the power out +/datum/gizpulse/electric/draw/activate(atom/movable/holder, datum/gizmodes/master, datum/gizmo_interface/interface) + if(!istype(master, /datum/gizmodes/electric)) + return + + var/datum/gizmodes/electric/electromaster = master + + for(var/atom/movable/power_source in oview(4, holder)) + if(!power_source.get_cell()) + continue + + var/obj/item/stock_parts/power_store/cell = power_source.get_cell() + + var/charge = cell.charge() - electromaster.power.used_charge() + if(charge <= 0) + continue + + cell.use(charge) + electromaster.power.give(charge) + + holder.Beam(power_source, icon_state = "r_beam", time = 5) + playsound(power_source, 'sound/effects/magic/ethereal_exit.ogg', 40) + return + +/// Give a bit of charge, FOR FREE +/datum/gizpulse/electric/passive_charge + /// How much we magically charge from nothing per pulse + var/recharge = STANDARD_BATTERY_CHARGE * 0.001 + +/datum/gizpulse/electric/passive_charge/activate(atom/movable/holder, datum/gizmodes/master, datum/gizmo_interface/interface) + if(!istype(master, /datum/gizmodes/electric)) + return + + var/datum/gizmodes/electric/electromaster = master + electromaster.power.give(recharge) + + playsound(holder, 'sound/effects/magic/charge.ogg', 50, TRUE) diff --git a/code/modules/research/gizmo/gizmodes/gizmisc.dm b/code/modules/research/gizmo/gizmodes/gizmisc.dm new file mode 100644 index 00000000000..ae3ad6ce9fa --- /dev/null +++ b/code/modules/research/gizmo/gizmodes/gizmisc.dm @@ -0,0 +1,51 @@ +/// Make the holder move by adding a movement element. Signal is for aestethic interactions mostly +/datum/gizmodes/mover + guaranteed_active_gizmodes = list(/datum/gizpulse/start_moving = 1, /datum/gizpulse/stop_moving = 1) + +/datum/gizpulse/start_moving/activate(atom/movable/holder, datum/gizmodes/master, datum/gizmo_interface/interface) + holder.AddElement(/datum/element/moving_randomly) + SEND_SIGNAL(holder, COMSIG_GIZMO_START_MOVING, src) + +/datum/gizpulse/stop_moving/activate(atom/movable/holder, datum/gizmodes/master, datum/gizmo_interface/interface) + holder.RemoveElement(/datum/element/moving_randomly) + SEND_SIGNAL(holder, COMSIG_GIZMO_STOP_MOVING, src) + +/// Start glowing +/datum/gizmodes/lights + guaranteed_active_gizmodes = list(/datum/gizpulse/lights_on, /datum/gizpulse/lights_off) + mode_pulses = list( + /datum/gizpulse/mode_controle/direct_activate, + /datum/gizpulse/mode_controle/cycle_mode/activate, + ) + +/datum/gizpulse/lights_on/activate(atom/movable/holder, datum/gizmodes/master, datum/gizmo_interface/interface) + SEND_SIGNAL(holder, COMSIG_GIZMO_ON_STATE) + + holder.set_light( + l_range = 3, + l_power = 2, + l_color = LIGHT_COLOR_INTENSE_RED, + l_on = TRUE, + ) + +/datum/gizpulse/lights_off/activate(atom/movable/holder, datum/gizmodes/master, datum/gizmo_interface/interface) + SEND_SIGNAL(holder, COMSIG_GIZMO_OFF_STATE) + holder.set_light_on(FALSE) + +/// Gives a voice hint or changes the voices language for use with a voice interface (i mean you give this to a wire interface or other but it then gives you +/// the info to use a voice interface) +/datum/gizmodes/voice + guaranteed_active_gizmodes = list(/datum/gizpulse/voice_hint, /datum/gizpulse/language_change) + mode_pulses = list( + /datum/gizpulse/mode_controle/direct_activate, + ) + +/// Spit out a hint for using the voice interface +/datum/gizpulse/voice_hint/activate(atom/movable/holder, datum/gizmodes/master, datum/gizmo_interface/interface) + var/datum/component/gizmo_voice/voice = holder.GetComponent(/datum/component/gizmo_voice) + + holder.say(voice.active_words.Join(" ")) + +/// Pick a different language +/datum/gizpulse/language_change/activate(atom/movable/holder, datum/gizmodes/master, datum/gizmo_interface/interface) + holder.grant_random_uncommon_language("gizmo") diff --git a/code/modules/research/gizmo/gizmodes/gizmood.dm b/code/modules/research/gizmo/gizmodes/gizmood.dm new file mode 100644 index 00000000000..ed9133f7e63 --- /dev/null +++ b/code/modules/research/gizmo/gizmodes/gizmood.dm @@ -0,0 +1,41 @@ +/// Send out mood pulses, good or bad +/datum/gizmodes/mood_pulser + guaranteed_active_gizmodes = list(/datum/gizpulse/mood_pulser/positive, /datum/gizpulse/mood_pulser/negative) + possible_active_modes = list( + /datum/gizpulse/radiation_pulse = 1, + ) + min_modes = 0 + max_modes = 1 + +/// Send out a mood pulse +/datum/gizpulse/mood_pulser + /// Mood event to give out + var/datum/mood_event/mood + /// Color of the ring effect (god i love the ring effect) + var/ring_color + /// Range of the mood pulse + var/range = 14 + +/datum/gizpulse/mood_pulser/activate(atom/movable/holder, datum/gizmodes/master, datum/gizmo_interface/interface) + mood_pulse(holder) + +/// Send a mood pulse to a range +/datum/gizpulse/mood_pulser/proc/mood_pulse(atom/movable/holder) + new /obj/effect/temp_visual/circle_wave(get_turf(holder), ring_color) + for(var/mob/living/carbon/human/human in urange(range, holder)) + human.add_mood_event("gizmo_mood_pulse", mood) + +/// Make a positive mood pulse +/datum/gizpulse/mood_pulser/positive + mood = /datum/mood_event/gizmo_positive + ring_color = COLOR_GREEN + +/// Make a negative mood pulse +/datum/gizpulse/mood_pulser/negative + mood = /datum/mood_event/gizmo_negative + ring_color = COLOR_RED + +/datum/gizpulse/radiation_pulse/activate(atom/movable/holder, datum/gizmodes/master, datum/gizmo_interface/interface) + new /obj/effect/temp_visual/circle_wave(get_turf(holder), COLOR_GREEN) + + radiation_pulse(holder, max_range = 5, threshold = RAD_LIGHT_INSULATION, chance = 30) diff --git a/code/modules/research/gizmo/gizmodes/gizmopper.dm b/code/modules/research/gizmo/gizmodes/gizmopper.dm new file mode 100644 index 00000000000..560fc3b8cfa --- /dev/null +++ b/code/modules/research/gizmo/gizmodes/gizmopper.dm @@ -0,0 +1,92 @@ +/// Gizmo mode that regenerates, cycles and expells reagents in different functions +/datum/gizmodes/mopper + possible_active_modes = list( + /datum/gizpulse/wet_tiles/fluid_circle/small = 1, + /datum/gizpulse/wet_tiles/fluid_circle/medium = 1, + /datum/gizpulse/wet_tiles/fluid_circle/large = 1, + /datum/gizpulse/fluid_smoke = 1, + /datum/gizpulse/swap_reagent = 1, + ) + + min_modes = 3 + max_modes = 5 + + /// Reagents that can be selected + var/list/reagents = list( + /datum/reagent/water, + /datum/reagent/toxin/acid, + /datum/reagent/consumable/salt, + /datum/reagent/uranium/radium, + ) + /// Reference to the reagent holder. Preferably access it from the holder instead, but some procs dont like that (process()) + var/datum/reagents/reagent_holder + /// Reagent that is being generated right now + var/active_reagent = /datum/reagent/water + /// Max volume of the reagent holder we hand out + var/max_volume = 50 + /// Amount of reagents we regenerate per second + var/regeneration_speed = 2 + /// How many reagents we grab from get_random_reagent_id + var/random_reagents_to_add = 1 + /// Flags to pass to the reagent holder + var/reagent_flags = AMOUNT_VISIBLE + +/datum/gizmodes/mopper/New() + . = ..() + + for(var/i in 1 to random_reagents_to_add) + reagents += get_random_reagent_id() + +/datum/gizmodes/mopper/activate(atom/movable/holder) + if(!holder.reagents) + holder.create_reagents(max_volume, reagent_flags) + holder.reagents.add_reagent(active_reagent, max_volume) + reagent_holder = holder.reagents + START_PROCESSING(SSdcs, src) + return ..() + +/datum/gizmodes/mopper/process(seconds_per_tick) + reagent_holder.add_reagent(active_reagent, regeneration_speed * seconds_per_tick) + +/// Wet the surounding tiles +/datum/gizpulse/wet_tiles/activate(atom/movable/holder, datum/gizmodes/mopper/master, datum/gizmo_interface/interface) + var/list/tiles = get_tiles(holder) + for(var/turf/open/tile in tiles) + tile.expose_reagents(holder.reagents.reagent_list, holder.reagents) + + holder.reagents.expose(tile, TOUCH, 1, master.max_volume / tiles.len) + holder.reagents.remove_reagent(master.active_reagent, master.max_volume / tiles.len) + +/// Get the tiles to wet +/datum/gizpulse/wet_tiles/proc/get_tiles(atom/movable/holder) + return + +/// Dump reagents in a circle +/datum/gizpulse/wet_tiles/fluid_circle + /// Size, in a circle, around the holder for wetting + var/size = 0 + +/datum/gizpulse/wet_tiles/fluid_circle/get_tiles(atom/movable/holder) + return RANGE_TURFS(size, holder) + +/// In a small circle +/datum/gizpulse/wet_tiles/fluid_circle/small + size = 1 + +/// In a medium circle +/datum/gizpulse/wet_tiles/fluid_circle/medium + size = 2 + +/// In a large circle +/datum/gizpulse/wet_tiles/fluid_circle/large + size = 3 + +/// Make a smoke cloud of our fluid +/datum/gizpulse/fluid_smoke/activate(atom/movable/holder, datum/gizmo_interface/interface) + do_chem_smoke(3, holder, get_turf(holder), carry = holder.reagents) + holder.reagents.clear_reagents() + +/// Select different reagents +/datum/gizpulse/swap_reagent/activate(atom/movable/holder, datum/gizmodes/mopper/master, datum/gizmo_interface/interface) + holder.reagents.clear_reagents() + master.active_reagent = pick(master.reagents - master.active_reagent) //maybe also add a cycle one instead of random diff --git a/code/modules/research/gizmo/gizmodes/gizporter.dm b/code/modules/research/gizmo/gizmodes/gizporter.dm new file mode 100644 index 00000000000..e28ca158057 --- /dev/null +++ b/code/modules/research/gizmo/gizmodes/gizporter.dm @@ -0,0 +1,45 @@ +/// Teleports itself and/or others +/datum/gizmodes/teleporter + possible_active_modes = list( + /datum/gizpulse/teleport/self = 1, + /datum/gizpulse/teleport/other = 1, + /datum/gizpulse/teleport/other/and_self = 1, + ) + + min_modes = 2 + max_modes = 3 + +/// Teleport... stuff... +/datum/gizpulse/teleport + /// Min distance to teleport + var/offset_min = 5 + /// Max distance to teleport + var/offset_max = 15 + +/// Teleport... stuff... +/datum/gizpulse/teleport/activate(atom/movable/holder, datum/gizmodes/master, datum/gizmo_interface/interface) + var/list/targets = get_teleport_targets(holder) + var/range = rand(offset_min, offset_max) + var/dir = pick(GLOB.alldirs) + + for(var/atom/movable/target as anything in targets) + var/turf/new_turf = get_ranged_target_turf(target, dir, range) + do_teleport(target, new_turf, asoundin = 'sound/effects/cartoon_sfx/cartoon_pop.ogg', channel = TELEPORT_CHANNEL_BLUESPACE) + +/datum/gizpulse/teleport/proc/get_teleport_targets(atom/movable/holder) + return list() + +/// Teleport yourself +/datum/gizpulse/teleport/self/get_teleport_targets(atom/movable/holder) + return list(holder) + +/// Teleport someone else +/datum/gizpulse/teleport/other/get_teleport_targets(atom/movable/holder) + . = list() + for(var/mob/living/living in view(2, holder)) + . += living + +/// Teleport yourself and someone else +/datum/gizpulse/teleport/other/and_self/get_teleport_targets(atom/movable/holder) + return ..() + holder + diff --git a/code/modules/research/gizmo/gizpuzzle.dm b/code/modules/research/gizmo/gizpuzzle.dm new file mode 100644 index 00000000000..18763db7a56 --- /dev/null +++ b/code/modules/research/gizmo/gizpuzzle.dm @@ -0,0 +1,95 @@ +/// Holds the puzzle sequences, receives the pulses, decides if theyre correct, and gives feedback and calls the right callbacks when it does +/datum/gizmo_puzzle + /// The wires we need to pulse for cracking the code + var/list/cryptic_pulse = list( + GIZMO_PULSE_1, + GIZMO_PULSE_2, + GIZMO_PULSE_3, + GIZMO_PULSE_4, + GIZMO_PULSE_5, + GIZMO_PULSE_6, + GIZMO_PULSE_7, + GIZMO_PULSE_8, + ) + + /// How long a code sequence can be + var/code_length = 3 + /// The codes that got generated, formatted as (1 = list(CRYPTIC_WIRE_5, CRYPTIC_WIRE_3, CRYPTIC_WIRE_7, 2 = list(...))) + var/list/code_sequences + /// The current sequence we're on. Will reset if it doesn't match anything + var/list/current_sequence = list() + /// List of callbacks that the solutions will call on succes + var/list/solution_callbacks + + /// For if you want something to happen on merely being pulsed. If null, simply ping, bleep and creak or whatever as feedback + var/datum/callback/pulsed_callback + + COOLDOWN_DECLARE(feedback_cooldown) + /// So the ping buzz feedback doesnt spam too much + var/feedback_cooldown_time = 0.2 SECONDS + +/datum/gizmo_puzzle/New(datum/callback/pulsed) + if(pulsed) + pulsed_callback = pulsed + else + pulsed_callback = CALLBACK(src, PROC_REF(default_on_pulsed)) + return ..() + +/// Make up a sequence +/datum/gizmo_puzzle/proc/generate_code_sequences(list/solution_callbacks) + src.solution_callbacks = solution_callbacks + code_sequences = list() + + for(var/i in 1 to solution_callbacks.len) + code_sequences += list(list()) + for(var/j in 1 to code_length) + code_sequences[i] += pick(cryptic_pulse) + +/// Whenever a puzzle attempt is made +/datum/gizmo_puzzle/proc/on_pulse(pulse_number, mob/living/user, atom/movable/holder, no_feedback = FALSE) + current_sequence += cryptic_pulse[pulse_number] + . = GIZMO_PUZZLE_CORRECT + + var/succeeded = FALSE + + for(var/i in 1 to code_sequences.len) + var/list/a = code_sequences[i] + for(var/j in 1 to current_sequence.len) + if(current_sequence[j] != a[j]) + break + if(current_sequence.len == j) + succeeded = TRUE + if(j == a.len) + var/datum/callback/callback = solution_callbacks[i] + callback.Invoke(holder) + current_sequence.Cut() + . = GIZMO_PUZZLE_SOLVED + break + + if(!succeeded) + current_sequence.Cut() + . = GIZMO_PUZZLE_WRONG + + pulsed_callback?.Invoke(holder, user, ., no_feedback) + +/// Just some feedback so people can start forcing sequences. No feedback if it's done automatically +/datum/gizmo_puzzle/proc/default_on_pulsed(atom/movable/holder, mob/living/user, solved_type, no_feedback = FALSE) + if(!COOLDOWN_FINISHED(src, feedback_cooldown) || !isliving(user) || no_feedback) + return + + COOLDOWN_START(src, feedback_cooldown, feedback_cooldown_time) + + switch(solved_type) + if(GIZMO_PUZZLE_WRONG) + holder.balloon_alert(user, "buzz") + playsound(holder, 'sound/machines/buzz/buzz-sigh.ogg', 30, FALSE) + if(GIZMO_PUZZLE_CORRECT) + holder.balloon_alert(user, "ping") + playsound(holder, 'sound/machines/ping.ogg', 30, FALSE) + if(GIZMO_PUZZLE_SOLVED) + holder.balloon_alert(user, "creak") + playsound(holder, 'sound/machines/creak.ogg', 30, FALSE) + +/// Sequences can be a bit shorter since you have to constantly type and scream them +/datum/gizmo_puzzle/voice + code_length = 2 diff --git a/code/modules/research/ordnance/_scipaper.dm b/code/modules/research/ordnance/_scipaper.dm index 0b5efc03e10..e5fa3c3c8f0 100644 --- a/code/modules/research/ordnance/_scipaper.dm +++ b/code/modules/research/ordnance/_scipaper.dm @@ -185,7 +185,7 @@ author = "Unknown" et_alia = FALSE if(!abstract) - abstract = "Published on [station_time_timestamp()]" + abstract = "Published on [server_timestamp(ic_time = TRUE)] (PT: [round_timestamp()])" /datum/scientific_paper/explosive /** diff --git a/code/modules/research/ordnance/doppler_array.dm b/code/modules/research/ordnance/doppler_array.dm index b39758918ea..e22bb36b8e6 100644 --- a/code/modules/research/ordnance/doppler_array.dm +++ b/code/modules/research/ordnance/doppler_array.dm @@ -169,7 +169,7 @@ var/datum/data/tachyon_record/new_record = new /datum/data/tachyon_record() new_record.name = "Log Recording #[record_number]" - new_record.timestamp = station_time_timestamp() + new_record.timestamp = "[server_timestamp(ic_time = TRUE)] (PT: [round_timestamp()])" new_record.coordinates = "[epicenter.x], [epicenter.y]" new_record.displacement = took new_record.factual_radius["epicenter_radius"] = devastation_range diff --git a/code/modules/research/ordnance/tank_compressor.dm b/code/modules/research/ordnance/tank_compressor.dm index 4887b41849b..0631a7ed0aa 100644 --- a/code/modules/research/ordnance/tank_compressor.dm +++ b/code/modules/research/ordnance/tank_compressor.dm @@ -169,7 +169,7 @@ var/datum/data/compressor_record/new_record = new() new_record.name = "Log Recording #[record_number]" new_record.experiment_source = inserted_tank.name - new_record.timestamp = station_time_timestamp() + new_record.timestamp = "[server_timestamp(ic_time = TRUE)] (PT: [round_timestamp()])" for(var/gas_path in leaked_gas_buffer.gases) new_record.gas_data[gas_path] = leaked_gas_buffer.gases[gas_path][MOLES] diff --git a/code/modules/research/part_replacer.dm b/code/modules/research/part_replacer.dm index b0901cd9b01..581c1d6e28b 100644 --- a/code/modules/research/part_replacer.dm +++ b/code/modules/research/part_replacer.dm @@ -123,6 +123,7 @@ new /obj/item/stock_parts/micro_laser(src) new /obj/item/stock_parts/matter_bin(src) new /obj/item/stock_parts/power_store/cell/high(src) + new /obj/item/stock_parts/power_store/battery/high(src) /obj/item/storage/part_replacer/bluespace/tier2/PopulateContents() for(var/i in 1 to 10) @@ -132,6 +133,7 @@ new /obj/item/stock_parts/micro_laser/high(src) new /obj/item/stock_parts/matter_bin/adv(src) new /obj/item/stock_parts/power_store/cell/super(src) + new /obj/item/stock_parts/power_store/battery/super(src) /obj/item/storage/part_replacer/bluespace/tier3/PopulateContents() for(var/i in 1 to 10) @@ -141,6 +143,7 @@ new /obj/item/stock_parts/micro_laser/ultra(src) new /obj/item/stock_parts/matter_bin/super(src) new /obj/item/stock_parts/power_store/cell/hyper(src) + new /obj/item/stock_parts/power_store/battery/hyper(src) /obj/item/storage/part_replacer/bluespace/tier4/PopulateContents() for(var/i in 1 to 10) @@ -150,6 +153,7 @@ new /obj/item/stock_parts/micro_laser/quadultra(src) new /obj/item/stock_parts/matter_bin/bluespace(src) new /obj/item/stock_parts/power_store/cell/bluespace(src) + new /obj/item/stock_parts/power_store/battery/bluespace(src) new /obj/item/stack/cable_coil/thirty(src) //used in a cargo crate diff --git a/code/modules/research/server.dm b/code/modules/research/server.dm index 628e0fcfe4a..12dbc25158b 100644 --- a/code/modules/research/server.dm +++ b/code/modules/research/server.dm @@ -46,12 +46,14 @@ return ..() /obj/machinery/rnd/server/update_icon_state() + . = ..() if(machine_stat & NOPOWER) icon_state = "[base_icon_state]-off" + else if(panel_open) + icon_state = "[base_icon_state]-on" + "_t" else // "working" will cover EMP'd, disabled, or just broken icon_state = "[base_icon_state]-[working ? "on" : "halt"]" - return ..() /obj/machinery/rnd/server/power_change() refresh_working() diff --git a/code/modules/research/techweb/nodes/service_nodes.dm b/code/modules/research/techweb/nodes/service_nodes.dm index c40e15b001c..c0a07e72c68 100644 --- a/code/modules/research/techweb/nodes/service_nodes.dm +++ b/code/modules/research/techweb/nodes/service_nodes.dm @@ -29,6 +29,7 @@ "razor", "bucket", "mop", + "wet_floor_sign", "pushbroom", "normtrash", "wirebrush", diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm index 6ed0030a2dd..a0315544d11 100644 --- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm +++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm @@ -5,7 +5,8 @@ /datum/status_effect/rainbow_protection id = "rainbow_protection" - duration = 100 + duration = 10 SECONDS + tick_interval = STATUS_EFFECT_NO_TICK alert_type = /atom/movable/screen/alert/status_effect/rainbow_protection show_duration = TRUE @@ -13,14 +14,17 @@ owner.add_traits(list(TRAIT_GODMODE, TRAIT_PACIFISM), TRAIT_STATUS_EFFECT(id)) owner.visible_message(span_warning("[owner] shines with a brilliant rainbow light."), span_notice("You feel protected by an unknown force!")) - return ..() - -/datum/status_effect/rainbow_protection/tick(seconds_between_ticks) - owner.add_atom_colour(RANDOM_COLOUR, TEMPORARY_COLOUR_PRIORITY) - return ..() + // okay, now time for the rainbow animation. + owner.add_filter("rainbow_protection_[REF(src)]", 2, color_matrix_filter(list(0,0,0, 0,0.75,0, 0,0,1, 0,0.25,0), COLORSPACE_HSL)) + var/color_filter = owner.get_filter("rainbow_protection_[REF(src)]") + animate(color_filter, list("color" = list(0,0,0, 0,0.75,0, 0,0,1, 0.33,0.25,0)), time = 1 SECONDS, loop = -1) + animate(list("color" = list(0,0,0, 0,0.75,0, 0,0,1, 0.66,0.25,0)), time = 1 SECONDS) + animate(list("color" = list(0,0,0, 0,0.75,0, 0,0,1, 1,0.25,0)), time = 1 SECONDS) + animate(list("color" = list(0,0,0, 0,0.75,0, 0,0,1, 0,0.25,0)), time = 0) // IMPORTANT! + return TRUE /datum/status_effect/rainbow_protection/on_remove() - owner.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY) + owner.remove_filter("rainbow_protection_[REF(src)]") owner.remove_traits(list(TRAIT_GODMODE, TRAIT_PACIFISM), TRAIT_STATUS_EFFECT(id)) owner.visible_message(span_notice("[owner] stops glowing, the rainbow light fading away."), span_warning("You no longer feel protected...")) @@ -32,12 +36,12 @@ /datum/status_effect/slimeskin id = "slimeskin" - duration = 300 + duration = 30 SECONDS alert_type = /atom/movable/screen/alert/status_effect/slimeskin show_duration = TRUE /datum/status_effect/slimeskin/on_apply() - owner.add_atom_colour("#3070CC", TEMPORARY_COLOUR_PRIORITY) + owner.add_atom_colour(color_transition_filter("#3070CC", SATURATION_OVERRIDE), TEMPORARY_COLOUR_PRIORITY) if(ishuman(owner)) var/mob/living/carbon/human/H = owner H.physiology.damage_resistance += 10 @@ -168,7 +172,7 @@ owner.ckey = originalmind.key if(clone) clone.unequip_everything() - qdel(clone) + QDEL_NULL(clone) /atom/movable/screen/alert/status_effect/clone_decay name = "Clone Decay" @@ -202,7 +206,7 @@ /datum/status_effect/bloodchill id = "bloodchill" - duration = 100 + duration = 10 SECONDS alert_type = /atom/movable/screen/alert/status_effect/bloodchill /datum/status_effect/bloodchill/on_apply() @@ -210,7 +214,7 @@ return ..() /datum/status_effect/bloodchill/tick(seconds_between_ticks) - if(prob(50)) + if(SPT_PROB(50, seconds_between_ticks)) owner.adjust_fire_loss(2) /datum/status_effect/bloodchill/on_remove() @@ -218,7 +222,7 @@ /datum/status_effect/bonechill id = "bonechill" - duration = 80 + duration = 8 SECONDS alert_type = /atom/movable/screen/alert/status_effect/bonechill /datum/status_effect/bonechill/on_apply() @@ -226,13 +230,14 @@ return ..() /datum/status_effect/bonechill/tick(seconds_between_ticks) - if(prob(50)) - owner.adjust_fire_loss(1) - owner.set_jitter_if_lower(6 SECONDS) - owner.adjust_bodytemperature(-10) - if(ishuman(owner)) - var/mob/living/carbon/human/humi = owner - humi.adjust_coretemperature(-10) + if(!SPT_PROB(50, seconds_between_ticks)) + return + owner.adjust_fire_loss(1) + owner.set_jitter_if_lower(6 SECONDS) + owner.adjust_bodytemperature(-10) + if(ishuman(owner)) + var/mob/living/carbon/human/humi = owner + humi.adjust_coretemperature(-10) /datum/status_effect/bonechill/on_remove() owner.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/bonechill) @@ -249,7 +254,7 @@ alert_type = null /datum/status_effect/rebreathing/tick(seconds_between_ticks) - owner.adjust_oxy_loss(-6, 0) //Just a bit more than normal breathing. + owner.adjust_oxy_loss(-6 * seconds_between_ticks) //Just a bit more than normal breathing. /////////////////////////////////////////////////////// //////////////////CONSUMING EXTRACTS/////////////////// @@ -259,7 +264,8 @@ id = "firecookie" status_type = STATUS_EFFECT_REPLACE alert_type = null - duration = 100 + duration = 10 SECONDS + tick_interval = STATUS_EFFECT_NO_TICK /datum/status_effect/firecookie/on_apply() ADD_TRAIT(owner, TRAIT_RESISTCOLD, TRAIT_STATUS_EFFECT(id)) @@ -273,7 +279,7 @@ id = "watercookie" status_type = STATUS_EFFECT_REPLACE alert_type = null - duration = 100 + duration = 10 SECONDS /datum/status_effect/watercookie/on_apply() ADD_TRAIT(owner, TRAIT_NO_SLIP_WATER, TRAIT_STATUS_EFFECT(id)) @@ -290,7 +296,8 @@ id = "metalcookie" status_type = STATUS_EFFECT_REFRESH alert_type = null - duration = 100 + duration = 10 SECONDS + tick_interval = STATUS_EFFECT_NO_TICK /datum/status_effect/metalcookie/on_apply() if(ishuman(owner)) @@ -307,7 +314,8 @@ id = "sparkcookie" status_type = STATUS_EFFECT_REFRESH alert_type = null - duration = 300 + duration = 30 SECONDS + tick_interval = STATUS_EFFECT_NO_TICK var/original_coeff /datum/status_effect/sparkcookie/on_apply() @@ -326,7 +334,8 @@ id = "toxincookie" status_type = STATUS_EFFECT_REPLACE alert_type = null - duration = 600 + duration = 1 MINUTES + tick_interval = STATUS_EFFECT_NO_TICK /datum/status_effect/toxincookie/on_apply() ADD_TRAIT(owner, TRAIT_TOXINLOVER, TRAIT_STATUS_EFFECT(id)) @@ -339,7 +348,8 @@ id = "timecookie" status_type = STATUS_EFFECT_REPLACE alert_type = null - duration = 600 + duration = 1 MINUTES + tick_interval = STATUS_EFFECT_NO_TICK /datum/status_effect/timecookie/on_apply() owner.add_actionspeed_modifier(/datum/actionspeed_modifier/timecookie) @@ -353,7 +363,7 @@ id = "lovecookie" status_type = STATUS_EFFECT_REPLACE alert_type = null - duration = 300 + duration = 30 SECONDS /datum/status_effect/lovecookie/tick(seconds_between_ticks) if(owner.stat != CONSCIOUS) @@ -374,7 +384,7 @@ id = "tarcookie" status_type = STATUS_EFFECT_REPLACE alert_type = null - duration = 100 + duration = 10 SECONDS /datum/status_effect/tarcookie/tick(seconds_between_ticks) for(var/mob/living/carbon/human/L in range(get_turf(owner),1)) @@ -385,7 +395,7 @@ id = "tarfoot" status_type = STATUS_EFFECT_REPLACE alert_type = null - duration = 30 + duration = 3 SECONDS /datum/status_effect/tarfoot/on_apply() owner.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/tarfoot) @@ -398,12 +408,12 @@ id = "spookcookie" status_type = STATUS_EFFECT_REPLACE alert_type = null - duration = 300 + duration = 30 SECONDS /datum/status_effect/spookcookie/on_apply() - var/image/I = image(icon = 'icons/mob/human/human.dmi', icon_state = "skeleton", layer = ABOVE_MOB_LAYER, loc = owner) - I.override = 1 - owner.add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/everyone, "spookyscary", I) + var/image/skeleton_image = image(icon = 'icons/mob/human/human.dmi', icon_state = "skeleton", layer = ABOVE_MOB_LAYER, loc = owner) + skeleton_image.override = TRUE + owner.add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/everyone, "spookyscary", skeleton_image) return ..() /datum/status_effect/spookcookie/on_remove() @@ -413,7 +423,7 @@ id = "peacecookie" status_type = STATUS_EFFECT_REPLACE alert_type = null - duration = 100 + duration = 10 SECONDS /datum/status_effect/peacecookie/tick(seconds_between_ticks) for(var/mob/living/L in range(get_turf(owner),1)) @@ -423,7 +433,8 @@ id = "plur" status_type = STATUS_EFFECT_REPLACE alert_type = null - duration = 30 + duration = 3 SECONDS + tick_interval = STATUS_EFFECT_NO_TICK /datum/status_effect/plur/on_apply() ADD_TRAIT(owner, TRAIT_PACIFISM, TRAIT_STATUS_EFFECT(id)) @@ -436,7 +447,8 @@ id = "adamantinecookie" status_type = STATUS_EFFECT_REFRESH alert_type = null - duration = 100 + duration = 10 SECONDS + tick_interval = STATUS_EFFECT_NO_TICK /datum/status_effect/adamantinecookie/on_apply() if(ishuman(owner)) @@ -638,7 +650,7 @@ /datum/status_effect/stabilized/darkpurple/on_remove() REMOVE_TRAIT(owner, TRAIT_RESISTHEATHANDS, TRAIT_STATUS_EFFECT(id)) - qdel(fire) + QDEL_NULL(fire) /datum/status_effect/stabilized/darkpurple/get_examine_text() return span_notice("[owner.p_Their()] fingertips burn brightly!") @@ -698,7 +710,8 @@ /datum/status_effect/bluespacestabilization id = "stabilizedbluespacecooldown" - duration = 1200 + duration = 2 MINUTES + tick_interval = STATUS_EFFECT_NO_TICK alert_type = null /datum/status_effect/stabilized/bluespace @@ -796,7 +809,8 @@ colour = SLIME_TYPE_PYRITE /datum/status_effect/stabilized/pyrite/tick(seconds_between_ticks) - owner.add_atom_colour(RANDOM_COLOUR, TEMPORARY_COLOUR_PRIORITY) + var/new_color = rgb(rand(0, 360), 100, 50, space = COLORSPACE_HSL) + owner.add_atom_colour(color_transition_filter(new_color, SATURATION_OVERRIDE), TEMPORARY_COLOUR_PRIORITY) return ..() /datum/status_effect/stabilized/pyrite/on_remove() diff --git a/code/modules/research/xenobiology/vatgrowing/petri_dish.dm b/code/modules/research/xenobiology/vatgrowing/petri_dish.dm index 08e88b1e481..c26906c0091 100644 --- a/code/modules/research/xenobiology/vatgrowing/petri_dish.dm +++ b/code/modules/research/xenobiology/vatgrowing/petri_dish.dm @@ -26,11 +26,8 @@ var/datum/micro_organism/MO = i . += MO.get_details() -/obj/item/petri_dish/pre_attack(atom/A, mob/living/user, list/modifiers, list/attack_modifiers) +/obj/item/petri_dish/wash(clean_types) . = ..() - if(!sample || !istype(A, /obj/structure/sink)) - return FALSE - to_chat(user, span_notice("You wash the sample out of [src].")) sample = null update_appearance() diff --git a/code/modules/reta/reta_system.dm b/code/modules/reta/reta_system.dm index ebcfe06d896..51591a20590 100644 --- a/code/modules/reta/reta_system.dm +++ b/code/modules/reta/reta_system.dm @@ -5,7 +5,7 @@ /// Helper function for RETA-specific logging /proc/log_reta(text) - WRITE_LOG(GLOB.reta_log, "[time_stamp()] RETA: [text]") + WRITE_LOG(GLOB.reta_log, "[server_timestamp()] RETA: [text]") log_game("RETA: [text]") /proc/initialize_reta_system() diff --git a/code/modules/shuttle/misc/special.dm b/code/modules/shuttle/misc/special.dm index f8cb0efd116..e1bd0f77b77 100644 --- a/code/modules/shuttle/misc/special.dm +++ b/code/modules/shuttle/misc/special.dm @@ -80,18 +80,14 @@ /obj/structure/table/abductor/wabbajack/Initialize(mapload, obj/structure/table_frame/frame_used, obj/item/stack/stack_used) . = ..() + AddElement(/datum/element/tool_blocker, TOOL_SCREWDRIVER, TOOL_ACT_PRIMARY) + AddElement(/datum/element/tool_blocker, TOOL_WRENCH, TOOL_ACT_PRIMARY) START_PROCESSING(SSobj, src) /obj/structure/table/abductor/wabbajack/Destroy() STOP_PROCESSING(SSobj, src) . = ..() -/obj/structure/table/abductor/wabbajack/screwdriver_act(mob/living/user, obj/item/tool) - return NONE - -/obj/structure/table/abductor/wabbajack/wrench_act(mob/living/user, obj/item/tool) - return NONE - /obj/structure/table/abductor/wabbajack/process() if(isnull(our_statue)) our_statue = locate() in orange(4, src) @@ -186,12 +182,8 @@ COMSIG_ATOM_ENTERED = PROC_REF(on_climbed), ) AddElement(/datum/element/connect_loc, loc_connections) - -/obj/structure/table/wood/shuttle_bar/screwdriver_act(mob/living/user, obj/item/tool) - return NONE - -/obj/structure/table/wood/shuttle_bar/wrench_act(mob/living/user, obj/item/tool) - return NONE + AddElement(/datum/element/tool_blocker, TOOL_SCREWDRIVER) + AddElement(/datum/element/tool_blocker, TOOL_WRENCH) /obj/structure/table/wood/shuttle_bar/proc/on_climbed(datum/source, atom/movable/AM) SIGNAL_HANDLER diff --git a/code/modules/shuttle/mobile_port/shuttle_move_callbacks.dm b/code/modules/shuttle/mobile_port/shuttle_move_callbacks.dm index 987e8e904ac..04d95889f33 100644 --- a/code/modules/shuttle/mobile_port/shuttle_move_callbacks.dm +++ b/code/modules/shuttle/mobile_port/shuttle_move_callbacks.dm @@ -78,6 +78,13 @@ All ShuttleMove procs go here if(rotation) shuttleRotate(rotation, params = ALL) //see shuttle_rotate.dm + + // if we have a lighting object that needs to be updated + if(lighting_object?.needs_update) + lighting_object.update() + lighting_object.needs_update = FALSE + SSlighting.objects_queue -= lighting_object + SEND_SIGNAL(src, COMSIG_TURF_AFTER_SHUTTLE_MOVE, oldT) return TRUE @@ -402,6 +409,9 @@ All ShuttleMove procs go here /************************************Misc move procs************************************/ +/atom/movable/lighting_object/onShuttleMove() + return FALSE + /obj/docking_port/mobile/hypotheticalShuttleMove(rotation, move_mode, obj/docking_port/mobile/moving_dock) . = ..() if(moving_dock == src) diff --git a/code/modules/shuttle/shuttle_consoles/syndicate.dm b/code/modules/shuttle/shuttle_consoles/syndicate.dm index dc1500437a3..07115b52636 100644 --- a/code/modules/shuttle/shuttle_consoles/syndicate.dm +++ b/code/modules/shuttle/shuttle_consoles/syndicate.dm @@ -12,8 +12,9 @@ possible_destinations = "syndicate_away;syndicate_z5;syndicate_ne;syndicate_nw;syndicate_n;syndicate_se;syndicate_sw;syndicate_s;syndicate_custom" resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF -/obj/machinery/computer/shuttle/syndicate/screwdriver_act(mob/living/user, obj/item/I) - return NONE +/obj/machinery/computer/shuttle/syndicate/Initialize(mapload) + . = ..() + AddElement(/datum/element/tool_blocker, TOOL_SCREWDRIVER, TOOL_ACT_PRIMARY) /obj/machinery/computer/shuttle/syndicate/launch_check(mob/user) . = ..() diff --git a/code/modules/spells/spell_types/conjure/ed_swarm.dm b/code/modules/spells/spell_types/conjure/ed_swarm.dm index 3341f3a6aac..0370bc97099 100644 --- a/code/modules/spells/spell_types/conjure/ed_swarm.dm +++ b/code/modules/spells/spell_types/conjure/ed_swarm.dm @@ -4,19 +4,19 @@ desc = "This spell dispenses wizard justice." summon_radius = 3 - summon_type = list(/mob/living/simple_animal/bot/secbot/ed209) + summon_type = list(/mob/living/basic/bot/secbot/ed209) summon_amount = 10 /datum/action/cooldown/spell/conjure/summon_ed_swarm/post_summon(atom/summoned_object, atom/cast_on) - if(!istype(summoned_object, /mob/living/simple_animal/bot/secbot/ed209)) + if(!istype(summoned_object, /mob/living/basic/bot/secbot/ed209)) return - var/mob/living/simple_animal/bot/secbot/ed209/summoned_bot = summoned_object + var/mob/living/basic/bot/secbot/ed209/summoned_bot = summoned_object summoned_bot.name = "Wizard's Justicebot" summoned_bot.security_mode_flags = ~SECBOT_DECLARE_ARRESTS summoned_bot.bot_mode_flags &= ~BOT_MODE_REMOTE_ENABLED summoned_bot.bot_mode_flags |= BOT_COVER_EMAGGED - summoned_bot.projectile = /obj/projectile/beam/laser - summoned_bot.shoot_sound = 'sound/items/weapons/laser.ogg' + summoned_bot.projectile_type = /obj/projectile/beam/laser + summoned_bot.projectile_sound = 'sound/items/weapons/laser.ogg' diff --git a/code/modules/spells/spell_types/right_and_wrong.dm b/code/modules/spells/spell_types/right_and_wrong.dm index 664b99f0cc7..14c5279564d 100644 --- a/code/modules/spells/spell_types/right_and_wrong.dm +++ b/code/modules/spells/spell_types/right_and_wrong.dm @@ -27,7 +27,7 @@ GLOBAL_LIST_INIT(summoned_guns, list( /obj/item/gun/ballistic/automatic/pistol/clandestine/fisher, /obj/item/gun/ballistic/automatic/pistol/deagle, /obj/item/gun/ballistic/automatic/pistol/deagle/regal, - /obj/item/gun/ballistic/automatic/pistol/doorhickey, + /obj/item/gun/ballistic/automatic/pistol/doohickey, /obj/item/gun/ballistic/automatic/pistol/m1911, /obj/item/gun/ballistic/automatic/proto/unrestricted, /obj/item/gun/ballistic/automatic/smartgun, @@ -86,25 +86,42 @@ GLOBAL_LIST_INIT(summoned_magic, list( /obj/item/book/granter/action/spell/charge, /obj/item/book/granter/action/spell/summonitem, /obj/item/book/granter/action/spell/lightningbolt, - /obj/item/gun/magic/wand/nothing, + /obj/item/gun/magic/staff/babel, + /obj/item/gun/magic/staff/door, + /obj/item/gun/magic/staff/healing, + /obj/item/gun/magic/wand/animate, + /obj/item/gun/magic/wand/babel, + /obj/item/gun/magic/wand/bald, /obj/item/gun/magic/wand/death, - /obj/item/gun/magic/wand/resurrection, - /obj/item/gun/magic/wand/polymorph, - /obj/item/gun/magic/wand/teleport, /obj/item/gun/magic/wand/door, /obj/item/gun/magic/wand/fireball, - /obj/item/gun/magic/staff/healing, - /obj/item/gun/magic/staff/door, - /obj/item/gun/magic/staff/babel, + /obj/item/gun/magic/wand/freeze, + /obj/item/gun/magic/wand/hallucination, + /obj/item/gun/magic/wand/levitate, + /obj/item/gun/magic/wand/nothing, + /obj/item/gun/magic/wand/pax, + /obj/item/gun/magic/wand/pizza, + /obj/item/gun/magic/wand/plague, + /obj/item/gun/magic/wand/polymorph, + /obj/item/gun/magic/wand/prank, + /obj/item/gun/magic/wand/rebel, + /obj/item/gun/magic/wand/repulse, + /obj/item/gun/magic/wand/resurrection, + /obj/item/gun/magic/wand/swap, + /obj/item/gun/magic/wand/teleport, + /obj/item/gun/magic/wand/tentacles, + /obj/item/gun/magic/wand/zap, + /obj/item/immortality_talisman, + /obj/item/melee/ghost_sword, /obj/item/scrying, /obj/item/warp_whistle, - /obj/item/immortality_talisman, - /obj/item/melee/ghost_sword)) +)) GLOBAL_LIST_INIT(summoned_special_magic, list( // /obj/item/gun/magic/staff/change, //BUBBERSTATION CHANGE: REMOVES STAFF OF CHANGE. /obj/item/gun/magic/staff/animate, /obj/item/storage/belt/wands/full, + /obj/item/storage/belt/wands/full/discount, /obj/item/antag_spawner/contract, /obj/item/gun/magic/staff/chaos, /obj/item/necromantic_stone)) @@ -119,6 +136,7 @@ GLOBAL_LIST_INIT(summoned_magic_objectives, list( /obj/item/scrying, /obj/item/spellbook, /obj/item/storage/belt/wands/full, + /obj/item/storage/belt/wands/full/discount, /obj/item/warp_whistle)) /* diff --git a/code/modules/spells/spell_types/self/ghostliness.dm b/code/modules/spells/spell_types/self/ghostliness.dm new file mode 100644 index 00000000000..878114fa23f --- /dev/null +++ b/code/modules/spells/spell_types/self/ghostliness.dm @@ -0,0 +1,57 @@ +/datum/action/cooldown/spell/ghostliness + name = "Forsake Body" + desc = "A spell that severs your soul from your body, loosely binding it to the material plane." + button_icon = 'icons/mob/simple/mob.dmi' + button_icon_state = "ghost" + + school = SCHOOL_NECROMANCY + cooldown_time = 1 SECONDS + + invocation = "GHO'AN GHO'AST!" + invocation_type = INVOCATION_SHOUT + spell_requirements = SPELL_REQUIRES_NO_ANTIMAGIC|SPELL_REQUIRES_STATION|SPELL_REQUIRES_MIND + spell_max_level = 1 + +/datum/action/cooldown/spell/ghostliness/can_cast_spell(feedback = TRUE) + . = ..() + if(!.) + return FALSE + + if(!is_valid_target(owner)) + if(feedback) + owner.balloon_alert(owner, "no soul!") + return FALSE + + return TRUE + +/datum/action/cooldown/spell/ghostliness/is_valid_target(atom/cast_on) + return ishuman(cast_on) && !HAS_TRAIT(owner, TRAIT_NO_SOUL) + +/datum/action/cooldown/spell/ghostliness/cast(mob/living/carbon/human/cast_on) + . = ..() + + if(isspirit(cast_on)) + to_chat(cast_on, span_green("You begin to focus on loosening the bonds holding you to the material plane.")) + else + to_chat(cast_on, span_green("You begin to focus on your very being, drawing it out of its corporeal vessel...")) + if(!do_after(cast_on, 5 SECONDS)) + if(isspirit(cast_on)) + to_chat(cast_on, span_warning("Your focus is broken, and you feel your material bindings snap tight once more.")) + else + to_chat(cast_on, span_warning("Your focus is broken, and your soul snaps back into place.")) + return + if(isspirit(cast_on)) + to_chat(cast_on, span_green("You successfully loosen your bonds to the material plane, and can now slip partially out of it.")) + else + to_chat(cast_on, span_danger("As the last trailing filament of your essence ceases intersection with your body, \ + your perspective abruptly snaps to your new, ghostly figure! Your former vessel falls to the ground, vacant and devoid of volition!")) + var/mob/living/carbon/human/soulless_husk = new(cast_on.drop_location()) + soulless_husk.setDir(cast_on.dir) + cast_on.dna.copy_dna(soulless_husk.dna, ALL) + soulless_husk.real_name = cast_on.real_name + soulless_husk.updateappearance(icon_update = TRUE, mutcolor_update = TRUE, mutations_overlay_update = TRUE) + soulless_husk.domutcheck() + ADD_TRAIT(soulless_husk, TRAIT_NO_SOUL, MAGIC_TRAIT) + ADD_TRAIT(soulless_husk, TRAIT_FLOORED, MAGIC_TRAIT) + cast_on.set_species(/datum/species/spirit/ghost) + qdel(src) diff --git a/code/modules/spells/spell_types/shapeshift/shapechange.dm b/code/modules/spells/spell_types/shapeshift/shapechange.dm index dd2597d0097..aabec75e3db 100644 --- a/code/modules/spells/spell_types/shapeshift/shapechange.dm +++ b/code/modules/spells/spell_types/shapeshift/shapechange.dm @@ -17,5 +17,5 @@ /mob/living/basic/mouse, /mob/living/basic/pet/dog/corgi, /mob/living/basic/spider/giant/viper/wizard, - /mob/living/simple_animal/bot/secbot/ed209, + /mob/living/basic/bot/secbot/ed209, ) diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm index 717b379f896..9cd19e026b7 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -285,6 +285,7 @@ if (length(drop_results)) butcher_drops = string_list(drop_results) butcher_drop_cache[type] = butcher_drops + update_limb(TRUE) update_icon_dropped() refresh_bleed_rate() @@ -650,8 +651,7 @@ bodypart_organ.apply_organ_damage(bodypart_organ.maxHealth * 0.5) if(owner) - if(!bodypart_organ.Remove(bodypart_organ.owner)) - continue + bodypart_organ.Remove(bodypart_organ.owner) else if(!bodypart_organ.bodypart_remove(src)) continue @@ -669,10 +669,6 @@ update_icon_dropped() -//Return TRUE to get whatever mob this is in to update health. -/obj/item/bodypart/proc/on_life(seconds_per_tick) - SHOULD_CALL_PARENT(TRUE) - /** * #receive_damage * @@ -1160,6 +1156,8 @@ /obj/item/bodypart/proc/update_limb(dropping_limb = FALSE, is_creating = FALSE) SHOULD_CALL_PARENT(TRUE) + SEND_SIGNAL(src, COMSIG_BODYPART_UPDATED, dropping_limb, is_creating) + if(IS_ORGANIC_LIMB(src)) // Try to add a cached blood type data, we must do it in here because for some reason DNA gets initialized AFTER the mob's limbs are created. // Should be fine as this gets called before all the important stuff happens @@ -1183,7 +1181,7 @@ update_draw_color() if(!is_creating || !owner) - return + return FALSE // There should technically to be an ishuman(owner) check here, but it is absent because no basetype carbons use bodyparts // No, xenos don't actually use bodyparts. Don't ask. @@ -1867,6 +1865,22 @@ return REMOVE_TRAIT(owner, old_trait, bodypart_trait_source) +/// Add a bodyshape to the bodypart, then synchronize with the owner if necessary +/obj/item/bodypart/proc/add_bodyshape(new_shape) + if(bodyshape & new_shape) + return + + bodyshape |= new_shape + owner?.synchronize_bodyshapes() + +/// Remove a bodyshape from the bodypart, then synchronize with the owner if necessary +/obj/item/bodypart/proc/remove_bodyshape(old_shape) + if(!(bodyshape & old_shape)) + return + + bodyshape &= ~old_shape + owner?.synchronize_bodyshapes() + /// Add one or multiple surgical states to the bodypart /obj/item/bodypart/proc/add_surgical_state(new_states) if(!new_states) @@ -1921,3 +1935,34 @@ var/old_state = surgery_state . = ..() update_surgical_state(old_state, surgery_state ^ old_state) + +/// Adds biostate to the limb and ensures surgical states are updated accordingly +/obj/item/bodypart/proc/add_biostate(new_biostate) + if(biological_state & new_biostate) + return + + var/had_skin = LIMB_HAS_SKIN(src) + var/had_bones = LIMB_HAS_BONES(src) + var/had_vessels = LIMB_HAS_VESSELS(src) + + biological_state |= new_biostate + + if(!had_skin && LIMB_HAS_SKIN(src)) + remove_surgical_state(SKINLESS_SURGERY_STATES) + if(!had_bones && LIMB_HAS_BONES(src)) + remove_surgical_state(BONELESS_SURGERY_STATES) + if(!had_vessels && LIMB_HAS_VESSELS(src)) + remove_surgical_state(VESSELLESS_SURGERY_STATES) + +/// Removes biostate from the limb and ensures surgical states are updated accordingly +/obj/item/bodypart/proc/remove_biostate(old_biostate) + if(!(biological_state & old_biostate)) + return + + biological_state &= ~old_biostate + if(!LIMB_HAS_SKIN(src)) + add_surgical_state(SKINLESS_SURGERY_STATES) + if(!LIMB_HAS_BONES(src)) + add_surgical_state(BONELESS_SURGERY_STATES) + if(!LIMB_HAS_VESSELS(src)) + add_surgical_state(VESSELLESS_SURGERY_STATES) diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index 2f7c85d587a..9fdf5e78738 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -24,22 +24,17 @@ if (wounding_type) LAZYSET(limb_owner.body_zone_dismembered_by, body_zone, wounding_type) - if (can_bleed()) - limb_owner.bleed(rand(20, 40)) - drop_limb(dismembered = TRUE) - limb_owner.update_equipment_speed_mods() // Update in case speed affecting item unequipped by dismemberment - var/turf/owner_location = limb_owner.loc - if(wounding_type != WOUND_BURN && istype(owner_location) && can_bleed()) - limb_owner.add_splatter_floor(owner_location) if(QDELETED(src)) //Could have dropped into lava/explosion/chasm/whatever return TRUE if(dam_type == BURN) burn() return TRUE - if (can_bleed()) + + // Assume we had our limb sliced/punched off by this point + if(can_bleed()) limb_owner.bleed(rand(20, 40)) var/direction = pick(GLOB.cardinals) @@ -211,9 +206,7 @@ var/obj/item/lost_cuffs = arm_owner.handcuffed arm_owner.set_handcuffed(null) arm_owner.dropItemToGround(lost_cuffs, force = TRUE) - 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() + arm_owner.hud_used?.update_inventory_slot(ITEM_SLOT_HANDS, held_index) if(arm_owner.num_hands == 0) arm_owner.dropItemToGround(arm_owner.gloves, force = TRUE) arm_owner.update_worn_gloves() //to remove the bloody hands overlay @@ -317,7 +310,7 @@ LAZYREMOVE(wounds, wound) wound.apply_wound(src, TRUE, wound_source = wound.wound_source) - if(new_limb_owner.mob_mood?.has_mood_of_category("dismembered_[body_zone]")) + if(new_limb_owner.mob_mood?.has_mood_of_category("dismembered_[body_zone]") && !(bodypart_flags & BODYPART_STUMP)) new_limb_owner.clear_mood_event("dismembered_[body_zone]") new_limb_owner.add_mood_event("phantom_pain_[body_zone]", /datum/mood_event/reattachment, src) @@ -336,7 +329,7 @@ // behavior within said bodyparts list. We sort it here, as it's the only place we make changes to bodyparts. new_limb_owner.bodyparts = sort_list(new_limb_owner.bodyparts, GLOBAL_PROC_REF(cmp_bodypart_by_body_part_asc)) new_limb_owner.updatehealth() - new_limb_owner.update_body() + new_limb_owner.update_body() // updates lips + hair + eyes new_limb_owner.update_damage_overlays() if(!special) new_limb_owner.hud_used?.update_locked_slots() @@ -380,7 +373,7 @@ sexy_chad.lip_color = lip_color new_head_owner.updatehealth() - new_head_owner.update_body() + new_head_owner.update_body() // updates lips + hair + eyes new_head_owner.update_damage_overlays() /obj/item/bodypart/arm/try_attach_limb(mob/living/carbon/new_arm_owner, special, lazy) diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm index ce5e8c669e8..3a2f4ef01fa 100644 --- a/code/modules/surgery/bodyparts/head.dm +++ b/code/modules/surgery/bodyparts/head.dm @@ -44,10 +44,6 @@ var/hair_color = COLOR_BLACK /// Hair alpha var/hair_alpha = 255 - /// Is the hair currently hidden by something? - var/hair_hidden = FALSE - /// Lazy initialized hashset of all hair mask types that should be applied - var/list/hair_masks ///Facial hair style var/facial_hairstyle = "Shaved" @@ -55,8 +51,6 @@ var/facial_hair_color = COLOR_BLACK ///Facial hair alpha var/facial_hair_alpha = 255 - ///Is the facial hair currently hidden by something? - var/facial_hair_hidden = FALSE /// Gradient styles, if any var/list/gradient_styles @@ -89,15 +83,8 @@ /// Offset to apply to overlays placed on the face var/datum/worn_feature_offset/worn_face_offset - VAR_PROTECTED - /// Draw this head as "debrained" - show_debrained = FALSE - - /// Draw this head as missing eyes - show_eyeless = FALSE - - /// Can this head be dismembered normally? - can_dismember = FALSE + /// Can this head be dismembered normally? + VAR_PROTECTED/can_dismember = FALSE /obj/item/bodypart/head/Initialize(mapload) . = ..() @@ -122,6 +109,13 @@ return null return list(species.skinned_type = 1) +/obj/item/bodypart/head/animate_atom_living(mob/living/owner) + var/mob/living/basic/animated = ..() + animated.attack_vis_effect = ATTACK_EFFECT_BITE + animated.attack_verb_continuous = "bites" + animated.attack_verb_simple = "bite" + return animated + /obj/item/bodypart/head/grind_results() return null @@ -181,50 +175,25 @@ /obj/item/bodypart/head/update_limb(dropping_limb, is_creating) . = ..() - if(!isnull(owner)) + if(isnull(owner)) + return + if(is_husked) + ADD_TRAIT(src, TRAIT_DISFIGURED, HUSK_TRAIT) + else + REMOVE_TRAIT(src, TRAIT_DISFIGURED, HUSK_TRAIT) + if(is_creating) real_name = owner.real_name - if(is_husked) - ADD_TRAIT(src, TRAIT_DISFIGURED, HUSK_TRAIT) - else - REMOVE_TRAIT(src, TRAIT_DISFIGURED, HUSK_TRAIT) - update_hair_and_lips(dropping_limb, is_creating) - -// Ensures putting organs in and removing organs from our head always updates the limb -/obj/item/bodypart/head/Entered(atom/movable/arrived, atom/old_loc, list/atom/old_locs) - . = ..() - if(isorgan(arrived) && !ismob(loc)) - addtimer(CALLBACK(src, PROC_REF(update_head_on_organ_movement)), 1, TIMER_UNIQUE|TIMER_DELETE_ME) - -/obj/item/bodypart/head/Exited(atom/movable/gone, direction) - . = ..() - if(isorgan(gone) && !ismob(loc)) - addtimer(CALLBACK(src, PROC_REF(update_head_on_organ_movement)), 1, TIMER_UNIQUE|TIMER_DELETE_ME) - -/obj/item/bodypart/head/proc/update_head_on_organ_movement() - update_limb() - update_icon_dropped() + copy_appearance_from(owner) ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/obj/item/bodypart/head/get_limb_icon(dropped, mob/living/carbon/update_on) +/obj/item/bodypart/head/get_limb_icon(dropped) . = ..() - . += get_hair_and_lips_icon(dropped) - // We need to get the eyes if we are dropped (ugh) - if(!dropped) - return + if(dropped) // These overlays are applied as standing overlays so we only need them if dropped + . += get_hair_overlays(dropped) + . += get_eye_overlays(dropped) - var/obj/item/organ/eyes/eyes = locate(/obj/item/organ/eyes) in src - if(!eyes) - if (!(head_flags & HEAD_EYEHOLES)) - return - var/image/no_eyes = image('icons/mob/human/human_eyes.dmi', "eyes_missing", -EYES_LAYER, SOUTH) - worn_face_offset?.apply_offset(no_eyes) - . += no_eyes - return - - if(head_flags & HEAD_EYESPRITES) - for (var/mutable_appearance/overlay as anything in eyes.generate_body_overlay(null, src)) - . += image(overlay, dir = SOUTH) + . += get_lips_overlays(dropped) /obj/item/bodypart/head/get_voice(add_id_name) return "The head of [get_face_name()]" diff --git a/code/modules/surgery/bodyparts/head_hair_and_lips.dm b/code/modules/surgery/bodyparts/head_hair_and_lips.dm index 45025158b90..65b87c30150 100644 --- a/code/modules/surgery/bodyparts/head_hair_and_lips.dm +++ b/code/modules/surgery/bodyparts/head_hair_and_lips.dm @@ -1,49 +1,3 @@ -#define SET_OVERLAY_VALUE(overlay,variable,value) if(overlay) overlay.variable = value - -/// Part of `update_limb()`, basically does all the head specific icon stuff. -/obj/item/bodypart/head/proc/update_hair_and_lips(dropping_limb, is_creating) - var/mob/living/carbon/human/human_head_owner = owner - - //HIDDEN CHECKS START - hair_hidden = FALSE - facial_hair_hidden = FALSE - LAZYNULL(hair_masks) - if(human_head_owner) - for(var/obj/item/worn_item in human_head_owner.get_equipped_items(INCLUDE_ABSTRACT)) - if(worn_item.hair_mask) - LAZYSET(hair_masks, worn_item.hair_mask, TRUE) - hair_hidden = !!(human_head_owner.obscured_slots & HIDEHAIR) - facial_hair_hidden = !!(human_head_owner.obscured_slots & HIDEFACIALHAIR) - if(is_husked) - hair_hidden = TRUE - facial_hair_hidden = TRUE - //HIDDEN CHECKS END - - if(owner) - if(!hair_hidden && !owner.get_organ_slot(ORGAN_SLOT_BRAIN) && !HAS_TRAIT(owner, TRAIT_NO_DEBRAIN_OVERLAY)) - show_debrained = TRUE - else - show_debrained = FALSE - - if(!owner.get_organ_slot(ORGAN_SLOT_EYES)) - show_eyeless = TRUE - else - show_eyeless = FALSE - else - if(!hair_hidden && !(locate(/obj/item/organ/brain) in src)) - show_debrained = TRUE - else - show_debrained = FALSE - - if(!(locate(/obj/item/organ/eyes) in src)) - show_eyeless = TRUE - else - show_eyeless = FALSE - - if(!is_creating || !owner) - return - copy_appearance_from(human_head_owner) - /obj/item/bodypart/head/proc/copy_appearance_from(mob/living/carbon/human/target, overwrite_eyes = FALSE) var/datum/species/target_species = target.dna.species @@ -77,120 +31,145 @@ skin_tone = "" species_color = "" -/obj/item/bodypart/head/proc/get_hair_and_lips_icon(dropped) - SHOULD_CALL_PARENT(TRUE) - RETURN_TYPE(/list) +/// Returns a list of all overlays associated with the lips +/obj/item/bodypart/head/proc/get_lips_overlays(dropped) . = list() + if(!lip_style || is_husked || is_invisible || (owner?.obscured_slots & HIDEFACIALHAIR) || !(head_flags & HEAD_LIPS)) + return . - var/atom/location = loc || owner || src - var/image_dir = null - if (dropped) - image_dir = SOUTH + var/image/lip_overlay = image('icons/mob/human/human_face.dmi', "lips_[lip_style]", -BODY_LAYER, dir = (dropped ? SOUTH : null)) + lip_overlay.color = lip_color + worn_face_offset?.apply_offset(lip_overlay) + . += lip_overlay + return . - var/datum/sprite_accessory/sprite_accessory - if(!facial_hair_hidden && lip_style && (head_flags & HEAD_LIPS)) - //not a sprite accessory, don't ask - //Overlay - var/image/lip_overlay = image('icons/mob/human/human_face.dmi', "lips_[lip_style]", -BODY_LAYER, dir = image_dir) - lip_overlay.color = lip_color - //Offsets - worn_face_offset?.apply_offset(lip_overlay) - . += lip_overlay +/// Returns a list of all hair/facial hair related overlays, or alternatively the debrained overlay if applicable +/obj/item/bodypart/head/proc/get_hair_overlays(dropped) + . = list() + var/hair_hidden = is_husked || is_invisible || (owner?.obscured_slots & HIDEHAIR) + var/facial_hair_hidden = is_husked || is_invisible || (owner?.obscured_slots & HIDEFACIALHAIR) - var/image/facial_hair_overlay - if(!facial_hair_hidden && facial_hairstyle && (head_flags & HEAD_FACIAL_HAIR)) - sprite_accessory = SSaccessories.facial_hairstyles_list[facial_hairstyle] - if(sprite_accessory) - //Overlay - facial_hair_overlay = image(sprite_accessory.icon, sprite_accessory.icon_state, -HAIR_LAYER, dir = image_dir) - facial_hair_overlay.alpha = facial_hair_alpha - //Emissive blocker - if(blocks_emissive != EMISSIVE_BLOCK_NONE) - var/mutable_appearance/em_block = emissive_blocker(facial_hair_overlay.icon, facial_hair_overlay.icon_state, location, alpha = facial_hair_alpha) - if (dropped) - em_block = image(em_block, dir = SOUTH) - facial_hair_overlay.overlays += em_block - //Offsets - worn_face_offset?.apply_offset(facial_hair_overlay) - . += facial_hair_overlay - //Gradients - var/facial_hair_gradient_style = get_hair_gradient_style(GRADIENT_FACIAL_HAIR_KEY) - if(facial_hair_gradient_style != "None") - var/facial_hair_gradient_color = get_hair_gradient_color(GRADIENT_FACIAL_HAIR_KEY) - var/image/facial_hair_gradient_overlay = get_gradient_overlay(icon(sprite_accessory.icon, sprite_accessory.icon_state), -HAIR_LAYER, SSaccessories.facial_hair_gradients_list[facial_hair_gradient_style], facial_hair_gradient_color, dropped) - . += facial_hair_gradient_overlay + if(!facial_hair_hidden && (head_flags & HEAD_FACIAL_HAIR)) + . += get_base_facial_hair_overlays(dropped) - var/list/all_hair_overlays = list() - if(!(show_debrained && (head_flags & HEAD_DEBRAIN)) && !hair_hidden && hairstyle && (head_flags & HEAD_HAIR)) - var/datum/sprite_accessory/hair/hair_sprite_accessory = SSaccessories.hairstyles_list[hairstyle] - if(hair_sprite_accessory) - //Hair masks - var/icon/base_icon = icon(hair_sprite_accessory.getCachedIcon(hair_masks)) - //Overlay - all_hair_overlays += image(base_icon, layer=-HAIR_LAYER, dir = image_dir) - //If we have any hair appendages (ponytails, etc.) sticking out on a particular side, we need to add an additional hair layer to go above hats/helmets for the sides they stick out on - if(LAZYLEN(hair_sprite_accessory.hair_appendages_outer)) - var/strictly_masked_zones = NONE - for(var/datum/hair_mask/mask as anything in hair_masks) - strictly_masked_zones |= mask.strict_coverage_zones - for(var/appendage_icon_state in hair_sprite_accessory.hair_appendages_outer) - var/appendage_zone = hair_sprite_accessory.hair_appendages_outer[appendage_icon_state] - if(!(appendage_zone & strictly_masked_zones)) // if there are no strict masks in this zone - all_hair_overlays += image(hair_sprite_accessory.icon, icon_state=appendage_icon_state, layer=-OUTER_HAIR_LAYER, dir = image_dir) - for(var/image/hair_overlay as anything in all_hair_overlays) - hair_overlay.alpha = hair_alpha - hair_overlay.pixel_z = hair_sprite_accessory.y_offset - // SKYRAT EDIT ADDITION - Species hair offset - if(LAZYFIND(owner?.dna?.species?.offset_features, OFFSET_HAIR)) - hair_overlay.pixel_w += owner.dna.species.offset_features[OFFSET_HAIR][INDEX_X] - hair_overlay.pixel_z += owner.dna.species.offset_features[OFFSET_HAIR][INDEX_Y] - // SKYRAT EDIT ADDITION END - //Emissive blocker - if(blocks_emissive != EMISSIVE_BLOCK_NONE) - var/mutable_appearance/em_block = emissive_blocker(hair_overlay.icon, hair_overlay.icon_state, location, alpha = hair_alpha) - if (dropped) - em_block = image(em_block, dir = SOUTH) - hair_overlay.overlays += em_block - //Offsets - worn_face_offset?.apply_offset(hair_overlay) - . += hair_overlay - //Gradients - var/hair_gradient_style = get_hair_gradient_style(GRADIENT_HAIR_KEY) - if(hair_gradient_style != "None") - var/hair_gradient_color = get_hair_gradient_color(GRADIENT_HAIR_KEY) - var/image/hair_gradient_overlay = get_gradient_overlay(base_icon, hair_overlay.layer, SSaccessories.hair_gradients_list[hair_gradient_style], hair_gradient_color, dropped) - hair_gradient_overlay.pixel_z = hair_sprite_accessory.y_offset - // SKYRAT EDIT ADDITION - Species hair offset - if(LAZYFIND(owner?.dna?.species?.offset_features, OFFSET_HAIR)) - hair_gradient_overlay.pixel_w += owner.dna.species.offset_features[OFFSET_HAIR][INDEX_X] - hair_gradient_overlay.pixel_z += owner.dna.species.offset_features[OFFSET_HAIR][INDEX_Y] - // SKYRAT EDIT ADDITION END - . += hair_gradient_overlay - - if(show_debrained && (head_flags & HEAD_DEBRAIN)) - . += get_debrain_overlay(dropped) - - if(show_eyeless && (head_flags & HEAD_EYEHOLES)) - . += get_eyeless_overlay(dropped) - - //HAIR COLOR START - if(override_hair_color) - SET_OVERLAY_VALUE(facial_hair_overlay, color, override_hair_color) - for(var/image/hair_overlay as anything in all_hair_overlays) - SET_OVERLAY_VALUE(hair_overlay, color, override_hair_color) - else if(fixed_hair_color) - SET_OVERLAY_VALUE(facial_hair_overlay, color, fixed_hair_color) - for(var/image/hair_overlay as anything in all_hair_overlays) - SET_OVERLAY_VALUE(hair_overlay, color, fixed_hair_color) - else - SET_OVERLAY_VALUE(facial_hair_overlay, color, facial_hair_color) - for(var/image/hair_overlay as anything in all_hair_overlays) - SET_OVERLAY_VALUE(hair_overlay, color, hair_color) - //HAIR COLOR END + if(!hair_hidden) + var/obj/item/organ/brain/brain = locate() in src + if(QDELETED(brain) && (head_flags & HEAD_DEBRAIN)) + . += get_debrain_overlay(dropped) + else if(head_flags & HEAD_HAIR) + . += get_base_hair_overlays(dropped) return . -#undef SET_OVERLAY_VALUE +/// Used in constructing the hair overlays - handles just facial hair +/obj/item/bodypart/head/proc/get_base_facial_hair_overlays(dropped) + PRIVATE_PROC(TRUE) + . = list() + var/datum/sprite_accessory/facial_hair/sprite_accessory = SSaccessories.facial_hairstyles_list[facial_hairstyle] + if(!sprite_accessory || sprite_accessory.icon_state == SPRITE_ACCESSORY_NONE) + return . + + var/atom/location = loc || owner || src + var/image_dir = dropped ? SOUTH : null + + // Overlay + var/image/facial_hair_overlay = image(sprite_accessory.icon, sprite_accessory.icon_state, -HAIR_LAYER, dir = image_dir) + facial_hair_overlay.alpha = facial_hair_alpha + set_overlay_hair_color(facial_hair_overlay, facial_hair_color) + // Emissive blocker + if(blocks_emissive != EMISSIVE_BLOCK_NONE) + var/mutable_appearance/em_block = emissive_blocker(facial_hair_overlay.icon, facial_hair_overlay.icon_state, location, alpha = facial_hair_alpha) + if (dropped) + em_block = image(em_block, dir = SOUTH) + facial_hair_overlay.overlays += em_block + + //Offsets + worn_face_offset?.apply_offset(facial_hair_overlay) + . += facial_hair_overlay + + //Gradients + var/facial_hair_gradient_style = get_hair_gradient_style(GRADIENT_FACIAL_HAIR_KEY) + if(facial_hair_gradient_style != SPRITE_ACCESSORY_NONE) + var/facial_hair_gradient_color = get_hair_gradient_color(GRADIENT_FACIAL_HAIR_KEY) + var/image/facial_hair_gradient_overlay = get_gradient_overlay(icon(sprite_accessory.icon, sprite_accessory.icon_state), -HAIR_LAYER, SSaccessories.facial_hair_gradients_list[facial_hair_gradient_style], facial_hair_gradient_color, dropped) + . += facial_hair_gradient_overlay + + return . + +/// Used in constructing the hair overlays - handles just the hair on top of the head +/obj/item/bodypart/head/proc/get_base_hair_overlays(dropped) + PRIVATE_PROC(TRUE) + . = list() + var/datum/sprite_accessory/hair/hair_sprite_accessory = SSaccessories.hairstyles_list[hairstyle] + if(!hair_sprite_accessory || hair_sprite_accessory.icon_state == SPRITE_ACCESSORY_NONE) + return . + + var/atom/location = loc || owner || src + var/image_dir = dropped ? SOUTH : null + + var/list/all_hair_overlays = list() + // Hair masks + var/icon/base_icon = icon(hair_sprite_accessory.getCachedIcon(owner?.hair_masks)) + // Overlay + all_hair_overlays += image(base_icon, layer = -HAIR_LAYER, dir = image_dir) + // If we have any hair appendages (ponytails, etc.) sticking out on a particular side, + // we need to add an additional hair layer to go above hats/helmets for the sides they stick out on + if(LAZYLEN(hair_sprite_accessory.hair_appendages_outer)) + var/strictly_masked_zones = NONE + for(var/datum/hair_mask/mask as anything in owner?.hair_masks) + strictly_masked_zones |= mask.strict_coverage_zones + for(var/appendage_icon_state in hair_sprite_accessory.hair_appendages_outer) + var/appendage_zone = hair_sprite_accessory.hair_appendages_outer[appendage_icon_state] + if(!(appendage_zone & strictly_masked_zones)) // if there are no strict masks in this zone + all_hair_overlays += image(hair_sprite_accessory.icon, icon_state = appendage_icon_state, layer = -OUTER_HAIR_LAYER, dir = image_dir) + + for(var/image/hair_overlay as anything in all_hair_overlays) + set_overlay_hair_color(hair_overlay, hair_color) + hair_overlay.alpha = hair_alpha + hair_overlay.pixel_z = hair_sprite_accessory.y_offset + // Emissive blocker + if(blocks_emissive != EMISSIVE_BLOCK_NONE) + var/mutable_appearance/em_block = emissive_blocker(hair_overlay.icon, hair_overlay.icon_state, location, alpha = hair_alpha) + if (dropped) + em_block = image(em_block, dir = SOUTH) + hair_overlay.overlays += em_block + // Offsets + worn_face_offset?.apply_offset(hair_overlay) + . += hair_overlay + // Gradients + var/hair_gradient_style = get_hair_gradient_style(GRADIENT_HAIR_KEY) + if(hair_gradient_style != SPRITE_ACCESSORY_NONE) + var/hair_gradient_color = get_hair_gradient_color(GRADIENT_HAIR_KEY) + var/image/hair_gradient_overlay = get_gradient_overlay(base_icon, hair_overlay.layer, SSaccessories.hair_gradients_list[hair_gradient_style], hair_gradient_color, dropped) + hair_gradient_overlay.pixel_z = hair_sprite_accessory.y_offset + . += hair_gradient_overlay + + return . + +/// Helper for setting hair color of an overlay appropriately +/obj/item/bodypart/head/proc/set_overlay_hair_color(image/hair_overlay, hair_color_to_use = src.hair_color) + PRIVATE_PROC(TRUE) + if(override_hair_color) + hair_overlay.color = override_hair_color + else if(fixed_hair_color) + hair_overlay.color = fixed_hair_color + else + hair_overlay.color = hair_color_to_use + +/// Returns a list of all eye related overlays, or an eyeless overlay if applicable +/obj/item/bodypart/head/proc/get_eye_overlays(dropped) + . = list() + + var/obj/item/organ/eyes/eyes = locate() in src + if(QDELETED(eyes)) + if(head_flags & HEAD_EYEHOLES) + . += get_eyeless_overlay(dropped) + return . + + if(head_flags & HEAD_EYESPRITES) + . += eyes.generate_body_overlay(src) + + return . /// Returns an appropriate debrained overlay /obj/item/bodypart/head/proc/get_debrain_overlay(dropped) @@ -261,7 +240,7 @@ hopefully_a_head?.stored_lipstick_trait = apply_trait if(update) - update_body_parts() + update_body() // lips is done as a body layer /** * A wrapper for [mob/living/carbon/human/proc/update_lips] that sets the lip style and color to null. @@ -289,7 +268,7 @@ my_head?.hairstyle = new_style if(update) - update_body_parts() + update_hair() /** * Set the hair color of a human. @@ -310,7 +289,7 @@ my_head?.hair_color = hex_string if(update) - update_body_parts() + update_hair() /** * Get the hair gradient style of a human. @@ -362,7 +341,7 @@ LAZYSET(my_head.gradient_styles, GRADIENT_HAIR_KEY, new_style) if(update) - update_body_parts() + update_hair() /** * Get the hair gradient color of a human. @@ -416,7 +395,7 @@ LAZYSET(my_head.gradient_colors, GRADIENT_HAIR_KEY, new_color) if(update) - update_body_parts() + update_hair() /** * Set the facial hair style of a human. @@ -432,7 +411,7 @@ my_head?.facial_hairstyle = new_style if(update) - update_body_parts() + update_hair() /** * Set the facial hair color of a human. @@ -453,7 +432,7 @@ my_head?.facial_hair_color = hex_string if(update) - update_body_parts() + update_hair() /** * Set the facial hair gradient style of a human. @@ -472,7 +451,7 @@ LAZYSET(my_head.gradient_styles, GRADIENT_FACIAL_HAIR_KEY, new_style) if(update) - update_body_parts() + update_hair() /** * Set the facial hair gradient color of a human. @@ -491,4 +470,4 @@ LAZYSET(my_head.gradient_colors, GRADIENT_FACIAL_HAIR_KEY, new_color) if(update) - update_body_parts() + update_hair() diff --git a/code/modules/surgery/bodyparts/helpers.dm b/code/modules/surgery/bodyparts/helpers.dm index 258162453a7..c3e8319120d 100644 --- a/code/modules/surgery/bodyparts/helpers.dm +++ b/code/modules/surgery/bodyparts/helpers.dm @@ -284,17 +284,10 @@ all_limb_flags |= organ.external_bodyshapes all_limb_flags |= limb.bodyshape - bodyshape = all_limb_flags + if(obscured_slots & HIDESNOUT) + all_limb_flags &= ~BODYSHAPE_SNOUTED -/// Get all bodyshapes but filter out bodyshapes that are currently being hidden -/mob/living/carbon/proc/get_active_bodyshapes() - var/active_shapes = bodyshape - // future todo: both of these are state based, maybe we can just remove relevant bodyshapes directly. would remove the need for this proc - if((active_shapes & BODYSHAPE_DIGITIGRADE) && is_digitigrade_squished()) - active_shapes &= ~BODYSHAPE_DIGITIGRADE - if((active_shapes & BODYSHAPE_SNOUTED) && (obscured_slots & HIDESNOUT)) - active_shapes &= ~BODYSHAPE_SNOUTED - return active_shapes + bodyshape = all_limb_flags /proc/skintone2hex(skin_tone) . = 0 diff --git a/code/modules/surgery/bodyparts/parts.dm b/code/modules/surgery/bodyparts/parts.dm index 9b0f56c6a58..6c52f99300d 100644 --- a/code/modules/surgery/bodyparts/parts.dm +++ b/code/modules/surgery/bodyparts/parts.dm @@ -207,12 +207,7 @@ old_owner.on_lost_hand(src) if(interaction_modifier != 0 || click_cd_modifier != 1) old_owner.remove_status_effect(/datum/status_effect/arm_speed_penalty, held_index) - - if(!old_owner.hud_used) - return - - var/atom/movable/screen/inventory/hand/hand = old_owner.hud_used.hand_slots[held_index] - hand?.update_appearance() + old_owner.hud_used?.update_inventory_slot(ITEM_SLOT_HANDS, held_index) /// We need to add hand hud items and appearance, so do that here /obj/item/bodypart/arm/apply_ownership(mob/living/carbon/new_owner) @@ -226,12 +221,7 @@ new_owner.on_added_hand(src, held_index) if(interaction_modifier != 0 || click_cd_modifier != 1) new_owner.apply_status_effect(/datum/status_effect/arm_speed_penalty, held_index, interaction_modifier, click_cd_modifier) - - if(!new_owner.hud_used) - return - - var/atom/movable/screen/inventory/hand/hand = new_owner.hud_used.hand_slots[held_index] - hand?.update_appearance() + new_owner.hud_used?.update_inventory_slot(ITEM_SLOT_HANDS, held_index) /obj/item/bodypart/arm/set_disabled(new_disabled) . = ..() @@ -247,10 +237,14 @@ owner.dropItemToGround(owner.get_item_for_held_index(held_index)) else if(!bodypart_disabled) owner.set_usable_hands(owner.usable_hands + 1) + owner.hud_used?.update_inventory_slot(ITEM_SLOT_HANDS, held_index) - if(owner.hud_used) - var/atom/movable/screen/inventory/hand/hand_screen_object = owner.hud_used.hand_slots[held_index] - hand_screen_object?.update_appearance() +/obj/item/bodypart/arm/animate_atom_living(mob/living/owner) + var/mob/living/basic/slapper = ..() + slapper.attack_vis_effect = ATTACK_EFFECT_PUNCH + slapper.attack_verb_continuous = "punches" + slapper.attack_verb_simple = "punch" + return slapper /datum/status_effect/arm_speed_penalty id = "arm_speed_penalty" @@ -539,6 +533,13 @@ else if(!bodypart_disabled) owner.set_usable_legs(owner.usable_legs + 1) +/obj/item/bodypart/leg/animate_atom_living(mob/living/owner) + var/mob/living/basic/kicker = ..() + kicker.attack_vis_effect = ATTACK_EFFECT_KICK + kicker.attack_verb_continuous = "kicks" + kicker.attack_verb_simple = "kick" + return kicker + /obj/item/bodypart/leg/apply_ownership(mob/living/carbon/new_owner) . = ..() if(speed_modifier) diff --git a/code/modules/surgery/bodyparts/species_parts/ghost_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/ghost_bodyparts.dm index f3247ab84dc..8fd9913f6d3 100644 --- a/code/modules/surgery/bodyparts/species_parts/ghost_bodyparts.dm +++ b/code/modules/surgery/bodyparts/species_parts/ghost_bodyparts.dm @@ -27,6 +27,11 @@ wing_types = null butcher_replacement = null +//slightly different sprite meant to differentiate spirit from ghost. +/obj/item/bodypart/chest/ghost/spirit + icon_state = "spirit_chest" + limb_id = SPECIES_SPIRIT + /obj/item/bodypart/arm/left/ghost icon = 'icons/mob/human/species/ghost.dmi' icon_static = 'icons/mob/human/species/ghost.dmi' diff --git a/code/modules/surgery/bodyparts/species_parts/lizard_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/lizard_bodyparts.dm index 45889011818..00858221c05 100644 --- a/code/modules/surgery/bodyparts/species_parts/lizard_bodyparts.dm +++ b/code/modules/surgery/bodyparts/species_parts/lizard_bodyparts.dm @@ -51,50 +51,26 @@ icon_greyscale = 'icons/mob/human/species/lizard/bodyparts.dmi' limb_id = SPECIES_LIZARD -/// Checks if this mob is wearing anything that does not have a valid sprite set for digitigrade legs -/// (In other words, is the mob's digitigrade body squished by its clothing?) -/mob/living/carbon/proc/is_digitigrade_squished() - return FALSE - -/mob/living/carbon/human/is_digitigrade_squished() - var/obj/item/clothing/shoes/worn_shoes = shoes - var/obj/item/clothing/under/worn_suit = wear_suit - var/obj/item/clothing/under/worn_uniform = w_uniform - - var/uniform_compatible = isnull(worn_uniform) \ - || (worn_uniform.supports_variations_flags & DIGITIGRADE_VARIATIONS) \ - || !(worn_uniform.body_parts_covered & LEGS) \ - || (obscured_slots & HIDEJUMPSUIT) // If suit hides our jumpsuit, it doesn't matter if it squishes - - var/suit_compatible = isnull(worn_suit) \ - || (worn_suit.supports_variations_flags & DIGITIGRADE_VARIATIONS) \ - || !(worn_suit.body_parts_covered & LEGS) - - var/shoes_compatible = isnull(worn_shoes) \ - || (worn_shoes.supports_variations_flags & DIGITIGRADE_VARIATIONS) - - return !uniform_compatible || !suit_compatible || !shoes_compatible - /obj/item/bodypart/leg/left/digitigrade icon_greyscale = 'icons/mob/human/species/lizard/bodyparts.dmi' limb_id = BODYPART_ID_DIGITIGRADE species_id = SPECIES_LIZARD - bodyshape = BODYSHAPE_HUMANOID | BODYSHAPE_DIGITIGRADE + bodyshape = BODYSHAPE_HUMANOID footprint_sprite = FOOTPRINT_SPRITE_CLAWS footstep_type = FOOTSTEP_MOB_CLAW -/obj/item/bodypart/leg/left/digitigrade/update_limb(dropping_limb = FALSE, is_creating = FALSE) +/obj/item/bodypart/leg/left/digitigrade/Initialize(mapload) . = ..() - limb_id = owner?.is_digitigrade_squished() ? SPECIES_LIZARD : BODYPART_ID_DIGITIGRADE + AddComponent(/datum/component/digitigrade_limb, SPECIES_LIZARD, initial(limb_id)) /obj/item/bodypart/leg/right/digitigrade icon_greyscale = 'icons/mob/human/species/lizard/bodyparts.dmi' limb_id = BODYPART_ID_DIGITIGRADE species_id = SPECIES_LIZARD - bodyshape = BODYSHAPE_HUMANOID | BODYSHAPE_DIGITIGRADE + bodyshape = BODYSHAPE_HUMANOID footprint_sprite = FOOTPRINT_SPRITE_CLAWS footstep_type = FOOTSTEP_MOB_CLAW -/obj/item/bodypart/leg/right/digitigrade/update_limb(dropping_limb = FALSE, is_creating = FALSE) +/obj/item/bodypart/leg/right/digitigrade/Initialize(mapload) . = ..() - limb_id = owner?.is_digitigrade_squished() ? SPECIES_LIZARD : BODYPART_ID_DIGITIGRADE + AddComponent(/datum/component/digitigrade_limb, SPECIES_LIZARD, initial(limb_id)) diff --git a/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm index 5803a5f57be..b5359c98f77 100644 --- a/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm +++ b/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm @@ -481,10 +481,6 @@ . = ..() AddElement(/datum/element/blood_limb_overlay) -/obj/item/bodypart/leg/left/skeleton/nonfunctional/update_limb(dropping_limb = FALSE, is_creating = FALSE) - . = ..() - limb_id = ((bodyshape & BODYSHAPE_DIGITIGRADE) && owner?.is_digitigrade_squished()) ? initial(limb_id) : "[initial(limb_id)]_[BODYPART_ID_DIGITIGRADE]" - /obj/item/bodypart/leg/right/skeleton/nonfunctional limb_id = BODYPART_ID_BONE disabling_threshold_percentage = 0 @@ -493,10 +489,6 @@ . = ..() AddElement(/datum/element/blood_limb_overlay) -/obj/item/bodypart/leg/right/skeleton/nonfunctional/update_limb(dropping_limb = FALSE, is_creating = FALSE) - . = ..() - limb_id = ((bodyshape & BODYSHAPE_DIGITIGRADE) && owner?.is_digitigrade_squished()) ? initial(limb_id) : "[initial(limb_id)]_[BODYPART_ID_DIGITIGRADE]" - ///MUSHROOM /obj/item/bodypart/head/mushroom limb_id = SPECIES_MUSHROOM diff --git a/code/modules/surgery/organs/external/_visual_organs.dm b/code/modules/surgery/organs/external/_visual_organs.dm index b11efd28289..953332b338b 100644 --- a/code/modules/surgery/organs/external/_visual_organs.dm +++ b/code/modules/surgery/organs/external/_visual_organs.dm @@ -150,7 +150,32 @@ Unlike normal organs, we're actually inside a persons limbs at all times feature_key = FEATURE_FRILLS /datum/bodypart_overlay/mutant/frills/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner, mob/living/carbon/owner, is_husked = FALSE) - return ..() && !(bodypart_owner.owner?.obscured_slots & HIDEEARS) + return ..() && !(bodypart_owner.owner?.obscured_slots & HIDEHAIR) + +/datum/bodypart_overlay/mutant/frills/generate_icon_cache(obj/item/bodypart/limb) + . = ..() + if(LAZYLEN(limb?.owner?.hair_masks)) + . += jointext(limb.owner.hair_masks, ",") + +/datum/bodypart_overlay/mutant/frills/get_image(image_layer, obj/item/bodypart/limb) + if(!LAZYLEN(limb?.owner?.hair_masks)) + return ..() + + var/list/hair_masks_to_use = limb.owner.hair_masks + var/icon_state_to_use = build_icon_state(image_layer, limb) + var/frill_cache_key = "[sprite_datum.type]-[icon_state_to_use]-[jointext(hair_masks_to_use, ",")]" + var/static/list/cached_frill_icons + var/icon/cached_icon = LAZYACCESS(cached_frill_icons, frill_cache_key) + if(isnull(cached_icon)) + cached_icon = icon(sprite_datum.icon, build_icon_state(image_layer, limb)) + for(var/datum/hair_mask/mask as anything in hair_masks_to_use) + cached_icon.Blend(icon(mask::icon, mask::icon_state), ICON_ADD) + LAZYSET(cached_frill_icons, frill_cache_key, cached_icon) + + var/mutable_appearance/uncached_appearance = mutable_appearance(cached_icon, layer = image_layer) + if(sprite_datum.center) + center_image(uncached_appearance, sprite_datum.dimension_x, sprite_datum.dimension_y) + return uncached_appearance ///Guess what part of the lizard this is? /obj/item/organ/snout diff --git a/code/modules/surgery/organs/external/wings/functional_wings.dm b/code/modules/surgery/organs/external/wings/functional_wings.dm index e883fd69039..2bf1a1aa3b8 100644 --- a/code/modules/surgery/organs/external/wings/functional_wings.dm +++ b/code/modules/surgery/organs/external/wings/functional_wings.dm @@ -188,7 +188,7 @@ feature_key = initial(feature_key) set_appearance_from_name(sprite_datum.name) -/datum/bodypart_overlay/mutant/wings/functional/generate_icon_cache() +/datum/bodypart_overlay/mutant/wings/functional/generate_icon_cache(obj/item/bodypart/limb) . = ..() . += wings_open ? "open" : "closed" diff --git a/code/modules/surgery/organs/internal/appendix/_appendix.dm b/code/modules/surgery/organs/internal/appendix/_appendix.dm index 767be5214b7..e1c959891bb 100644 --- a/code/modules/surgery/organs/internal/appendix/_appendix.dm +++ b/code/modules/surgery/organs/internal/appendix/_appendix.dm @@ -15,6 +15,7 @@ now_failing = span_warning("An explosion of pain erupts in your lower right abdomen!") now_fixed = span_info("The pain in your abdomen has subsided.") + visual = FALSE var/inflamation_stage = 0 diff --git a/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm b/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm index d3991d7aa99..f3833f0b491 100644 --- a/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm +++ b/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm @@ -5,6 +5,7 @@ abstract_type = /obj/item/organ/cyberimp organ_flags = ORGAN_ROBOTIC failing_desc = "seems to be broken." + visual = FALSE /// icon of the bodypart overlay we're going to be applying to our owner var/aug_icon = 'icons/mob/human/species/misc/bodypart_overlay_augmentations.dmi' /// icon_state of the bodypart overlay we're going to be applying to our owner @@ -17,11 +18,12 @@ /obj/item/organ/cyberimp/Initialize(mapload) . = ..() if (aug_overlay) + visual = TRUE bodypart_aug = new(src) /obj/item/organ/cyberimp/Destroy() - QDEL_NULL(bodypart_aug) - return ..() + . = ..() + QDEL_NULL(bodypart_aug) // Do this after Remove() has done its thing, otherwise on_bodypart_remove() will not properly remove the overlay /obj/item/organ/cyberimp/proc/get_overlay_state() return aug_overlay @@ -56,7 +58,7 @@ implant = null return ..() -/datum/bodypart_overlay/augment/generate_icon_cache() +/datum/bodypart_overlay/augment/generate_icon_cache(obj/item/bodypart/limb) . = ..() . += implant.get_overlay_state() diff --git a/code/modules/surgery/organs/internal/ears/_ears.dm b/code/modules/surgery/organs/internal/ears/_ears.dm index beaca05b039..18599b5e7a6 100644 --- a/code/modules/surgery/organs/internal/ears/_ears.dm +++ b/code/modules/surgery/organs/internal/ears/_ears.dm @@ -13,6 +13,7 @@ now_failing = span_warning("You are unable to hear at all!") now_fixed = span_info("Noise slowly begins filling your ears once more.") low_threshold_cleared = span_info("The ringing in your ears has died down.") + visual = FALSE /// temporary deafness, measured in seconds. While > 0, the person is unable to hear anything. var/temporary_deafness = 0 @@ -141,7 +142,6 @@ /obj/item/organ/ears/invincible damage_multiplier = 0 - /obj/item/organ/ears/cat name = "cat ears" icon = 'icons/obj/clothing/head/costume.dmi' @@ -254,10 +254,10 @@ return all_images /datum/bodypart_overlay/mutant/cat_ears/cybernetic/green - inner_color = "#0079EA" + inner_color = "#00D844" /datum/bodypart_overlay/mutant/cat_ears/cybernetic/blue - inner_color = "#00D844" + inner_color = "#0079EA" /obj/item/organ/ears/ghost name = "ghost ears" diff --git a/code/modules/surgery/organs/internal/eyes/_eyes.dm b/code/modules/surgery/organs/internal/eyes/_eyes.dm index add2859f389..656a6e1de09 100644 --- a/code/modules/surgery/organs/internal/eyes/_eyes.dm +++ b/code/modules/surgery/organs/internal/eyes/_eyes.dm @@ -54,7 +54,7 @@ /// Glasses cannot be worn over these eyes. Currently unused var/no_glasses = FALSE /// Native FOV that will be applied if a config is enabled - var/native_fov = FOV_90_DEGREES + var/native_fov = NONE //BUBBER EDIT CHANGE - ORIGINAL: var/native_fov = FOV_90_DEGREES /// Scarring on this organ var/scarring = NONE @@ -68,11 +68,6 @@ /// do these eyes have pupils (or equivalent) that react to light when penlighted. var/light_reactive = TRUE - // BUBBER EDIT - ADDITION - START - /// This enables alpha values for eyes, adjusted using preferences - var/eyes_opacity = 255 - //BUBBER EDIT - ADDITION - END - /obj/item/organ/eyes/Initialize(mapload) . = ..() if (blink_animation) @@ -117,8 +112,11 @@ /// Refreshes the visuals of the eyes /// If call_update is TRUE, we also will call update_body /obj/item/organ/eyes/proc/refresh(mob/living/carbon/eye_owner = owner, call_update = TRUE) - owner.update_sight() - owner.update_tint() + if(isnull(eye_owner)) + return + + eye_owner.update_sight() + eye_owner.update_tint() if(!ishuman(eye_owner)) return @@ -156,7 +154,7 @@ if(native_fov) organ_owner.remove_fov_trait(type) if(!special) - human_owner.update_body() + human_owner.update_eyes(refresh = FALSE) // become blind (if not special) if(!special) @@ -176,7 +174,6 @@ organ_owner.update_tint() organ_owner.update_sight() - is_emissive = FALSE // BUBBER EDIT - ADDITION UnregisterSignal(organ_owner, list( COMSIG_ATOM_BULLET_ACT, COMSIG_COMPONENT_CLEAN_FACE_ACT, @@ -186,6 +183,20 @@ SIGNAL_REMOVETRAIT(TRAIT_REFLECTIVE_EYES), )) +/obj/item/organ/eyes/on_bodypart_insert(obj/item/bodypart/limb) + . = ..() + if(ishuman(limb.owner)) + limb.owner.update_eyes(refresh = FALSE) + else + limb.update_icon_dropped() + +/obj/item/organ/eyes/on_bodypart_remove(obj/item/bodypart/limb, movement_flags) + . = ..() + if(ishuman(limb.owner)) + limb.owner.update_eyes(refresh = FALSE) + else + limb.update_icon_dropped() + ///Called whenever the luminescent and/or reflective eyes traits are added or removed /obj/item/organ/eyes/proc/on_shiny_eyes_trait_update(mob/living/carbon/human/source) SIGNAL_HANDLER @@ -195,7 +206,7 @@ . = ..() if (ishuman(owner)) refresh_atom_color_overrides() - owner.update_body() + owner.update_eyes() /// Adds eye color overrides to our owner from our atom color /obj/item/organ/eyes/proc/refresh_atom_color_overrides() @@ -298,69 +309,62 @@ // Always show if we have an appendix return ..() || (owner.stat != DEAD && !HAS_TRAIT(owner, TRAIT_KNOCKEDOUT) && (owner.is_blind() || owner.is_nearsighted())) -/// This proc generates a list of overlays that the eye should be displayed using for the given parent -/obj/item/organ/eyes/proc/generate_body_overlay(mob/living/carbon/human/parent, obj/item/bodypart/limb) - if(isnull(eye_icon_state)) +/// This proc generates a list of overlays that the eye displays on the given head +/obj/item/organ/eyes/proc/generate_body_overlay(obj/item/bodypart/head/my_head) + if(!eye_icon_state || isnull(my_head)) return list() - var/mutable_appearance/eye_left = mutable_appearance(eye_icon, "[eye_icon_state]_l", -EYES_LAYER, parent || limb) - var/mutable_appearance/eye_right = mutable_appearance(eye_icon, "[eye_icon_state]_r", -EYES_LAYER, parent || limb) + var/eye_dir = my_head.owner ? null : SOUTH + var/mutable_appearance/eye_left = mutable_appearance(eye_icon, "[eye_icon_state]_l", -EYES_LAYER) + var/mutable_appearance/eye_right = mutable_appearance(eye_icon, "[eye_icon_state]_r", -EYES_LAYER) + eye_left.dir = eye_dir + eye_right.dir = eye_dir + var/list/overlays = list(eye_left, eye_right) - if(!(parent?.obscured_slots & HIDEEYES)) - overlays += get_emissive_overlays(eye_left, eye_right, parent || limb) + if(my_head.owner && !(my_head.owner.obscured_slots & HIDEEYES)) + overlays += get_emissive_overlays(eye_left, eye_right, my_head) - if(!limb) - return overlays - - // Futureproofing for HARS/weird species - var/obj/item/bodypart/head/head = astype(limb, /obj/item/bodypart/head) - if(head?.head_flags & HEAD_EYECOLOR) - if (parent) - eye_right.color = parent.get_right_eye_color() - eye_left.color = parent.get_left_eye_color() - var/list/eyelids = setup_eyelids(eye_left, eye_right, parent) - if (LAZYLEN(eyelids)) - overlays += eyelids - else - eye_right.color = eye_color_right - eye_left.color = eye_color_left + if(my_head.head_flags & HEAD_EYECOLOR) + eye_right.color = eye_color_right || my_head.owner?.get_right_eye_color() + eye_left.color = eye_color_left || my_head.owner?.get_left_eye_color() + var/list/eyelids = get_eyelid_overlays(eye_left, eye_right, my_head) + if (LAZYLEN(eyelids)) + overlays += eyelids if (scarring & RIGHT_EYE_SCAR) - var/mutable_appearance/right_scar = mutable_appearance('icons/mob/human/human_eyes.dmi', "eye_scar_right", -EYES_LAYER, parent || limb) - right_scar.color = limb.draw_color + var/mutable_appearance/right_scar = mutable_appearance('icons/mob/human/human_eyes.dmi', "eye_scar_right", -EYES_LAYER) + right_scar.color = my_head.draw_color overlays += right_scar if (scarring & LEFT_EYE_SCAR) - var/mutable_appearance/left_scar = mutable_appearance('icons/mob/human/human_eyes.dmi', "eye_scar_left", -EYES_LAYER, parent || limb) - left_scar.color = limb.draw_color + var/mutable_appearance/left_scar = mutable_appearance('icons/mob/human/human_eyes.dmi', "eye_scar_left", -EYES_LAYER) + left_scar.color = my_head.draw_color overlays += left_scar - // BUBBER EDIT - ADDITION - START - Customization Emissives & Quad Eyes - if(is_emissive) + if(my_head.worn_face_offset) + for (var/mutable_appearance/overlay as anything in overlays) + my_head.worn_face_offset.apply_offset(overlay) + + // BUBBER EDIT START - Customization (Synths + Emissives) + if(eye_icon_state == "None") + eye_left.alpha = 0 + eye_right.alpha = 0 + + if (is_emissive) // Because it was done all weird up there. var/mutable_appearance/emissive_left = emissive_appearance_copy(eye_left, owner) var/mutable_appearance/emissive_right = emissive_appearance_copy(eye_right, owner) + emissive_left.appearance_flags &= ~RESET_TRANSFORM + emissive_right.appearance_flags &= ~RESET_TRANSFORM + + if(my_head?.worn_face_offset) + my_head.worn_face_offset.apply_offset(emissive_right) + my_head.worn_face_offset.apply_offset(emissive_left) overlays += emissive_left overlays += emissive_right - if(owner && HAS_TRAIT(owner, TRAIT_QUAD_EYES)) // (*) (*) v (*) (*) - var/mutable_appearance/eye_left_2 = mutable_appearance('icons/mob/human/human_eyes.dmi', "eyes_l", -EYES_LAYER, parent) - eye_left_2.color = parent.get_left_eye_color() - eye_left_2.pixel_w -= parent.quad_eyes_offset_width - eye_left_2.pixel_z += parent.quad_eyes_offset - var/mutable_appearance/eye_right_2 = mutable_appearance('icons/mob/human/human_eyes.dmi', "eyes_r", -EYES_LAYER, parent) - eye_right_2.color = parent.get_right_eye_color() - eye_right_2.pixel_w += parent.quad_eyes_offset_width - eye_right_2.pixel_z += parent.quad_eyes_offset - - overlays += eye_left_2 - overlays += eye_right_2 - // BUBBER EDIT - ADDITION - END - Customization Emissives & Quad Eyes - - if(head?.worn_face_offset) - for (var/mutable_appearance/overlay as anything in overlays) - head.worn_face_offset.apply_offset(overlay) + // BUBBER EDIT ADDITION END return overlays @@ -427,7 +431,7 @@ owner.assign_nearsightedness(TRAIT_LEFT_EYE_SCAR, 1, FALSE) if((scarring & RIGHT_EYE_SCAR) && (scarring & LEFT_EYE_SCAR)) owner.become_blind(EYE_SCARRING_TRAIT) - owner.update_body() + owner.update_eyes() /obj/item/organ/eyes/proc/fix_scar(side) if (!(scarring & side)) @@ -439,7 +443,7 @@ return owner.cure_nearsighted(side == RIGHT_EYE_SCAR ? TRAIT_RIGHT_EYE_SCAR : TRAIT_LEFT_EYE_SCAR) owner.cure_blind(EYE_SCARRING_TRAIT) - owner.update_body() + owner.update_eyes() #undef OFFSET_X #undef OFFSET_Y @@ -449,6 +453,8 @@ . = ..() eye_color_left = initial(eye_color_left) eye_color_right = initial(eye_color_right) + fix_scar(LEFT_EYE_SCAR) + fix_scar(RIGHT_EYE_SCAR) /obj/item/organ/eyes/on_low_damage_received() if(damage >= high_threshold) @@ -483,10 +489,10 @@ #define BLINK_LOOPS 5 /// Modifies eye overlays to also act as eyelids, both for blinking and for when you're knocked out cold -/obj/item/organ/eyes/proc/setup_eyelids(mutable_appearance/eye_left, mutable_appearance/eye_right, mob/living/carbon/human/parent) - var/obj/item/bodypart/head/my_head = parent.get_bodypart(BODY_ZONE_HEAD) +/obj/item/organ/eyes/proc/get_eyelid_overlays(mutable_appearance/eye_left, mutable_appearance/eye_right, obj/item/bodypart/head/my_head) + var/mob/living/carbon/human/parent = my_head.owner // Robotic eyes or colorless heads don't get the privelege of having eyelids - if (IS_ROBOTIC_ORGAN(src) || !my_head.draw_color || HAS_TRAIT(parent, TRAIT_NO_EYELIDS)) + if (isnull(parent) || IS_ROBOTIC_ORGAN(src) || !my_head.draw_color || HAS_TRAIT(parent, TRAIT_NO_EYELIDS)) return var/list/base_color = rgb2num(my_head.draw_color, COLORSPACE_HSL) @@ -555,7 +561,7 @@ /obj/item/organ/eyes/proc/blink(duration = BLINK_DURATION, restart_animation = TRUE) var/left_delayed = prob(50) // Storing blink delay so mistimed blinks of lizards don't get cut short - var/sync_blinking = TRUE //BUBBERSTATION CHANGE: DISABLES SYNCED BLINKING UNTIL /TG/ AND/OR BYOND FIXES IT. OLD CODE: synchronized_blinking && (owner.get_organ_loss(ORGAN_SLOT_BRAIN) < BRAIN_DAMAGE_ASYNC_BLINKING) + var/sync_blinking = synchronized_blinking && (owner.get_organ_loss(ORGAN_SLOT_BRAIN) < BRAIN_DAMAGE_ASYNC_BLINKING) var/blink_delay = sync_blinking ? 0 : rand(0, RAND_BLINKING_DELAY) animate(eyelid_left, alpha = 0, time = 0) if (!sync_blinking && left_delayed) @@ -573,7 +579,8 @@ addtimer(CALLBACK(src, PROC_REF(animate_eyelids), owner), blink_delay + duration) /obj/item/organ/eyes/proc/animate_eyelids(mob/living/carbon/human/parent) - var/sync_blinking = TRUE //BUBBERSTATION CHANGE: DISABLES SYNCED BLINKING UNTIL /TG/ AND/OR BYOND FIXES IT. OLD CODE: synchronized_blinking && (parent.get_organ_loss(ORGAN_SLOT_BRAIN) < BRAIN_DAMAGE_ASYNC_BLINKING) + if(CONFIG_GET(flag/disable_blinking)) return // BUBBER EDIT ADDITION - CONFIG BLINKING + var/sync_blinking = synchronized_blinking && (parent.get_organ_loss(ORGAN_SLOT_BRAIN) < BRAIN_DAMAGE_ASYNC_BLINKING) // Randomize order for unsynched animations if (sync_blinking || prob(50)) var/list/anim_times = animate_eyelid(eyelid_left, parent, sync_blinking) diff --git a/code/modules/surgery/organs/internal/eyes/eyes_augments.dm b/code/modules/surgery/organs/internal/eyes/eyes_augments.dm index 276b8437b88..0cce64e4c0c 100644 --- a/code/modules/surgery/organs/internal/eyes/eyes_augments.dm +++ b/code/modules/surgery/organs/internal/eyes/eyes_augments.dm @@ -558,12 +558,12 @@ "Security Status" = JUDGE_RECORDCHECK, ) -/obj/item/organ/eyes/robotic/tacvisor/generate_body_overlay(mob/living/carbon/human/parent, obj/item/bodypart/limb) - var/mutable_appearance/visor_overlay = mutable_appearance(eye_icon, eye_icon_state, -EYES_LAYER, parent || limb) +/obj/item/organ/eyes/robotic/tacvisor/generate_body_overlay(obj/item/bodypart/limb) + var/mutable_appearance/visor_overlay = mutable_appearance(eye_icon, eye_icon_state, -EYES_LAYER) var/list/eye_overlays = list(visor_overlay) - + var/mob/living/carbon/human/parent = limb.owner if (parent && parent.appears_alive() && !HAS_TRAIT(parent, TRAIT_KNOCKEDOUT)) - var/mutable_appearance/display_overlay = mutable_appearance(eye_icon, "[eye_icon_state]_[LOWER_TEXT(visor_display)]", -EYES_LAYER, parent) + var/mutable_appearance/display_overlay = mutable_appearance(eye_icon, "[eye_icon_state]_[LOWER_TEXT(visor_display)]", -EYES_LAYER) eye_overlays += display_overlay if(!(parent.obscured_slots & HIDEEYES)) eye_overlays += emissive_appearance(eye_icon, "[eye_icon_state]_[LOWER_TEXT(visor_display)]", parent, -EYES_LAYER) diff --git a/code/modules/surgery/organs/internal/heart/_heart.dm b/code/modules/surgery/organs/internal/heart/_heart.dm index 5120fbeb949..c7b0bcce0f6 100644 --- a/code/modules/surgery/organs/internal/heart/_heart.dm +++ b/code/modules/surgery/organs/internal/heart/_heart.dm @@ -24,6 +24,7 @@ cell_line = CELL_LINE_ORGAN_HEART cells_minimum = 1 cells_maximum = 2 + visual = FALSE // Heart attack code is in code/modules/mob/living/carbon/human/life.dm @@ -35,7 +36,10 @@ var/beat = BEAT_NONE /// whether the heart's been operated on to fix some of its damages var/operated = FALSE + /// The message that is displayed when listening to a heart via a stethoscope var/beat_noise = "a rhythmic thumping" + /// The rate at which blood is pumped by the heart is multiplied by this (value of 0 disables blood regeneration entirely) + var/blood_regeneration_multiplier = 1 /obj/item/organ/heart/update_icon_state() . = ..() @@ -92,6 +96,14 @@ . = ..() Stop() +/// Returns how effectively this heart regenerates the owner's blood based on organ health +/obj/item/organ/heart/proc/get_blood_regeneration_multiplier() + if(!is_beating() || (organ_flags & (ORGAN_FAILING|ORGAN_EMP))) + return 0 + + var/health_percent = clamp((maxHealth - damage) / maxHealth, 0, 1) + return blood_regeneration_multiplier * health_percent + /// Checks if the heart is beating. /// Can be overridden to add more conditions for more complex hearts. /obj/item/organ/heart/proc/is_beating() @@ -203,16 +215,12 @@ beat_noise = "a steady fsssh of hydraulics" /// Whether or not we have a stabilization available. This prevents our owner from entering softcrit for an amount of time. var/stabilization_available = FALSE - /// How long our stabilization lasts for. var/stabilization_duration = 10 SECONDS - /// Whether our heart suppresses bleeders and restores blood automatically. var/bleed_prevention = FALSE - /// The probability that our blood replication causes toxin damage. var/toxification_probability = 20 - /// Chance of permanent effects if emp-ed. var/emp_vulnerability = 80 @@ -251,8 +259,6 @@ if(bleed_prevention && ishuman(owner) && owner.get_blood_volume() < BLOOD_VOLUME_NORMAL) var/mob/living/carbon/human/wounded_owner = owner - wounded_owner.adjust_blood_volume(2 * seconds_per_tick) - if(toxification_probability && prob(toxification_probability)) wounded_owner.adjust_tox_loss(1 * seconds_per_tick, updating_health = FALSE) @@ -281,6 +287,7 @@ maxHealth = 1.5 * STANDARD_ORGAN_THRESHOLD bleed_prevention = TRUE emp_vulnerability = 40 + blood_regeneration_multiplier = 9 // regenerates 2.25u of blood per tick (default is 0.25u) /obj/item/organ/heart/cybernetic/tier3 name = "upgraded cybernetic heart" @@ -342,9 +349,7 @@ desc = "It beats ever strong." icon_state = "heart-evolved-on" base_icon_state = "heart-evolved" - maxHealth = STANDARD_ORGAN_THRESHOLD * 1.2 - /// Chance to heal per on_life var/healing_probability = 10 /// Base healing we receive per tick at 0 damage and for standard versions @@ -370,7 +375,6 @@ healing_probability = 5 base_healing = 0.5 - // How much damage each magic block deals to us var/damage_per_block = 50 diff --git a/code/modules/surgery/organs/internal/liver/_liver.dm b/code/modules/surgery/organs/internal/liver/_liver.dm index dd5f495a148..e4ec7e017eb 100644 --- a/code/modules/surgery/organs/internal/liver/_liver.dm +++ b/code/modules/surgery/organs/internal/liver/_liver.dm @@ -21,6 +21,8 @@ cells_minimum = 1 cells_maximum = 2 + visual = FALSE + /// Affects how much damage the liver takes from alcohol var/alcohol_tolerance = ALCOHOL_RATE /// The maximum volume of toxins the liver will ignore diff --git a/code/modules/surgery/organs/internal/lungs/_lungs.dm b/code/modules/surgery/organs/internal/lungs/_lungs.dm index 7de94635f98..ef47378b6a3 100644 --- a/code/modules/surgery/organs/internal/lungs/_lungs.dm +++ b/code/modules/surgery/organs/internal/lungs/_lungs.dm @@ -22,6 +22,8 @@ cells_minimum = 1 cells_maximum = 2 + visual = FALSE + var/failed = FALSE var/operated = FALSE //whether we can still have our damages fixed through surgery @@ -1140,10 +1142,9 @@ /// H2O electrolysis /obj/item/organ/lungs/ethereal/proc/consume_water(mob/living/carbon/breather, datum/gas_mixture/breath, h2o_pp, old_h2o_pp) var/gas_breathed = breath.gases[/datum/gas/water_vapor][MOLES] - breath.gases[/datum/gas/water_vapor][MOLES] -= gas_breathed - breath_out.assert_gases(/datum/gas/oxygen, /datum/gas/hydrogen) - breath_out.gases[/datum/gas/oxygen][MOLES] += gas_breathed - breath_out.gases[/datum/gas/hydrogen][MOLES] += gas_breathed * 2 + breath.adjust_gas(/datum/gas/water_vapor, -gas_breathed) + var/list/new_gases = list(/datum/gas/oxygen = gas_breathed, /datum/gas/hydrogen = gas_breathed * 2) + breath_out.adjust_multiple_gases(new_gases) /obj/item/organ/lungs/pod diff --git a/code/modules/surgery/organs/internal/stomach/_stomach.dm b/code/modules/surgery/organs/internal/stomach/_stomach.dm index 1b062039c23..8560c127629 100644 --- a/code/modules/surgery/organs/internal/stomach/_stomach.dm +++ b/code/modules/surgery/organs/internal/stomach/_stomach.dm @@ -28,6 +28,8 @@ cells_minimum = 1 cells_maximum = 2 + visual = FALSE + ///The rate that disgust decays var/disgust_metabolism = 1 diff --git a/code/modules/surgery/organs/internal/tongue/_tongue.dm b/code/modules/surgery/organs/internal/tongue/_tongue.dm index 8f98af596c8..76ae5cd1fdc 100644 --- a/code/modules/surgery/organs/internal/tongue/_tongue.dm +++ b/code/modules/surgery/organs/internal/tongue/_tongue.dm @@ -8,7 +8,7 @@ attack_verb_continuous = list("licks", "slobbers", "slaps", "frenches", "tongues") attack_verb_simple = list("lick", "slobber", "slap", "french", "tongue") voice_filter = "" - organ_traits = list(TRAIT_SPEAKS_CLEARLY) + visual = FALSE /** * A cached list of paths of all the languages this tongue is capable of speaking * @@ -31,6 +31,8 @@ ///for temporary overrides of the above variable. var/temp_say_mod = "" + /// Whether the owner of this tongue can speak clearly. Being set to FALSE means they mumble and slur things + var/speakable_with = TRUE /// Whether the owner of this tongue can taste anything. Being set to FALSE will mean no taste feedback will be provided. var/sense_of_taste = TRUE /// Determines how "sensitive" this tongue is to tasting things, lower is more sensitive. @@ -52,6 +54,8 @@ // - then we cache it via string list // this results in tongues with identical possible languages sharing a cached list instance languages_possible = string_list(get_possible_languages()) + if(speakable_with) + add_organ_trait(TRAIT_SPEAKS_CLEARLY) if(!sense_of_taste) add_organ_trait(TRAIT_AGEUSIA) @@ -155,7 +159,8 @@ add_organ_trait(TRAIT_AGEUSIA) /obj/item/organ/tongue/on_failure_recovery() - add_organ_trait(TRAIT_SPEAKS_CLEARLY) + if(speakable_with) + add_organ_trait(TRAIT_SPEAKS_CLEARLY) if(sense_of_taste) remove_organ_trait(TRAIT_AGEUSIA) @@ -433,6 +438,14 @@ disliked_foodtypes = NONE // List of english words that translate to zombie phrases var/static/list/english_to_zombie = list() + /// Spooky growls we sometimes play while alive + var/static/list/spooks = list( + 'sound/effects/hallucinations/growl1.ogg', + 'sound/effects/hallucinations/growl2.ogg', + 'sound/effects/hallucinations/growl3.ogg', + 'sound/effects/hallucinations/veryfar_noise.ogg', + 'sound/effects/hallucinations/wail.ogg', + ) /obj/item/organ/tongue/zombie/proc/add_word_to_translations(english_word, zombie_word) english_to_zombie[english_word] = zombie_word @@ -488,6 +501,11 @@ message = capitalize(message) speech_args[SPEECH_MESSAGE] = message +/obj/item/organ/tongue/zombie/on_life(seconds_per_tick) + . = ..() + if(owner.stat == CONSCIOUS && SPT_PROB(2, seconds_per_tick)) + playsound(owner, pick(spooks), 50, TRUE, 10) + /obj/item/organ/tongue/alien name = "alien tongue" desc = "According to leading xenobiologists the evolutionary benefit of having a second mouth in your mouth is \"that it looks badass\"." @@ -566,7 +584,7 @@ attack_verb_simple = list("beep", "boop") modifies_speech = TRUE taste_sensitivity = 25 // not as good as an organic tongue - organ_traits = list(TRAIT_SPEAKS_CLEARLY, TRAIT_SILICON_EMOTES_ALLOWED) + organ_traits = list(TRAIT_SILICON_EMOTES_ALLOWED) voice_filter = "alimiter=0.9,acompressor=threshold=0.2:ratio=20:attack=10:release=50:makeup=2,highpass=f=1000" /obj/item/organ/tongue/robot/could_speak_language(datum/language/language_path) @@ -632,7 +650,7 @@ say_mod = "meows" liked_foodtypes = SEAFOOD | ORANGES | BUGS | GORE disliked_foodtypes = GROSS | CLOTH | RAW - organ_traits = list(TRAIT_SPEAKS_CLEARLY, TRAIT_WOUND_LICKER, TRAIT_FISH_EATER, TRAIT_CARPOTOXIN_IMMUNE) + organ_traits = list(TRAIT_WOUND_LICKER, TRAIT_FISH_EATER, TRAIT_CARPOTOXIN_IMMUNE) languages_native = list(/datum/language/nekomimetic) actions_types = list(/datum/action/item_action/organ_action/go_feral) var/feral_mode = FALSE diff --git a/code/modules/surgery/organs/internal/vocal_cords/_vocal_cords.dm b/code/modules/surgery/organs/internal/vocal_cords/_vocal_cords.dm index eff8aaf5ac0..86eb5afd29d 100644 --- a/code/modules/surgery/organs/internal/vocal_cords/_vocal_cords.dm +++ b/code/modules/surgery/organs/internal/vocal_cords/_vocal_cords.dm @@ -6,6 +6,7 @@ gender = PLURAL decay_factor = 0 //we don't want decaying vocal cords to somehow matter or appear on scanners since they don't do anything damaged healing_factor = 0 + visual = FALSE var/list/spans = null /obj/item/organ/vocal_cords/proc/can_speak_with() //if there is any limitation to speaking with these cords diff --git a/code/modules/surgery/organs/organ_movement.dm b/code/modules/surgery/organs/organ_movement.dm index 4851e952dcd..6f1b5ae5334 100644 --- a/code/modules/surgery/organs/organ_movement.dm +++ b/code/modules/surgery/organs/organ_movement.dm @@ -197,7 +197,8 @@ SEND_SIGNAL(src, COMSIG_ORGAN_REMOVED, organ_owner) SEND_SIGNAL(organ_owner, COMSIG_CARBON_LOSE_ORGAN, src, special) - ADD_TRAIT(src, TRAIT_USED_ORGAN, ORGAN_TRAIT) + if(organ_owner.mind) + ADD_TRAIT(src, TRAIT_ORGAN_USED_BY_PLAYER, ORGAN_TRAIT) if(!special) organ_owner.hud_used?.update_locked_slots() diff --git a/code/modules/surgery/surgery_tools.dm b/code/modules/surgery/surgery_tools.dm index 69f97210b30..f07c53b8117 100644 --- a/code/modules/surgery/surgery_tools.dm +++ b/code/modules/surgery/surgery_tools.dm @@ -729,7 +729,7 @@ /obj/item/scalpel/cruel/Initialize(mapload) . = ..() - AddElement(/datum/element/bane, mob_biotypes = MOB_UNDEAD, damage_multiplier = 1) //Just in case one of the tennants get uppity + AddComponent(/datum/component/bane, affected_biotypes = MOB_UNDEAD, damage_multiplier = 2) //Just in case one of the tennants get uppity /obj/item/surgicaldrill/cruel name = "tearing drill" diff --git a/code/modules/tgui/tgui_window.dm b/code/modules/tgui/tgui_window.dm index 2357e9030e9..f82457a8ba8 100644 --- a/code/modules/tgui/tgui_window.dm +++ b/code/modules/tgui/tgui_window.dm @@ -359,6 +359,8 @@ switch(type) if("ping") send_message("ping/reply", payload) + if("ping/set") + client?.avgping = payload["ping"] if("visible") visible = TRUE SEND_SIGNAL(src, COMSIG_TGUI_WINDOW_VISIBLE, client) diff --git a/code/modules/tgui_input/alert.dm b/code/modules/tgui_input/alert.dm index b6df3fc4c3e..b24ec394235 100644 --- a/code/modules/tgui_input/alert.dm +++ b/code/modules/tgui_input/alert.dm @@ -26,7 +26,7 @@ // A gentle nudge - you should not be using TGUI alert for anything other than a simple message. if(length(buttons) > 3) log_tgui(user, "Error: TGUI Alert initiated with too many buttons. Use a list.", "TguiAlert") - return tgui_input_list(user, message, title, buttons, timeout, autofocus) + return tgui_input_list(user, message, title, buttons, timeout=timeout) // Client does NOT have tgui_input on: Returns regular input if(!user.client.prefs.read_preference(/datum/preference/toggle/tgui_input)) if(length(buttons) == 2) diff --git a/code/modules/tgui_input/say_modal/modal.dm b/code/modules/tgui_input/say_modal/modal.dm index e2bd320576e..f57ab94bcbc 100644 --- a/code/modules/tgui_input/say_modal/modal.dm +++ b/code/modules/tgui_input/say_modal/modal.dm @@ -42,7 +42,7 @@ /datum/tgui_say/New(client/client, id) src.client = client window = new(client, id) - winset(client, "tgui_say", "size=1,1;is-visible=0;") + winset(client, SKIN_TGUISAY, "size=1,1;is-visible=0;") window.subscribe(src, PROC_REF(on_message)) window.is_browser = TRUE @@ -69,7 +69,7 @@ /datum/tgui_say/proc/load() window_open = FALSE - winset(client, "tgui_say", "pos=848,500;is-visible=0;") + winset(client, SKIN_TGUISAY, "pos=848,500;is-visible=0;") window.send_message("props", list( "lightMode" = client.prefs?.read_preference(/datum/preference/toggle/tgui_say_light_mode), @@ -92,7 +92,7 @@ if(!payload?["channel"]) CRASH("No channel provided to an open TGUI-Say") window_open = TRUE - if(payload["channel"] != OOC_CHANNEL && payload["channel"] != ADMIN_CHANNEL && payload["channel"] != LOOC_CHANNEL) // SKYRAT EDIT CHANGE (Add LOOC_CHANNEL) + if(payload["channel"] != OOC_CHANNEL && payload["channel"] != ADMIN_CHANNEL && payload["channel"] != PRAY_CHANNEL && payload["channel"] != LOOC_CHANNEL) // SKYRAT EDIT CHANGE (Add LOOC_CHANNEL) start_thinking() if(!client.typing_indicators) log_speech_indicators("[key_name(client)] started typing at [loc_name(client.mob)], indicators DISABLED.") diff --git a/code/modules/tgui_input/say_modal/speech.dm b/code/modules/tgui_input/say_modal/speech.dm index b328a3c955c..5643d3cd269 100644 --- a/code/modules/tgui_input/say_modal/speech.dm +++ b/code/modules/tgui_input/say_modal/speech.dm @@ -12,7 +12,7 @@ var/list/phrases = alter_phrases || hurt_phrases /// No OOC leaks - if(!entry || payload["channel"] == OOC_CHANNEL || payload["channel"] == ME_CHANNEL || payload["channel"] == LOOC_CHANNEL) // BUBBER EDIT - CHANGE - ORIGINAL: if(!entry || payload["channel"] == OOC_CHANNEL || payload["channel"] == ME_CHANNEL) + if(!entry || payload["channel"] == OOC_CHANNEL || payload["channel"] == ME_CHANNEL || payload["channel"] == PRAY_CHANNEL || payload["channel"] == LOOC_CHANNEL) // BUBBER EDIT - CHANGE - ORIGINAL: if(!entry || payload["channel"] == OOC_CHANNEL || payload["channel"] == ME_CHANNEL || payload["channel"] == PRAY_CHANNEL) return pick(phrases) /// Random trimming for larger sentences if(length(entry) > 50) @@ -58,6 +58,9 @@ client.mob.whisper_verb(entry) return TRUE // BUBBER EDIT - ADDITION - END + if(PRAY_CHANNEL) + client.mob.pray(entry) + return TRUE return FALSE /** @@ -128,7 +131,7 @@ * boolean - success or failure */ /datum/tgui_say/proc/handle_entry(type, payload) - if(!payload?["channel"] || !payload["entry"]) + if(!payload?["channel"] || isnull(payload["entry"])) CRASH("[usr] entered in a null payload to the chat window.") if(length(payload["entry"]) > max_length) CRASH("[usr] has entered more characters than allowed into a TGUI-Say") @@ -137,7 +140,7 @@ return TRUE if(type == "force") var/target_channel = payload["channel"] - if(target_channel == ME_CHANNEL || target_channel == OOC_CHANNEL) + if(target_channel == ME_CHANNEL || target_channel == OOC_CHANNEL || target_channel == PRAY_CHANNEL) target_channel = SAY_CHANNEL // No ooc leaks delegate_speech(alter_entry(payload), target_channel) return TRUE diff --git a/code/modules/tgui_panel/external.dm b/code/modules/tgui_panel/external.dm index 0d715b2bf53..ae504fdb0c5 100644 --- a/code/modules/tgui_panel/external.dm +++ b/code/modules/tgui_panel/external.dm @@ -19,19 +19,19 @@ // Failed to fix, using tg_alert as fallback action = tg_alert(src, "Did that work?", "", "Yes", "No, switch to old ui") if (action == "No, switch to old ui") - winset(src, "output_selector.legacy_output_selector", "left=output_legacy") + winset(src, OUTPUT_SELECTOR_LEGACY_OUTPUT_SELECTOR, "left=output_legacy") log_tgui(src, "Failed to fix.", context = "verb/fix_tgui_panel") /client/proc/nuke_chat() // Catch all solution (kick the whole thing in the pants) - winset(src, "output_selector.legacy_output_selector", "left=output_legacy") + winset(src, OUTPUT_SELECTOR_LEGACY_OUTPUT_SELECTOR, "left=output_legacy") if(!tgui_panel || !istype(tgui_panel)) log_tgui(src, "tgui_panel datum is missing", context = "verb/fix_tgui_panel") tgui_panel = new(src) tgui_panel.initialize(force = TRUE) // Force show the panel to see if there are any errors - winset(src, "output_selector.legacy_output_selector", "left=output_browser") + winset(src, OUTPUT_SELECTOR_LEGACY_OUTPUT_SELECTOR, "left=output_browser") /client/verb/refresh_tgui() set name = "Refresh TGUI" diff --git a/code/modules/tooltip/tooltip.dm b/code/modules/tooltip/tooltip.dm index f3c691ce3e9..88973a9a793 100644 --- a/code/modules/tooltip/tooltip.dm +++ b/code/modules/tooltip/tooltip.dm @@ -19,7 +19,7 @@ Notes: /datum/tooltip var/client/owner - var/control = "mainwindow.tooltip" + var/control = SKIN_MAINWINDOW_TOOLTIP var/showing = 0 var/queueHide = 0 var/init = 0 diff --git a/code/modules/transport/tram/tram_controller.dm b/code/modules/transport/tram/tram_controller.dm index 735e9dea48b..06d457ca296 100644 --- a/code/modules/transport/tram/tram_controller.dm +++ b/code/modules/transport/tram/tram_controller.dm @@ -788,14 +788,12 @@ /obj/machinery/transport/tram_controller/hilbert configured_transport_id = HILBERT_LINE_1 -/obj/machinery/transport/tram_controller/wrench_act_secondary(mob/living/user, obj/item/tool) - return NONE - /obj/machinery/transport/tram_controller/Initialize(mapload) . = ..() register_context() if(!id_tag) id_tag = assign_random_name() + AddElement(/datum/element/tool_blocker, TOOL_WRENCH, TOOL_ACT_SECONDARY) /** * Mapped or built tram cabinet isn't located on a transport module. diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm index 22a6885b2e8..a10d412bebe 100644 --- a/code/modules/unit_tests/_unit_tests.dm +++ b/code/modules/unit_tests/_unit_tests.dm @@ -287,6 +287,7 @@ #include "screenshot_airlocks.dm" #include "screenshot_antag_icons.dm" #include "screenshot_basic.dm" +#include "screenshot_debrain.dm" #include "screenshot_digi.dm" #include "screenshot_dynamic_human_icons.dm" #include "screenshot_high_luminosity_eyes.dm" @@ -326,6 +327,7 @@ #include "strippable.dm" #include "stuns.dm" #include "style_hotswapping.dm" +#include "subsystem_flags.dm" #include "subsystem_init.dm" #include "suit_sensor.dm" #include "suit_storage_icons.dm" diff --git a/code/modules/unit_tests/dna_infusion.dm b/code/modules/unit_tests/dna_infusion.dm index 50c339b0e21..0b3b251a923 100644 --- a/code/modules/unit_tests/dna_infusion.dm +++ b/code/modules/unit_tests/dna_infusion.dm @@ -3,9 +3,12 @@ /datum/unit_test/valid_dna_infusion/Run() for(var/datum/infuser_entry/infuser_entry as anything in assoc_to_values(GLOB.infuser_entries)) - for(var/input_type in infuser_entry.input_obj_or_mob) + for(var/datum/input_type as anything in infuser_entry.input_obj_or_mob) if(ispath(input_type, /mob/living)) continue + if(input_type == input_type::abstract_type) + input_type = pick(subtypesof(input_type)) + 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. diff --git a/code/modules/unit_tests/door_access.dm b/code/modules/unit_tests/door_access.dm index 595e68297ad..78e663bb310 100644 --- a/code/modules/unit_tests/door_access.dm +++ b/code/modules/unit_tests/door_access.dm @@ -173,3 +173,55 @@ door.req_access = list(ACCESS_ENGINEERING, ACCESS_MAINT_TUNNELS) subject.Bump(door) TEST_ASSERT_EQUAL(door.density, TRUE, "Subject opened access-locked airlock while hands blocked!") + +/// Checks that doors with the id wire cut are inaccessible +/datum/unit_test/door_require_id_wire_cut + +/datum/unit_test/door_require_id_wire_cut/Run() + var/obj/machinery/door/airlock/instant/door = EASY_ALLOCATE() + door.interaction_flags_machine |= INTERACT_MACHINE_OFFLINE + door.req_access = list(ACCESS_ENGINEERING) + + var/mob/living/carbon/human/subject = EASY_ALLOCATE() + subject.equipOutfit(/datum/outfit/job/assistant/consistent) + var/obj/item/card/id/advanced/keycard = subject.wear_id + keycard.access = list(ACCESS_ENGINEERING, ACCESS_MAINT_TUNNELS) + + subject.Bump(door) + TEST_ASSERT_EQUAL(door.density, FALSE, "Subject failed to open access-locked airlock before id wire cut!") + door.close() + door.wires.pulse(WIRE_OPEN, subject) + TEST_ASSERT_EQUAL(door.density, TRUE, "Pulsing the door's open wire allowed the subject to open the access-locked airlock without cutting the id wire!") + door.wires.cut(WIRE_IDSCAN, subject) + subject.last_bumped = 0 + subject.Bump(door) + TEST_ASSERT_EQUAL(door.density, TRUE, "Subject opened access-locked airlock with id wire cut!") + door.wires.pulse(WIRE_OPEN, subject) + TEST_ASSERT_EQUAL(door.density, FALSE, "Subject failed to open access-locked airlock with id wire cut and open wire pulsed!") + door.close() + door.wires.cut(WIRE_IDSCAN, subject) // mend + subject.last_bumped = 0 + subject.Bump(door) + TEST_ASSERT_EQUAL(door.density, FALSE, "Subject failed to open access-locked airlock after mending id wire!") + +/// Same as above but testing throwing the item at the door +/datum/unit_test/door_require_id_wire_cut/item_only + +/datum/unit_test/door_require_id_wire_cut/item_only/Run() + var/obj/machinery/door/airlock/instant/door = EASY_ALLOCATE() + door.interaction_flags_machine |= INTERACT_MACHINE_OFFLINE + door.req_access = list(ACCESS_ENGINEERING) + + var/obj/item/card/id/advanced/keycard = EASY_ALLOCATE() + keycard.access = list(ACCESS_ENGINEERING, ACCESS_MAINT_TUNNELS) + + keycard.Bump(door) + TEST_ASSERT_EQUAL(door.density, FALSE, "Throwing an ID at an access-locked airlock failed to open it before id wire cut!") + door.close() + door.wires.cut(WIRE_IDSCAN) + keycard.Bump(door) + TEST_ASSERT_EQUAL(door.density, TRUE, "Throwing an ID at an access-locked airlock succeeded in opening it after id wire cut!") + door.close() + door.wires.cut(WIRE_IDSCAN) // mend + keycard.Bump(door) + TEST_ASSERT_EQUAL(door.density, FALSE, "Throwing an ID at an access-locked airlock failed to open it after mending the id wire!") diff --git a/code/modules/unit_tests/plane_double_transform.dm b/code/modules/unit_tests/plane_double_transform.dm index 3379f751e11..fc0245d0c54 100644 --- a/code/modules/unit_tests/plane_double_transform.dm +++ b/code/modules/unit_tests/plane_double_transform.dm @@ -13,30 +13,43 @@ // Generates a list of render target -> PM for future use var/list/render_target_to_plane = list() + // List of all the plane masters that are being scaled by multiz. These cannot feed into each other + var/list/atom/movable/screen/plane_master/input_planes = list() for(var/plane_key in our_group.plane_masters) var/atom/movable/screen/plane_master/plane = our_group.plane_masters[plane_key] if(plane.render_target) render_target_to_plane[plane.render_target] = plane + if(plane.multiz_scaled) + input_planes += plane_key + // We need to walk all our input planes and see if they feed into any plane masters that are also multiz scaled + for(var/input_key in input_planes) + var/list/keys_to_walk = list() + var/atom/movable/screen/plane_master/input_plane = our_group.plane_masters[input_key] + keys_to_walk[input_key] = "[input_plane.type]" + var/key_index = 0 + while(key_index < length(keys_to_walk)) + key_index += 1 + var/next_plane_key = keys_to_walk[key_index] + var/atom/movable/screen/plane_master/next_plane = our_group.plane_masters[next_plane_key] - for(var/plane_key in our_group.plane_masters) - var/atom/movable/screen/plane_master/plane = our_group.plane_masters[plane_key] + for(var/target_plane in next_plane.render_relay_planes) + var/target_key = "[target_plane]" + var/atom/movable/screen/plane_master/target = our_group.plane_masters["[target_key]"] + if(!keys_to_walk[target_key]) + keys_to_walk[target_key] = "[keys_to_walk[next_plane_key]]-[target.type]" + if(target.multiz_scaled) + TEST_FAIL("[input_plane.type] is eventually drawn (via render relays) onto [target.type] {[keys_to_walk[target_key]]}. Both are scaled by multiz, so this will cause strange transforms.\n\ + consider making a new render plate that they can both draw to instead, or something of that nature.") - if(!plane.multiz_scaled) - continue - - // Walk the relay targets - for(var/target_plane in plane.render_relay_planes) - var/atom/movable/screen/plane_master/target = our_group.plane_masters["[target_plane]"] - if(target.multiz_scaled) - TEST_FAIL("[plane.type] draws a render relay into [target.type]. Both are scaled by multiz, so this will cause strange transforms.\n\ - consider making a new render plate that they can both draw to instead, or something of that nature.") - - // Now we walk for filters that take from us - for(var/list/filter in plane.filter_data) - if(!filter["render_source"]) - continue - var/atom/movable/screen/plane_master/target = render_target_to_plane[filter["render_source"]] - if(target.multiz_scaled) - TEST_FAIL("[plane.type] draws a render relay into [target.type]. Both are scaled by multiz, so this will cause strange transforms.\n\ - consider making a new render plate that they can both draw to instead, or something of that nature.") + // Now we walk for filters that take from us + for(var/list/filter in next_plane.filter_data) + if(!filter["render_source"]) + continue + var/atom/movable/screen/plane_master/target = render_target_to_plane[filter["render_source"]] + var/target_key = "[target.plane]" + if(!keys_to_walk[target_key]) + keys_to_walk[target_key] = "[keys_to_walk[next_plane_key]]-[target.type]" + if(target.multiz_scaled) + TEST_FAIL("[input_plane.type] is eventually drawn (via render relays) onto [target.type] {[keys_to_walk[target_key]]}. Both are scaled by multiz, so this will cause strange transforms.\n\ + consider making a new render plate that they can both draw to instead, or something of that nature.") diff --git a/code/modules/unit_tests/plantgrowth_tests.dm b/code/modules/unit_tests/plantgrowth_tests.dm index 595c71d05a4..a7213e37f38 100644 --- a/code/modules/unit_tests/plantgrowth_tests.dm +++ b/code/modules/unit_tests/plantgrowth_tests.dm @@ -8,6 +8,9 @@ for(var/seedpath in paths) var/obj/item/seeds/seed = new seedpath + if (seed.seed_flags & NO_PLANTING) + continue + for(var/i in 1 to seed.growthstages) if(icon_exists(seed.growing_icon, "[seed.icon_grow][i]")) continue diff --git a/code/modules/unit_tests/resist.dm b/code/modules/unit_tests/resist.dm index 2fc64a02703..4e746e09aae 100644 --- a/code/modules/unit_tests/resist.dm +++ b/code/modules/unit_tests/resist.dm @@ -10,7 +10,7 @@ TEST_ASSERT_EQUAL(human.fire_stacks, 5, "Human does not have 5 fire stacks pre-resist") // Stop, drop, and roll has a sleep call. This would delay the test, and is not necessary. - call_async(human, /mob/living/verb/resist) + human.execute_resist() //since resist() is a verb that possibly queues its actual execution for the next tick, we need to make the subsystem that handles the delayed execution process //the callback. either that or sleep ourselves and see if it ran. diff --git a/code/modules/unit_tests/screenshot_debrain.dm b/code/modules/unit_tests/screenshot_debrain.dm new file mode 100644 index 00000000000..2eca2abd916 --- /dev/null +++ b/code/modules/unit_tests/screenshot_debrain.dm @@ -0,0 +1,32 @@ +/// Tests debrained overlay. And also eyeless since we're here +/datum/unit_test/screenshot_debrain + var/last_frame = 1 + +/datum/unit_test/screenshot_debrain/Run() + var/mob/living/carbon/human/human = allocate(/mob/living/carbon/human/dummy/consistent) + var/obj/item/organ/brain/their_brain = human.get_organ_by_type(__IMPLIED_TYPE__) + var/obj/item/organ/eyes/their_eyes = human.get_organ_by_type(__IMPLIED_TYPE__) + human.set_hairstyle(/datum/sprite_accessory/hair/bedheadv4::name) + human.set_facial_hairstyle(/datum/sprite_accessory/facial_hair/vlongbeard::name) + human.set_haircolor(COLOR_BLACK) + human.set_facial_haircolor(COLOR_BLACK) + + var/icon/final_icon = icon('icons/effects/effects.dmi', "nothing") + // record pre-test appearance + final_icon.Insert(getFlatIcon(human, no_anim = TRUE), dir = SOUTH, frame = 1) + + // remove brain, record appearance + their_brain.Remove(human) + final_icon.Insert(getFlatIcon(human, no_anim = TRUE), dir = NORTH, frame = 1) + + // remove eyes, record appearance + their_eyes.Remove(human) + final_icon.Insert(getFlatIcon(human, no_anim = TRUE), dir = EAST, frame = 1) + + // re-add organs, record appearance + their_brain.Insert(human) + their_eyes.Insert(human) + final_icon.Insert(getFlatIcon(human, no_anim = TRUE), dir = WEST, frame = 1) + + // test the final screenshot + test_screenshot("head_organs", final_icon) diff --git a/code/modules/unit_tests/screenshots/screenshot_debrain_head_organs.png b/code/modules/unit_tests/screenshots/screenshot_debrain_head_organs.png new file mode 100644 index 00000000000..fad6e7e38bd Binary files /dev/null and b/code/modules/unit_tests/screenshots/screenshot_debrain_head_organs.png differ diff --git a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_lizard.png b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_lizard.png index 76694152323..02d3799db69 100644 Binary files a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_lizard.png and b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_lizard.png differ diff --git a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_lizard_silverscale.png b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_lizard_silverscale.png index a032bc16fe8..c5bc9261ec5 100644 Binary files a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_lizard_silverscale.png and b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_lizard_silverscale.png differ diff --git a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_ghost.png b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_spirit.png similarity index 100% rename from code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_ghost.png rename to code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_spirit.png diff --git a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_spirit_ghost.png b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_spirit_ghost.png new file mode 100644 index 00000000000..c43c67f12a8 Binary files /dev/null and b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_spirit_ghost.png differ diff --git a/code/modules/unit_tests/simple_animal_freeze.dm b/code/modules/unit_tests/simple_animal_freeze.dm index 574e2bd8534..0c06182755f 100644 --- a/code/modules/unit_tests/simple_animal_freeze.dm +++ b/code/modules/unit_tests/simple_animal_freeze.dm @@ -8,17 +8,6 @@ /mob/living/simple_animal/bot, /mob/living/simple_animal/bot/mulebot, /mob/living/simple_animal/bot/mulebot/paranormal, - /mob/living/simple_animal/bot/secbot, - /mob/living/simple_animal/bot/secbot/beepsky, - /mob/living/simple_animal/bot/secbot/beepsky/armsky, - /mob/living/simple_animal/bot/secbot/beepsky/jr, - /mob/living/simple_animal/bot/secbot/beepsky/officer, - /mob/living/simple_animal/bot/secbot/beepsky/ofitser, - /mob/living/simple_animal/bot/secbot/ed209, - /mob/living/simple_animal/bot/secbot/genesky, - /mob/living/simple_animal/bot/secbot/grievous, - /mob/living/simple_animal/bot/secbot/grievous/toy, - /mob/living/simple_animal/bot/secbot/pingsky, /mob/living/simple_animal/hostile, /mob/living/simple_animal/hostile/asteroid, /mob/living/simple_animal/hostile/asteroid/elite, diff --git a/code/modules/unit_tests/subsystem_flags.dm b/code/modules/unit_tests/subsystem_flags.dm new file mode 100644 index 00000000000..60ce20d4560 --- /dev/null +++ b/code/modules/unit_tests/subsystem_flags.dm @@ -0,0 +1,12 @@ +// Ensures subystem flags are set in a coherent way +/datum/unit_test/subsystem_flags + +/datum/unit_test/subsystem_flags/Run() + for(var/datum/controller/subsystem/sub_lad as anything in subtypesof(/datum/controller/subsystem)) + if((sub_lad::ss_flags & (SS_TICKER | SS_KEEP_TIMING)) == (SS_TICKER | SS_KEEP_TIMING)) + var/list/matching = get_matching_bitflags("ss_flags", sub_lad::ss_flags) + TEST_FAIL("[sub_lad] {[matching.Join(" | ")]} had both SS_TICKER and SEE_KEEP_TIMING set, this is redundant! You should likely remove SS_KEEP_TIMING.") + if((sub_lad::ss_flags & (SS_POST_FIRE_TIMING | SS_KEEP_TIMING)) == (SS_POST_FIRE_TIMING | SS_KEEP_TIMING)) + var/list/matching = get_matching_bitflags("ss_flags", sub_lad::ss_flags) + TEST_FAIL("[sub_lad] {[matching.Join(" | ")]} had both SS_POST_FIRE_TIMING and SEE_KEEP_TIMING set, this is redundant! You should likely remove SS_KEEP_TIMING as SS_POST_FIRE_TIMING overrides it.") + diff --git a/code/modules/unit_tests/surgeries.dm b/code/modules/unit_tests/surgeries.dm index 7a538da8fbb..a0580cd5b24 100644 --- a/code/modules/unit_tests/surgeries.dm +++ b/code/modules/unit_tests/surgeries.dm @@ -244,6 +244,10 @@ var/obj/item/clothing/under/jumpsuit = test_mob.get_item_by_slot(ITEM_SLOT_ICLOTHING) jumpsuit.adjust_to_alt() TEST_ASSERT(test_mob.is_location_accessible(BODY_ZONE_CHEST), "Chest should be accessible after rolling jumpsuit down") + jumpsuit.adjust_to_alt() + + jumpsuit.flags_cover |= ALLOW_SURGERY_THROUGH + TEST_ASSERT(test_mob.is_location_accessible(BODY_ZONE_CHEST), "Chest should be accessible if it has the ALLOW_SURGERY_THROUGH flag") /// Tests surgeries which just modify basic surgical states /datum/unit_test/state_surgeries diff --git a/code/modules/unit_tests/unequip_defib.dm b/code/modules/unit_tests/unequip_defib.dm index 910cf599af2..6af213dec12 100644 --- a/code/modules/unit_tests/unequip_defib.dm +++ b/code/modules/unit_tests/unequip_defib.dm @@ -12,7 +12,7 @@ usr = dummy // mouse drop still uses usr - defib.MouseDrop(dummy.hud_used.hand_slots[1]) + defib.MouseDrop(dummy.hud_used.screen_objects[HUD_KEY_HAND_SLOT(1)]) if(!dummy.is_holding(defib)) TEST_FAIL("The dummy failed to remove the defib from their back via mouse drop.") diff --git a/code/modules/unit_tests/unit_test.dm b/code/modules/unit_tests/unit_test.dm index bd48b6f8f9d..79c5005f1c4 100644 --- a/code/modules/unit_tests/unit_test.dm +++ b/code/modules/unit_tests/unit_test.dm @@ -279,6 +279,9 @@ GLOBAL_VAR_INIT(focused_tests, focused_tests()) /obj/effect/decal/cleanable/blood/trail, //Should not exist outside of ethereals /obj/item/stock_parts/power_store/cell/ethereal, + // Abstract type, controlled by turfs + // Literally errors on creation/deletion + /atom/movable/lighting_object, ) // Everything that follows is a typesof() check. diff --git a/code/modules/uplink/uplink_items/explosive.dm b/code/modules/uplink/uplink_items/explosive.dm index a0c082de3b2..6283369b5f4 100644 --- a/code/modules/uplink/uplink_items/explosive.dm +++ b/code/modules/uplink/uplink_items/explosive.dm @@ -122,6 +122,15 @@ purchasable_from = ~UPLINK_ALL_SYNDIE_OPS /// Ops get their own version. limited_discount_stock = 4 +/datum/uplink_item/explosives/earthcracker + name = "E-2 Earthcracker" + desc = "The E-2 Earthcracker makes for a great partner to any conventional explosive. Set the device up on any station hull, arm, and activate.\ + What remains is a conventionally dangerous weakpoint, that will crack open a random pattern of floors upon being hit with an explosive force.\ + That pattern of cracks will in-turn also create additional cracks, ad-finimum if not repaired. It can also be used for mining out rock, though that's less advised." + item = /obj/item/earthcracker + cost = 2 + limited_discount_stock = 2 + /datum/uplink_item/explosives/syndicate_bomb/New() . = ..() desc = replacetext(desc, "%MIN_BOMB_TIMER", SYNDIEBOMB_MIN_TIMER_SECONDS) diff --git a/code/modules/uplink/uplink_items/nukeops.dm b/code/modules/uplink/uplink_items/nukeops.dm index 8f82486fbe5..58cc5a1307d 100644 --- a/code/modules/uplink/uplink_items/nukeops.dm +++ b/code/modules/uplink/uplink_items/nukeops.dm @@ -668,6 +668,16 @@ restricted = FALSE refundable = FALSE + +/datum/uplink_item/reinforcements/ed209 + name = "Modified ED209" + desc = "Stolen Nanotrasen tech, slightly tweaked and modified to fit a greater purpose." + item = /obj/item/antag_spawner/nuke_ops/ed209_nukie + cost = 20 + restricted = FALSE + refundable = FALSE + + // Bundles /datum/uplink_item/bundles_tc/cyber_implants diff --git a/code/modules/uplink/uplink_items/stealthy.dm b/code/modules/uplink/uplink_items/stealthy.dm index 1d2e5016db2..e5e39bdcbbf 100644 --- a/code/modules/uplink/uplink_items/stealthy.dm +++ b/code/modules/uplink/uplink_items/stealthy.dm @@ -44,6 +44,14 @@ cost = 6 surplus = 50 +/datum/uplink_item/stealthy_weapons/carnivorous_blood + name = "Carnivorous Blood" + desc = "A bottle of Carnivorous Blood, an Interdyne bioweapon that, once mixed with a potential victim's blood and then inserted into their bloodstream, \ + will rapidly consume its victim's supply of usable blood. Feed it high-protein meat to let it cultivate." + item = /obj/item/storage/box/syndie_kit/carnivorous_blood + cost = 3 + surplus = 50 + /datum/uplink_item/stealthy_weapons/suppressor name = "Suppressor" desc = "This suppressor will silence the shots of the weapon it is attached to for increased stealth and superior ambushing capability. It is compatible with many small ballistic guns including the Makarov, Stechkin APS and C-20r, but not revolvers or energy guns." diff --git a/code/modules/vehicles/_vehicle.dm b/code/modules/vehicles/_vehicle.dm index 895352a30a6..39c08e65351 100644 --- a/code/modules/vehicles/_vehicle.dm +++ b/code/modules/vehicles/_vehicle.dm @@ -24,9 +24,9 @@ * [/datum/component/riding/var/keytype] variable because only a few specific checks are handled here with this var, and the majority of it is on the riding component * Eventually the remaining checks should be moved to the component and this var removed. */ - var/key_type + var/obj/item/key_type ///The inserted key, needed on some vehicles to start the engine - var/obj/item/key/inserted_key + var/obj/item/inserted_key /// Whether the vehicle is currently able to move var/canmove = TRUE var/list/autogrant_actions_passenger //plain list of typepaths diff --git a/code/modules/vehicles/cars/car.dm b/code/modules/vehicles/cars/car.dm index 2b7307a0f88..79e5f6603d4 100644 --- a/code/modules/vehicles/cars/car.dm +++ b/code/modules/vehicles/cars/car.dm @@ -24,13 +24,13 @@ if(car_traits & CAN_KIDNAP) initialize_controller_action_type(/datum/action/vehicle/sealed/dump_kidnapped_mobs, VEHICLE_CONTROL_DRIVE) -/obj/vehicle/sealed/car/mouse_drop_receive(atom/dropping, mob/M, params) - if(HAS_TRAIT(M, TRAIT_HANDS_BLOCKED) && !is_driver(M)) +/obj/vehicle/sealed/car/mouse_drop_receive(atom/dropping, mob/user, params) + if(!isliving(user) || (HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) && !is_driver(user))) return - if((car_traits & CAN_KIDNAP) && isliving(dropping) && M != dropping) + if((car_traits & CAN_KIDNAP) && isliving(dropping) && user != dropping) var/mob/living/kidnapped = dropping - kidnapped.visible_message(span_warning("[M] starts forcing [kidnapped] into [src]!")) - mob_try_forced_enter(M, kidnapped) + kidnapped.visible_message(span_warning("[user] starts forcing [kidnapped] into [src]!")) + mob_try_forced_enter(user, kidnapped) return ..() /obj/vehicle/sealed/car/mob_try_exit(mob/future_pedestrian, mob/user, silent = FALSE) diff --git a/code/modules/vehicles/lavaboat.dm b/code/modules/vehicles/lavaboat.dm index 378f03923a9..194c8377b4c 100644 --- a/code/modules/vehicles/lavaboat.dm +++ b/code/modules/vehicles/lavaboat.dm @@ -1,6 +1,4 @@ - -//Boat - +// Boat /obj/vehicle/ridden/lavaboat name = "lava boat" desc = "A boat used for traversing lava." @@ -16,6 +14,26 @@ . = ..() AddElement(/datum/element/ridable, /datum/component/riding/vehicle/lavaboat) +/obj/vehicle/ridden/lavaboat/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(!key_type || is_key(inserted_key) || !is_key(tool)) + return NONE + if(!user.transferItemToLoc(tool, src)) + to_chat(user, span_warning("[tool] seems to be stuck to your hand!")) + return ITEM_INTERACT_BLOCKING + to_chat(user, span_notice("You attach \the [tool] to \the [src].")) + if(inserted_key) //just in case there's an invalid key + inserted_key.forceMove(drop_location()) + inserted_key = tool + return ITEM_INTERACT_SUCCESS + +/obj/vehicle/ridden/lavaboat/examine_key_message() + if(!key_type) + return + if(!inserted_key) + return span_notice("You can attach an oar to it by clicking \the [src] with one.") + else + return span_notice("Alt-click [src] to detach \the [inserted_key].") + /obj/item/oar name = "oar" desc = "Not to be confused with the kind Research hassles you for." @@ -57,19 +75,26 @@ result = /obj/vehicle/ridden/lavaboat/plasma reqs = list(/obj/item/stack/sheet/animalhide/goliath_hide/polar_bear_hide = 3) -//Dragon Boat - - +// Dragon Boat /obj/item/ship_in_a_bottle name = "ship in a bottle" desc = "A tiny ship inside a bottle." icon = 'icons/obj/mining_zones/artefacts.dmi' icon_state = "ship_bottle" + w_class = WEIGHT_CLASS_SMALL /obj/item/ship_in_a_bottle/attack_self(mob/user) to_chat(user, span_notice("You're not sure how they get the ships in these things, but you're pretty sure you know how to get it out.")) - playsound(user.loc, 'sound/effects/glass/glassbr1.ogg', 100, TRUE) - new /obj/vehicle/ridden/lavaboat/dragon(get_turf(src)) + create_boat(get_turf(src)) + +/obj/item/ship_in_a_bottle/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) + . = ..() + if (!.) // Shatter when not caught + create_boat(get_turf(src)) + +/obj/item/ship_in_a_bottle/proc/create_boat(drop_loc) + playsound(drop_loc, 'sound/effects/glass/glassbr1.ogg', 100, TRUE) + new /obj/vehicle/ridden/lavaboat/dragon(drop_loc) qdel(src) /obj/vehicle/ridden/lavaboat/dragon @@ -82,3 +107,17 @@ /obj/vehicle/ridden/lavaboat/dragon/Initialize(mapload) . = ..() AddElement(/datum/element/ridable, /datum/component/riding/vehicle/lavaboat/dragonboat) + +/obj/vehicle/ridden/lavaboat/dragon/examine(mob/user) + . = ..() + . += span_notice("You can reform [src] into its bottled shape by rubbing the dragon's nose with [EXAMINE_HINT("Alt-Click")].") + +/obj/vehicle/ridden/lavaboat/dragon/click_alt(mob/user) + balloon_alert(user, "bottling the boat...") + if (!do_after(user, 2 SECONDS, src)) + return CLICK_ACTION_BLOCKING + balloon_alert(user, "bottled the boat!") + var/obj/item/ship_in_a_bottle/bottled_ship = new(user.drop_location()) + user.put_in_hands(bottled_ship) + qdel(src) + return CLICK_ACTION_SUCCESS diff --git a/code/modules/vehicles/mecha/equipment/tools/air_tank.dm b/code/modules/vehicles/mecha/equipment/tools/air_tank.dm index 6d9765e6b05..eae27f5a183 100644 --- a/code/modules/vehicles/mecha/equipment/tools/air_tank.dm +++ b/code/modules/vehicles/mecha/equipment/tools/air_tank.dm @@ -31,9 +31,8 @@ internal_tank.air_contents.volume = volume internal_tank.maximum_pressure = maximum_pressure if(start_full) - internal_tank.air_contents.temperature = T20C - internal_tank.air_contents.add_gases(/datum/gas/oxygen) - internal_tank.air_contents.gases[/datum/gas/oxygen][MOLES] = maximum_pressure * volume / (R_IDEAL_GAS_EQUATION * internal_tank.air_contents.temperature) + internal_tank.air_contents.set_temperature(T20C) + internal_tank.air_contents.set_gas(/datum/gas/oxygen, maximum_pressure * volume / (R_IDEAL_GAS_EQUATION * internal_tank.air_contents.temperature)) /obj/item/mecha_parts/mecha_equipment/air_tank/Destroy() if(chassis) diff --git a/code/modules/vehicles/mecha/equipment/tools/mining_tools.dm b/code/modules/vehicles/mecha/equipment/tools/mining_tools.dm index a693fe33ab1..a4b600f496e 100644 --- a/code/modules/vehicles/mecha/equipment/tools/mining_tools.dm +++ b/code/modules/vehicles/mecha/equipment/tools/mining_tools.dm @@ -120,7 +120,7 @@ return target.visible_message(span_warning("[chassis] starts to drill [target]."), \ - span_userdanger("[chassis] starts to drill [target]..."), \ + span_userdanger("[chassis] starts to drill you!"), \ span_hear("You hear drilling.")) log_message("Started drilling [target]", LOG_MECHA) @@ -200,18 +200,20 @@ return //drill makes a hole - var/def_zone = target.get_random_valid_zone(BODY_ZONE_CHEST) - var/obj/item/bodypart/target_part = target.get_bodypart(def_zone) - var/blocked = target.run_armor_check(def_zone, MELEE) - target.apply_damage(10, BRUTE, def_zone, blocked) + var/def_zone = target.get_random_valid_zone(user.zone_selected) + target.apply_damage( + 10, + BRUTE, + def_zone, + blocked = target.run_armor_check(def_zone, MELEE), + wound_bonus = 30, + exposed_wound_bonus = 50, + sharpness = SHARP_POINTY + ) //blood splatters target.create_splatter(get_dir(chassis, target)) - //organs go everywhere - if(target_part && blocked < 100 && prob(10 * drill_level)) - target_part.dismember(BRUTE) - /obj/item/mecha_parts/mecha_equipment/drill/diamonddrill name = "diamond-tipped exosuit drill" desc = "Equipment for engineering and combat exosuits. This is an upgraded version of the drill that'll pierce the heavens!" diff --git a/code/modules/vehicles/ridden.dm b/code/modules/vehicles/ridden.dm index fc570c3b6dd..64c305d9c25 100644 --- a/code/modules/vehicles/ridden.dm +++ b/code/modules/vehicles/ridden.dm @@ -9,11 +9,17 @@ /obj/vehicle/ridden/examine(mob/user) . = ..() - if(key_type) - if(!inserted_key) - . += span_notice("Put a key inside it by clicking it with the key.") - else - . += span_notice("Alt-click [src] to remove the key.") + var/key_message = examine_key_message() + if (key_message) + . += key_message + +/obj/vehicle/ridden/proc/examine_key_message() + if(!key_type) + return + if(!inserted_key) + return span_notice("Put a key inside it by clicking it with the [key_type::name].") + else + return span_notice("Alt-click [src] to remove \the [inserted_key].") /obj/vehicle/ridden/generate_action_type(actiontype) var/datum/action/vehicle/ridden/A = ..() @@ -45,7 +51,7 @@ if(!inserted_key) return CLICK_ACTION_BLOCKING if(!is_occupant(user)) - to_chat(user, span_warning("You must be riding the [src] to remove [src]'s key!")) + to_chat(user, span_warning("You must be riding the [src] to remove [src]'s [inserted_key]!")) return CLICK_ACTION_BLOCKING to_chat(user, span_notice("You remove \the [inserted_key] from \the [src].")) user.put_in_hands(inserted_key) diff --git a/code/modules/vehicles/sealed.dm b/code/modules/vehicles/sealed.dm index c1116443204..6c5776e37d8 100644 --- a/code/modules/vehicles/sealed.dm +++ b/code/modules/vehicles/sealed.dm @@ -23,11 +23,11 @@ if(istype(E)) E.vehicle_entered_target = src -/obj/vehicle/sealed/mouse_drop_receive(atom/dropping, mob/M, params) - if(!istype(dropping) || !istype(M)) +/obj/vehicle/sealed/mouse_drop_receive(atom/dropping, mob/living/user, params) + if(!istype(dropping) || !istype(user)) return ..() - if(M == dropping) - mob_try_enter(M) + if(user == dropping) + mob_try_enter(user) return ..() /obj/vehicle/sealed/Exited(atom/movable/gone, direction) diff --git a/code/modules/vending/vendor/interaction.dm b/code/modules/vending/vendor/interaction.dm index 0e8c2cfc7b9..1cbd7a5ffa2 100644 --- a/code/modules/vending/vendor/interaction.dm +++ b/code/modules/vending/vendor/interaction.dm @@ -159,8 +159,9 @@ to_chat(user, span_notice("You loaded [restocked] items in [src][credits_contained > 0 ? ", and are rewarded [credits_contained] [MONEY_NAME]." : "."]")) var/datum/bank_account/cargo_account = SSeconomy.get_dep_account(ACCOUNT_CAR) cargo_account.adjust_money(round(credits_contained * 0.5), "Vending: Restock") - var/obj/item/holochip/payday = new(src, credits_contained) - try_put_in_hand(payday, user) + if(credits_contained >= 1) + var/obj/item/holochip/payday = new(src, credits_contained) + try_put_in_hand(payday, user) credits_contained = 0 /obj/machinery/vending/exchange_parts(mob/user, obj/item/storage/part_replacer/replacer) diff --git a/code/modules/vending/wardrobes.dm b/code/modules/vending/wardrobes.dm index c17ad858354..a2bc63934c2 100644 --- a/code/modules/vending/wardrobes.dm +++ b/code/modules/vending/wardrobes.dm @@ -699,7 +699,7 @@ GLOBAL_VAR_INIT(roaches_deployed, FALSE) /obj/item/clothing/under/rank/security/detective/noir = 2, /obj/item/clothing/under/rank/security/detective/noir/skirt = 2, /obj/item/clothing/shoes/laceup = 2, - /obj/item/clothing/head/fedora = 2, + /obj/item/clothing/head/fedora/det_hat/noir = 1, /obj/item/clothing/suit/toggle/jacket/det_trench/noir = 1, /obj/item/clothing/suit/jacket/det_suit/noir = 1, /obj/item/clothing/neck/tie/disco = 1, diff --git a/code/modules/wiremod/components/usb/emitter.dm b/code/modules/wiremod/components/usb/emitter.dm new file mode 100644 index 00000000000..a817a3d8cf5 --- /dev/null +++ b/code/modules/wiremod/components/usb/emitter.dm @@ -0,0 +1,58 @@ +/** + * USB wiremod interface for emitter machines + */ +/obj/item/circuit_component/emitter + display_name = "Emitter" + desc = "Allows you to manually fire and get the ready status of an emitter. Must be unlocked to use fired signal." + + ///Manually trigger the emitter + var/datum/port/input/fire + + ///Send a signal when the emitter is turned on + var/datum/port/output/turned_on + ///Send a signal when the emitter is turned off + var/datum/port/output/turned_off + ///Send a signal when the emitter has fired + var/datum/port/output/has_fired + + ///The component parent object + var/obj/machinery/power/emitter/attached_emitter + +/obj/item/circuit_component/emitter/populate_ports() + fire = add_input_port("Fire", PORT_TYPE_SIGNAL, trigger = PROC_REF(fire_emitter)) + + turned_on = add_output_port("Turned On", PORT_TYPE_SIGNAL) + turned_off = add_output_port("Turned Off", PORT_TYPE_SIGNAL) + has_fired = add_output_port("Has Fired", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/emitter/register_usb_parent(atom/movable/parent) + . = ..() + if(istype(parent, /obj/machinery/power/emitter)) + attached_emitter = parent + RegisterSignal(attached_emitter, COMSIG_EMITTER_MACHINE_SET_ON, PROC_REF(handle_emitter_activation)) + RegisterSignal(attached_emitter, COMSIG_EMITTER_MACHINE_ON_FIRE, PROC_REF(handle_emitter_on_fire)) + +/obj/item/circuit_component/emitter/unregister_usb_parent(atom/movable/parent) + UnregisterSignal(attached_emitter, COMSIG_EMITTER_MACHINE_SET_ON) + UnregisterSignal(attached_emitter, COMSIG_EMITTER_MACHINE_ON_FIRE) + attached_emitter = null + return ..() + +/obj/item/circuit_component/emitter/proc/handle_emitter_activation(datum/source, active) + SIGNAL_HANDLER + if(active) + turned_on.set_output(COMPONENT_SIGNAL) + else + turned_off.set_output(COMPONENT_SIGNAL) + +/obj/item/circuit_component/emitter/proc/handle_emitter_on_fire(datum/source, active) + SIGNAL_HANDLER + has_fired.set_output(COMPONENT_SIGNAL) + +/obj/item/circuit_component/emitter/proc/fire_emitter() + CIRCUIT_TRIGGER + if(!attached_emitter) + return + if(attached_emitter.locked) // do not fire if emitter is locked + return + attached_emitter.fire_beam_pulse() diff --git a/code/modules/wiremod/components/usb/temperature_pump.dm b/code/modules/wiremod/components/usb/temperature_pump.dm new file mode 100644 index 00000000000..abd199701d1 --- /dev/null +++ b/code/modules/wiremod/components/usb/temperature_pump.dm @@ -0,0 +1,105 @@ +/** + * USB wiremod interface for temperature pumps + */ +/obj/item/circuit_component/atmos_temperature_pump + display_name = "Atmospheric Temperature Pump" + desc = "The interface for communicating with a temperature pump." + + ///Set the percent of the heat delta to transfer + var/datum/port/input/heat_transfer_rate + ///Activate the pump + var/datum/port/input/on + ///Deactivate the pump + var/datum/port/input/off + ///Signals the circuit to retrieve the pump's current percent and temperature + var/datum/port/input/request_data + + ///Current status of the percent + var/datum/port/output/heat_transfer_rate_state + ///Pressure of the input port + var/datum/port/output/input_pressure + ///Pressure of the output port + var/datum/port/output/output_pressure + ///Temperature of the input port + var/datum/port/output/input_temperature + ///Temperature of the output port + var/datum/port/output/output_temperature + + ///Whether the pump is currently active + var/datum/port/output/is_active + ///Send a signal when the pump is turned on + var/datum/port/output/turned_on + ///Send a signal when the pump is turned off + var/datum/port/output/turned_off + + ///The component parent object + var/obj/machinery/atmospherics/components/binary/temperature_pump/connected_pump + +/obj/item/circuit_component/atmos_temperature_pump/populate_ports() + heat_transfer_rate = add_input_port("Set Heat Transfer Rate", PORT_TYPE_NUMBER, trigger = PROC_REF(set_pump_heat_rate)) + on = add_input_port("Turn On", PORT_TYPE_SIGNAL, trigger = PROC_REF(set_pump_on)) + off = add_input_port("Turn Off", PORT_TYPE_SIGNAL, trigger = PROC_REF(set_pump_off)) + request_data = add_input_port("Request Port Data", PORT_TYPE_SIGNAL, trigger = PROC_REF(request_pump_data)) + + heat_transfer_rate_state = add_output_port("Heat Transfer Rate", PORT_TYPE_NUMBER) + input_pressure = add_output_port("Input Pressure", PORT_TYPE_NUMBER) + output_pressure = add_output_port("Output Pressure", PORT_TYPE_NUMBER) + input_temperature = add_output_port("Input Temperature", PORT_TYPE_NUMBER) + output_temperature = add_output_port("Output Temperature", PORT_TYPE_NUMBER) + + is_active = add_output_port("Active", PORT_TYPE_NUMBER) + turned_on = add_output_port("Turned On", PORT_TYPE_SIGNAL) + turned_off = add_output_port("Turned Off", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/atmos_temperature_pump/register_usb_parent(atom/movable/shell) + . = ..() + if(istype(shell, /obj/machinery/atmospherics/components/binary/temperature_pump)) + connected_pump = shell + RegisterSignal(connected_pump, COMSIG_ATMOS_MACHINE_SET_ON, PROC_REF(handle_pump_activation)) + +/obj/item/circuit_component/atmos_temperature_pump/unregister_usb_parent(atom/movable/shell) + UnregisterSignal(connected_pump, COMSIG_ATMOS_MACHINE_SET_ON) + connected_pump = null + return ..() + +/obj/item/circuit_component/atmos_temperature_pump/pre_input_received(datum/port/input/port) + heat_transfer_rate.set_value(clamp(heat_transfer_rate.value, 0, connected_pump ? connected_pump.max_heat_transfer_rate : 100)) + +/obj/item/circuit_component/atmos_temperature_pump/proc/handle_pump_activation(datum/source, active) + SIGNAL_HANDLER + is_active.set_output(active) + if(active) + turned_on.set_output(COMPONENT_SIGNAL) + else + turned_off.set_output(COMPONENT_SIGNAL) + +/obj/item/circuit_component/atmos_temperature_pump/proc/set_pump_heat_rate() + CIRCUIT_TRIGGER + if(!connected_pump) + return + connected_pump.heat_transfer_rate = heat_transfer_rate.value + +/obj/item/circuit_component/atmos_temperature_pump/proc/set_pump_on() + CIRCUIT_TRIGGER + if(!connected_pump) + return + connected_pump.set_on(TRUE) + +/obj/item/circuit_component/atmos_temperature_pump/proc/set_pump_off() + CIRCUIT_TRIGGER + if(!connected_pump) + return + connected_pump.set_on(FALSE) + connected_pump.update_appearance(UPDATE_ICON) + +/obj/item/circuit_component/atmos_temperature_pump/proc/request_pump_data() + CIRCUIT_TRIGGER + if(!connected_pump) + return + var/datum/gas_mixture/air_input = connected_pump.airs[1] + var/datum/gas_mixture/air_output = connected_pump.airs[2] + heat_transfer_rate_state.set_output(connected_pump.heat_transfer_rate) + input_pressure.set_output(air_input.return_pressure()) + output_pressure.set_output(air_output.return_pressure()) + input_temperature.set_output(air_input.return_temperature()) + output_temperature.set_output(air_output.return_temperature()) diff --git a/code/modules/wiremod/components/usb/thermomachine.dm b/code/modules/wiremod/components/usb/thermomachine.dm new file mode 100644 index 00000000000..49929e2da83 --- /dev/null +++ b/code/modules/wiremod/components/usb/thermomachine.dm @@ -0,0 +1,100 @@ +/** + * USB wiremod interface for temperature control unit machines + */ +/obj/item/circuit_component/thermomachine + display_name = "Temperature Control Unit" + desc = "The interface for communicating with a temperature control unit." + + ///Set the target temperature + var/datum/port/input/temperature + ///Activate the machine + var/datum/port/input/on + ///Deactivate the machine + var/datum/port/input/off + ///Signals the circuit to retrieve the machine's current pressure and temperature + var/datum/port/input/request_data + + ///Pressure of the port + var/datum/port/output/port_pressure + ///Temperature of the port port + var/datum/port/output/port_temperature + + ///Whether the machine is currently active + var/datum/port/output/is_active + ///Send a signal when the machine is turned on + var/datum/port/output/turned_on + ///Send a signal when the machine is turned off + var/datum/port/output/turned_off + + ///The component parent object + var/obj/machinery/atmospherics/components/unary/thermomachine/connected_machine + +/obj/item/circuit_component/thermomachine/populate_ports() + temperature = add_input_port("Set Temperature", PORT_TYPE_NUMBER, trigger = PROC_REF(set_temperature)) + on = add_input_port("Turn On", PORT_TYPE_SIGNAL, trigger = PROC_REF(set_machine_on)) + off = add_input_port("Turn Off", PORT_TYPE_SIGNAL, trigger = PROC_REF(set_machine_off)) + request_data = add_input_port("Request Port Data", PORT_TYPE_SIGNAL, trigger = PROC_REF(request_pump_data)) + + port_pressure = add_output_port("Pressure", PORT_TYPE_NUMBER) + port_temperature = add_output_port("Temperature", PORT_TYPE_NUMBER) + + is_active = add_output_port("Active", PORT_TYPE_NUMBER) + turned_on = add_output_port("Turned On", PORT_TYPE_SIGNAL) + turned_off = add_output_port("Turned Off", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/thermomachine/register_usb_parent(atom/movable/shell) + . = ..() + if(istype(shell, /obj/machinery/atmospherics/components/unary/thermomachine)) + connected_machine = shell + RegisterSignal(connected_machine, COMSIG_ATMOS_MACHINE_SET_ON, PROC_REF(handle_pump_activation)) + +/obj/item/circuit_component/thermomachine/unregister_usb_parent(atom/movable/shell) + UnregisterSignal(connected_machine, COMSIG_ATMOS_MACHINE_SET_ON) + connected_machine = null + return ..() + +/obj/item/circuit_component/thermomachine/pre_input_received(datum/port/input/port) + if(connected_machine) + var/min = connected_machine.min_temperature + var/max = connected_machine.max_temperature + temperature.set_value(clamp(temperature.value, min, max)) + +/obj/item/circuit_component/thermomachine/proc/handle_pump_activation(datum/source, active) + SIGNAL_HANDLER + is_active.set_output(active) + if(active) + turned_on.set_output(COMPONENT_SIGNAL) + else + turned_off.set_output(COMPONENT_SIGNAL) + +/obj/item/circuit_component/thermomachine/proc/set_temperature() + CIRCUIT_TRIGGER + if(!connected_machine) + return + var/min = connected_machine.min_temperature + var/max = connected_machine.max_temperature + connected_machine.target_temperature = clamp(temperature.value, min, max) + connected_machine.update_icon_state() + +/obj/item/circuit_component/thermomachine/proc/set_machine_on() + CIRCUIT_TRIGGER + if(!connected_machine) + return + connected_machine.set_on(TRUE) + connected_machine.update_use_power(ACTIVE_POWER_USE) + +/obj/item/circuit_component/thermomachine/proc/set_machine_off() + CIRCUIT_TRIGGER + if(!connected_machine) + return + connected_machine.set_on(FALSE) + connected_machine.update_use_power(IDLE_POWER_USE) + connected_machine.update_appearance(UPDATE_ICON) + +/obj/item/circuit_component/thermomachine/proc/request_pump_data() + CIRCUIT_TRIGGER + if(!connected_machine) + return + var/datum/gas_mixture/port = connected_machine.airs[1] + port_pressure.set_output(port.return_pressure()) + port_temperature.set_output(port.return_temperature()) diff --git a/code/modules/wiremod/components/utility/timepiece.dm b/code/modules/wiremod/components/utility/timepiece.dm index fa675bfa1b9..e40e4d1f09c 100644 --- a/code/modules/wiremod/components/utility/timepiece.dm +++ b/code/modules/wiremod/components/utility/timepiece.dm @@ -46,19 +46,19 @@ switch(format.value) if(COMP_TIMEPIECE_TWENTYFOUR_HOUR) - time = station_time_timestamp() + time = round_timestamp() if(COMP_TIMEPIECE_TWELVE_HOUR) - time = time_to_twelve_hour(station_time()) + time = time_to_twelve_hour() text_output.set_output(time) switch(time_unit.value) if(COMP_TIMEPIECE_HOURS) - time = round(station_time() / (1 HOURS)) + time = round_timestamp(format = "hh") if(COMP_TIMEPIECE_MINUTES) - time = round(station_time() / (1 MINUTES)) + time = round_timestamp(format = "mm") if(COMP_TIMEPIECE_SECONDS) - time = round(station_time() / (1 SECONDS)) + time = round_timestamp(format = "ss") num_output.set_output(time) diff --git a/config/game_options.txt b/config/game_options.txt index 3104693b27c..5ced2acadd8 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -533,15 +533,6 @@ ROUNDSTART_TRAITS ## Enable night shifts #ENABLE_NIGHT_SHIFTS -## The shift start hour in 24-hour (0-23) notation -SHIFT_TIME_START_HOUR 7 - -## Sets shift time to server time at roundstart. Overrides SHIFT_TIME_START_HOUR -#SHIFT_TIME_REALTIME - -## Enable randomized shift start times. Overrides SHIFT_TIME_REALTIME and SHIFT_TIME_START_HOUR -#RANDOMIZE_SHIFT_TIME - ## A cap on how many monkeys may be created via monkey cubes MONKEYCAP 64 diff --git a/config/iceruinblacklist.txt b/config/iceruinblacklist.txt index f617b78e305..7276cb874a5 100644 --- a/config/iceruinblacklist.txt +++ b/config/iceruinblacklist.txt @@ -5,6 +5,7 @@ ##RESPAWN #_maps/RandomRuins/AnywhereRuins/golem_ship.dmm +#_maps/RandomRuins/AnywhereRuins/shoe_factory.dmm #_maps/RandomRuins/IceRuins/icemoon_underground_comms_agent.dmm #_maps/RandomRuins/IceRuins/icemoon_underground_hermit.dmm #modular_skyrat/modules/mapping/_maps/RandomRuins/IceRuins/icemoon_underground_syndicate_base1_skyrat.dmm diff --git a/config/lavaruinblacklist.txt b/config/lavaruinblacklist.txt index a5ce5abcd17..23c4a1c7d85 100644 --- a/config/lavaruinblacklist.txt +++ b/config/lavaruinblacklist.txt @@ -17,6 +17,7 @@ _maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm #_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_ash_walker1_skyrat.dmm #_maps/RandomRuins/AnywhereRuins/golem_ship.dmm #_maps/RandomRuins/LavaRuins/bubberstation/lavaland_dauntless.dmm +#_maps/RandomRuins/AnywhereRuins/shoe_factory.dmm ##SIN #_maps/RandomRuins/LavaRuins/lavaland_surface_envy.dmm diff --git a/html/changelogs/AutoChangeLog-pr-95773.yml b/html/changelogs/AutoChangeLog-pr-95773.yml deleted file mode 100644 index 715e024a73f..00000000000 --- a/html/changelogs/AutoChangeLog-pr-95773.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "timothymtorres" -delete-after: True -changes: - - bugfix: "Fix window spawners not being dense, which affected random spawners LOS boundaries." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-95780.yml b/html/changelogs/AutoChangeLog-pr-95780.yml deleted file mode 100644 index 592be626dc0..00000000000 --- a/html/changelogs/AutoChangeLog-pr-95780.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Yobrocharlie" -delete-after: True -changes: - - bugfix: "Removes inert wands of fireball and healing from the academy, apparently inert doesnt mean not working but just fewer charges." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-95788.yml b/html/changelogs/AutoChangeLog-pr-95788.yml deleted file mode 100644 index 4de607909a3..00000000000 --- a/html/changelogs/AutoChangeLog-pr-95788.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Hardly" -delete-after: True -changes: - - bugfix: "Kitsune mask no longer keeps the user's identity hidden while it's flipped" \ No newline at end of file diff --git a/html/changelogs/archive/2026-04.yml b/html/changelogs/archive/2026-04.yml index 0afd50854dd..45ce5ab8a93 100644 --- a/html/changelogs/archive/2026-04.yml +++ b/html/changelogs/archive/2026-04.yml @@ -346,6 +346,12 @@ timothymtorres: - server: Optimized CI workflow to skip map-specific linters when no maps are modified. 2026-04-17: + 00-Steven: + - bugfix: Books no longer get trimmed below the paper length limit. + - bugfix: Books made using paperwork created with multiple inputs no longer put + all that text on the same line. + Hardly: + - bugfix: Kitsune mask no longer keeps the user's identity hidden while it's flipped Melbert: - rscadd: Traitor Lawyers, Quartermasters, and Heads of Personnels can now purchase a "Briefcase Embedded Firearm Trigger" from the uplink for 4tc - a briefcase @@ -357,3 +363,291 @@ This can also appear as a medium Spy reward. - balance: The Spy item "boot dagger"'s examine tell now only appears if you're examining them WHILE holding them. + Yobrocharlie: + - bugfix: Removes inert wands of fireball and healing from the academy, apparently + inert doesnt mean not working but just fewer charges. + timothymtorres: + - bugfix: Fix window spawners not being dense, which affected random spawners LOS + boundaries. +2026-04-18: + RusselNotSCP: + - rscadd: The Pousse-Cafe's recipe has been changed to require more exotic liqueurs + - qol: The Improved Whiskey Cocktail's recipe has been changed to make it easier + to handcraft + combustor: + - balance: Removes the minimum APC requirement for robofactories + lelandkemble: + - bugfix: stimulants properly regenerate stamina in otherwise healthy people +2026-04-19: + Melbert: + - bugfix: Removing brain updates the med hud + vinylspiders: + - bugfix: changing your gender choice in character prefs no longer modifies your + physique preference +2026-04-20: + ArcaneMusic: + - spellcheck: corrected some instances within TGC cards to say "plasma" instead + of "mana" when referring to card costs. + Jacquerel: + - rscadd: Adds 16 more wizard wands to the game, which wizards can buy cheaply but + randomly, or are available via Summon Magic. + - rscadd: If a wizard buys more than one set of wands they will receive a "Wand + Bandolier" holster which fits in the backpack or, if worn in the suit slot, + will automatically exchange an expended wand for a full one. + - balance: Staffs (and wands) of animation that are animated will try to animate + other objects instead of firing at living mobs, which are already animated. + - balance: Animating a wand of nothing will turn it into a wand of animation (and + animate it). + - balance: The staff of chaos can now do more things. + - balance: Magicarp now additionally come in Babbling, Frigid, Quantum, and Weightless + varieties. Collect them all! + Melbert: + - bugfix: Heretic "research knowledge" objective no longer undershoots the target + value by ~8-10 + - balance: You can no longer dismount riders from ponies with a single click. Instead, + there is a chance to dismount the rider on shoving the pony OR the rider, based + on multiple factors (such as stamina + physical damage and stagger) + - balance: The Leaper mount also has this "disarm to dismount" mechanic, though + it is significantly more difficult as they are much sturdier beasts + - balance: Upon being successfully sacrificed by a heretic all other heretics lose + you as a target, and you can no longer be (re)rolled as a target by other heretics. + SmArtKar: + - balance: Ship from a bottle can now be bottled back up by alt-clicking it + - balance: Ship in a bottle can now be deployed by throwing it, and are a small + item instead of normal-sized + - spellcheck: Boats no longer refer to oars as keys + - bugfix: Transforming items like eswords should no longer get absurd stats when + metalgenned multiple times in a row + SmArtKar, Kryson, ArcaneMusic: + - rscadd: 'Lavaland has received 2 new rock types: Siderite, rich in iron and titanium, + and Shale, full of plasma, gold and uranium.' + - rscadd: A guaranteed river spawn and a fishing pond have been added to the lavaland + outpost raptor area. + - rscadd: Ores now tend to spawn in veins or clusters, and are much more likely + to spawn near exposed rock. + - balance: Natural ore spawns are much more abundant than before, closer to pre-arcmining + levels. Vent output has been halved + - balance: PKA AOE mining module has been reverted to 3x3 and incurs a cooldown + penalty + - balance: Plasma cutters eat more plasma when recharging and have slightly shorter + range. + - balance: Mining MOD sphere mode no longer instamines, and now just has an extremely + high mining speed. + - balance: Goldgrubs can now tunnel extremely fast and spawn much more frequently + than before. Goldgrub burrowing can be interrupted by dealing damage to them. + - balance: Goldgrubs no longer reflect non-bomb/energy shots. + - balance: AOE mining methods now have a 10/25% chance to not mine siderite/shale + unless it has ore inside of it. + - refactor: Lavaland generation has been rewritten. The caves should be much more + wilder. + SyncIt21: + - bugfix: AI camera mode works from any distances + TheRealSpriteMan1337: + - image: Omega soap texture has been updated. + TheRyeGuyWhoWillNowDie: + - bugfix: welding goggles now only cover your eyes when covering your eyes + Y0SH1M4S73R: + - balance: Wizards with the Heart Eater perk are only invigorated by the hearts + of sentient beings. + - rscadd: To facilitate the taking of hearts from sentient beings, the Heart Eater + perk lets you tear the heart out of the chest of an incapacitated or dead being + by targeting their chest with an empty hand in combat mode. + Yobrocharlie: + - rscadd: The heretic gateway now has a 40mm cannon in it. + lelandkemble: + - bugfix: Janiborgs will no longer track blood while autowashing + - bugfix: Fixes one way to get stuck in place forever while using a fulton extraction + kit + necromanceranne: + - qol: The detective's noir fedora is actually a detective fedora, and gets all + the unique qualities expected of one. +2026-04-21: + Ben10Omintrix: + - balance: the grapple gun's price has been reduced to 1500 points + LT3: + - bugfix: Fixed loss of credits for correctly denied minerals market cargo manifest + - bugfix: Cargo budget materials market orders arrive in crates as expected + Pumpkinoe: + - map: Centcom's ERT wing has been updated, including a new door that leads directly + to the pod bay and buttons to control the doors! + Yobrocharlie: + - rscadd: added more things to the antag gear spawner +2026-04-22: + ArcaneMusic: + - bugfix: More safeguards were added to the admin "Create Black Market Item" verb. + Melbert: + - rscadd: Spacers who manage to get nograv while on a planet are given a positive + moodlet, and are considered in space for the purpose of their buffs/debuffs + TheBoondock: + - refactor: refactored majority of gas_mix mole change into adjust_gas() proc + lelandkemble: + - bugfix: Butchering heads no longer moves their organs to nullspace, and probably + the same with any other method of mass removing organs. + vinylspiders: + - bugfix: fixes an issue where raptor chicks and other non-items appearing in item + contents would prevent any personal crafting in the vicinity +2026-04-23: + 1393F: + - bugfix: The mushroom bowl no longer turns invisible when filled with a reagent. + Absolucy, LemonInTheDark: + - bugfix: You can no longer see lights through walls when using mesons or when ventcrawling. + ArcaneMusic: + - qol: The GMM Ui can now tell you the minimum and maximum price ranges that a material + will sell for. + - qol: You can now sell materials on the edge of their buying and selling thresholds. + (This really only effects iron and glass, practically) + - rscadd: The boulder smelter and refinery may now take a plumbing input (Closely + examine to see the full list) to boost the mineral output of processed boulders. + - rscadd: Boulder refinery machines will produce a new chemical, industrial waste, + which must be managed, dispersed, or it will eventually overflow if too much + exists in the same container. + - balance: The smelter and refinery now produce less mining points per unit than + before, but the quantity of points are now better scaled to the quantity processed. + 50% more ores means 50% more points. + - balance: The amount of points generated per ore within boulders is now a separate + variable, not a percentage of the base value. This means some ores are better/worse + for generating mining points as a result. + - balance: Completing wave defense will award 200 more points across all ore vent + tiers, 700/1200/1700 for small/medium/large vents. + ElGitificador: + - balance: mutations coming from most random mutation sources can now be saved in + dna consoles + Ghommie: + - bugfix: Packs exclusive to the express console (crab rockets for example) can + now be ordered from express consoles. + Happyowl93: + - code_imp: makeHologram now allows a color override. + JohnFulpWillard: + - rscadd: You can Ctrl Click a camera to set it to print monochrome photos. The + detective's camera is on this mode by default. + - qol: Photos without a scribble written on them won't have empty white space at + the bottom. + Melbert: + - balance: Codex Cicatrix is now a tier 1 heretic knowledge, and can not be drafted. + - balance: Warren King's Welcome is now a tier 1 heretic knowledge, but can be drafted. + - balance: Warren King's Welcome soft reworked. Now needs 10 cable, 1 paper, 1 multitool. + Now adds access to all IDs present, including worn IDs. Now adds "heretic" access + to the ID card. Now changes all nearby airlocks to require "heretic" access, + and cuts the AI wire. + - balance: Eldritch ID card starts with "heretic" access. + - admin: Adds toggle for meteor mode in secrets + - rscadd: Some EVA helmets now have retractable visors, which you can pull up or + down at will, to reveal your face. + - balance: The amount of blood loss from an attack to an already bleeding wound + has been tweaked. As an example, a 20 force attack used to range 0.1% to 4% + blood loss, and now ranges 1% to 3%. + - bugfix: Plasma works in IEDs again + SmArtKar: + - admin: Planemaster Debugger now has a text search input to locate and jump to + planes + TealSeer: + - bugfix: fixed CSS-related errors in BYOND 516.1681+ + levels0: + - bugfix: metalgen and secret sauce recipes are now loaded properly + timothymtorres: + - map: Add Shoe Factory to lava/ice ruins. +2026-04-24: + lelandkemble: + - bugfix: Looming works again +2026-04-25: + Arturlang: + - rscadd: changes shutter and high security door sprites on the infiltrator battlecruiser + and the syndicate nuclear operative base + Ben10Omintrix: + - refactor: beepskies, and ed209s have been refactored. please report any bugs + - rscadd: ed209s can now wear hats! some hats give them new dialogue + - rscadd: emagged ed209s are now rideable! + - rscadd: added evil versions of the ed209s to the syndie uplink + Capsandi: + - sound: fire alarms are no longer stereo files condensed to mono at runtime + forgman6: + - rscadd: Saviors paper hat. + - rscadd: Added worn and normal icon states for it in costume.dmi + - map: Modified bus.dmm to include the paper hat behind the main bus. + lelandkemble: + - bugfix: Stamina bars no longer invert the value they show you + - bugfix: Nonbinary people can respawn +2026-04-26: + Aliceee2ch: + - bugfix: LIttle map fixes for lavaland. + JohnFulpWillard: + - rscdel: Removed Station Time, now we use NST (Nanotrasen Standard Time), which + is IRL server time +540 years, and PT (Pay Time), the amount of time since the + round has started. + - rscdel: Station nightshift is now a Station event rather than being based on Server + time. + - balance: Time circuit's Unit of Measure now tells the amount of time in hour/minute/seconds + rather than giving the whole time translated to hours/minutes/seconds. + - qol: Added a 12-hour clock pref for people who prefer it. + - qol: Hovering over NST timestamps on official documents will now translate how + much it is in PT/Shift Time. + - admin: Admins can now use style/class/background in their papercode. + - qol: Pray verb is now a hotkey, Whisper is now a command bar button, and all say + verbs have been removed from the stat panel. + - qol: Admin button on the escape menu is now its own section for praying, as well + as seeing your latest ticket & admin notes. + - bugfix: Resizing the stat panel will no longer change the size of the command + bar. + Rhials: + - bugfix: The bear mask in the pizzeria virtual domain is now a regular, non-cursed + mask. + Ruslanllll: + - bugfix: Alien plasma display works again + lelandkemble: + - bugfix: Ninja spider bomb can no longer be placed in certain situations it would + be unable to detonate + vinylspiders: + - bugfix: mobs and features should not be spawning in walls anymore in certain biomes +2026-04-27: + levels0: + - bugfix: metalgen and secret sauce should now generate properly +2026-04-28: + ArcaneMusic: + - bugfix: Mice now have a movement sprite going both east and west. + - qol: Added a sound effect when a geyser is properly scanned. + ElGitificador: + - bugfix: fixed heretic gate cam appearing in on station ss13 network + SmArtKar: + - bugfix: Fixed plasma cutter recharging + levels0: + - bugfix: molt'obeso sauce will no longer appear as an ingredient in random recipes + vinylspiders: + - bugfix: fixes blue and green cybernetic cat ears being switched +2026-04-29: + Dmeto: + - map: IceBox station boulder processing no longer exposed to outside. + ElGitificador: + - bugfix: hierophant achievement can now be obtained from 1 tile away of it s final + blast + Melbert: + - rscadd: Adds the Sect of the Dream God, a new option for chaplains. + - qol: Drinking soup from a bowl no longer yells at you in big text + tmyqlfpir: + - rscadd: Added USB interface to emitters, temperature pumps and temperature control + unit machines + vinylspiders: + - bugfix: fixes a few instances of crowbar deconstruction not working for certain + items + - refactor: extends the tool_blocker element to support secondary tool_acts +2026-04-30: + DresserOnFire: + - bugfix: Fixes a bug where player-controlled basic mobs would get a cooldown when + their attacks miss + - refactor: basic mob attack chain can now decided whether an attack resulted in + a cooldown or not. + Jacquerel: + - bugfix: The Hierophant Club will stop glowing when you can't use it to teleport + - image: Updated the Hierophant Club so that it looks like the Hierophant + SmArtKar: + - bugfix: Fixed circuits bluescreening whenever you try to put text or numbers into + a STRING or ANY type field + dresseronfire: + - bugfix: You can now sic pets onto targets again + - bugfix: Pointing at things no longer sometimes points at the wrong thing + lelandkemble: + - bugfix: Cables without power no longer produce sparks when placed + necromanceranne: + - rscadd: Gives the Cybersun reinforcement a new outfit. + - rscadd: No new items were added to the black market. None. Honest. + timothymtorres: + - bugfix: Fix large bulky toys from being stored in suit storage diff --git a/html/changelogs/archive/2026-05.yml b/html/changelogs/archive/2026-05.yml new file mode 100644 index 00000000000..586c9975988 --- /dev/null +++ b/html/changelogs/archive/2026-05.yml @@ -0,0 +1,614 @@ +2026-05-01: + TheRyeGuyWhoWillNowDie: + - qol: hyposprays can now draw from other reagent containers +2026-05-02: + Hatterhat: + - qol: The style meter for miners now stores its permanent multiplier on the meter + in case you're switching eyewear. The style meter item is now small, allowing + for easier storage. + lelandkemble: + - bugfix: Mjolnir only successfully attacks if it successfully attacks + necromanceranne: + - bugfix: Void cloaks no longer obstruct surgery while invisible. +2026-05-03: + Aliceee2ch: + - bugfix: Fixed color matrix not applying in reskinnable item preview. + Melbert: + - bugfix: Fix some erroneous dream portents from showing up + lelandkemble: + - code_imp: Things that interrupted the opening of storages are no longer reliant + on a runtime, meaning they interrupt regardless of whether you had another open + storage open at the time + - balance: Blood from blood bags is fully synthetic + vinylspiders: + - code_imp: fixes mining mobs being able to spawn too close to one another under + certain circumstances +2026-05-04: + SmArtKar: + - admin: Added a new debug tool which displays a detailed breakdown of in-game visuals +2026-05-05: + Absolucy: + - qol: Changed how chat highlights are styled - any color should look good now, + regardless of light or dark mode. + LT3: + - balance: Cargo manifest stamp payments/penalties are now consistently applied + as a percentage of the order value + - balance: Maximum payment for an approved cargo manifest raised to 120cr + - balance: Cargo orders that arrive empty and stamped denied receive a full refund + regardless of crate return + Melbert: + - refactor: Refactored hair and eye rendering a bit, they're now rendered separately + to the head - report any oddities with either. Lips too but to a lesser degree. + - rscadd: Adds Penguin tier zero gene infusion (gives you penguin ears, which make + you waddle) + - rscadd: Adds Plant tier zero gene infusion (gives you plant hair / organs, which + do nothing) + - rscadd: Adds Stoat tier one gene infusion (makes you tall, snouted, gives you + finer instincts, allows you to dodge large foes) + - rscadd: April 26th is Chernobyl Disaster Remembrance Day. + Time-Green: + - rscadd: Adds three new maintpill-only chems! Go eat more maintpills, and maybe + you'll find out what they are :) + - rscadd: Adds a new secret chem, which can rarely be found on a petrified piece + of paper somewhere in maintenance... + - bugfix: Fixes miscellaneous sources of petrification lasting 10x as long as intended + Y0SH1M4S73R: + - rscadd: Ghosts and spirits have once again been split into two species. Becoming + a ghost is only possible through a lucky polymorph, or the "Forsake Body" spell, + available for two points in a wizard's spellbook. + - rscdel: Spirits no longer have the passthrough ability. + - balance: Ghost's passthrough ability has unlimited range and no longer leaves + behind a grave. It is affected by holy water, and makes you drop all your equipment, + along with any bodyparts and organs that are not ghostly in nature. + lelandkemble: + - bugfix: You can now get the paddles from a compact defib by clicking on it + strandsofivy: + - bugfix: The PDA direct messenger will no longer overzealously break words, resulting + in cleaner chat message formatting overall. + vinylspiders: + - admin: invisimin now makes the admin invisible to ghosts/observers, as well as + pierce-immune and able to phase through walls + - qol: aghosting while invisimin'd or stealthmin'd will carry over your invisibility + to the aghost so you no longer have to trigger it again + - admin: added a new admin verb, 'Toggle Admin ESP', which lets you see ghosts and + invisimins while active +2026-05-06: + Absolucy, vinylspiders, neocloudy: + - rscadd: Added a pair of signboards that can be crafted in the crafting menu, a + wooden one, and a holographic one. Perfect for advertising or otherwise getting + your VERY important message across to passersby. + Hatterhat: + - admin: Admins can now varedit blob overminds (the eye mob) to not kill everyone + on the station if they hit critical mass. (Admins will still have to remove + the blob from the shuttle subsystem's "hostile environments" tracker, though.) + lelandkemble: + - bugfix: animating a wand of animation works, and that animated wand of animation + animating a wand of animation does not runtime + vinylspiders: + - code_imp: speeds ghost runechat up a bit, and makes it show as italic + - admin: adds a 'toggle dead runechat' admin verb in case you need to disable it + midround for an event or something +2026-05-07: + ArcaneMusic: + - rscadd: Adds the E-2 Earthcracker device as a purchasable traitor item for 2 TC. + Use it to create potentially devastating weakpoints onto the station! + Higgin: + - bugfix: positive viruses no longer self-cure when not having spaceacillin or meeting + the nutrition/satiety requirements. + Melbert: + - bugfix: Facial hair color can be separate from hair color again + - bugfix: Hair covering things update when they need up + Shroopy: + - bugfix: Fixed syndicate bombs having a maximum timer of 1000 minutes instead of + 100 minutes. + SmArtKar, SentryPrimis: + - rscadd: Siderite and Shale lavaland biomes now have unique floors, as well as + flora, features and fauna! + - bugfix: Fixed some ruins generating with default basalt walls instead of their + biome's walls +2026-05-08: + TheRyeGuyWhoWillNowDie: + - balance: Granibitaluri heals 1.5 brute and burn at best now, and scales down to + 0.5 at worst. + Y0SH1M4S73R: + - balance: You can no longer get Xenomicrobes and Nanomachines from botany mutations. +2026-05-09: + 1393F: + - bugfix: The crystallizer can be rotated once again, on left click + FalloutFalcon: + - bugfix: Drying rack no longer accepts or processes dried items + JohnFulpWillard: + - rscadd: Reorganized the UI around the game; the title bar has been removed in + favor of the old info buttons (top right of the screen), which now has some + new buttons for you. + - rscadd: The Status Panel is now able to be retracted with one of the infobuttons. + - qol: You can now go directly to your hotkey settings from your hotkeys help page. + Melbert: + - rscadd: Spacers are now "very tall" again, rather than just "decently tall". + - qol: Tweaks message displayed when examining recovered crew / thanatorenaisa bodies + - bugfix: Some masks no longer hide lizard frills. + - rscadd: Hats that flatten hair now also flatten lizard frills a bit. + Neocloudy: + - sound: Restored fire alarm sound quality + SmArtKar: + - rscadd: Mining mobs now use priority when choosing their target, prioritizing + NODE drones over miners who haven't attacked them or their allies + - bugfix: Removed a rogue syndiedome ruin decal + lelandkemble: + - bugfix: SyndEye PDA app tracking tracks successfully + - bugfix: You no longer need traitor on to get syndicate monkey or contractor ghost + polls, & banning from these roles bans from the polls as well +2026-05-10: + Melbert: + - balance: Cuffing items to yourself no longer prevents you from dropping or being + disarmed of the item- instead, the item becomes "chained" to you, forcing it + to stay within one tile's reach under all circumstances. + - balance: You can cuff shields to yourself again. Unless we figure out it's still + oppressive in which case it'll probably be removed (again) + - bugfix: IV drops should break your character's offsets less often +2026-05-11: + Aliceee2ch: + - bugfix: RND servers are visible once again. + CabinetOnFire: + - bugfix: Fixes the spawn panel being unable to spawn turfs + Melbert: + - bugfix: You can speak with a stoat tongue + - bugfix: Stoat infusion is slightly taller + - bugfix: Explosions won't remove organs from skeletons/plasmamen + - code_imp: Solar arrays don't check for the pressence of space vines every process + tick + - code_imp: Changes the way tongues allow you to speak correctly to make them less + prone to fault + - bugfix: Re-adding limbs surgically requires you do surgery again (ie, incise -> + retract -> clamp). + Time-Green: + - bugfix: Fixes voidwalker being unable to vomit jump if anyone vomits on a non-station + z-level + Y0SH1M4S73R: + - rscadd: Random polymorphs can turn you into hatchling blood worms that can mature, + but not reproduce. + vinylspiders: + - bugfix: disable dead keyloop lagswitch measure now properly affects new ghosts, + and fixes an issue where people can revive and still be frozen +2026-05-12: + Melbert: + - bugfix: Blocks two people cuffing to one item + SmArtKar: + - rscadd: Mining MOD sphere mode now fires a barrage of micromissiles instead of + a singular delayed explosive + - balance: Raptor are now immune to ice slippage + - balance: Mining MOD has had its ore digging speed increased + - bugfix: Buckled mobs can no longer "slip" (get stunned) on wet/icy tiles. + SmArtKar, thgvr: + - balance: Goliaths no longer hardstun, but instead bind and drag their targets + in with their tentacles. They are, however, much faster now. + - balance: Brimdemon beams can no longer wound, but deal a bit more DOT damage. + Their beams can also be interrupted by hitting them from the side or back in + melee. + - balance: Watchers and legions now try to maintain a few tiles of distance from + their targets instead of retreating. + - bugfix: Lobstrocity AI should no longer sometimes flee out of their aggro range + when retreating. + Y0SH1M4S73R: + - spellcheck: You are told you are downed instead of unconscious if you attempt + to use an action that requires you to be conscious while in softcrit. + kuricityy: + - balance: Flesh spiders are now slightly slower than your average spessmen. (10%) + - balance: Flesh spiders now regenerate after 3 seconds of not taking damage, compared + to 4. + lelandkemble: + - bugfix: sinks(and other methods of washing) clean out petri dishes + - rscadd: Added a new traitor item, Carnivorous Blood. It is purchasable in uplinks. + Carnivorous Blood is a reagent that eats away at a victim's blood once in their + bloodstream, doing so significantly faster if it has been mixed with the victim's + blood beforehand. + timothymtorres: + - bugfix: Fix shock immunity flag not working when electrocution occurs +2026-05-13: + Absolucy, SmArtKar: + - qol: The color changing from regenerative rainbow, adamantine, and stabilized + pyrite extracts now looks far better. + - qol: The protection effect from regenerative rainbow extracts now actually makes + you all rainbowy. + - code_imp: Minor improvements to crossbreed status effect code. + CabinetOnFire: + - refactor: Implements "Event Logging" an improved way for programmers to debug + specific datums. + ElGitificador: + - bugfix: fixes a certain explosions message related to influences + Glu-furro: + - rscadd: 'Increased max prisoners from 2 to 4. + + :cl:' + Happyowl93: + - bugfix: fixes material floor duplication + necromanceranne: + - qol: Your overall athletics level is what protects you from a random heart attack. + If you achieve peak fitness, you are immune to random heart attacks. +2026-05-14: + ArcaneMusic: + - qol: Grills now have screentips when using tools on them. + - qol: In-line with other deconstruction processes, grills now deconstruct on right + click. + Derpguy3: + - bugfix: The door control button in Deltastation's medical desk works again. + Iamgoofball: + - rscadd: You can now print basic wet floor signs at the Service Protolathe, because + you couldn't actually print them for decades. + Melbert: + - rscadd: You can purchase (lower quality) broadcast cameras in cargo for 800cr + TealSeer: + - bugfix: fixed arming grenades not being logged + TheRyeGuyWhoWillNowDie: + - spellcheck: nspect scanners no longer claim to be capable of area scans + carpotoxin: + - rscadd: Adds the Deep Space deathmatch map + lelandkemble: + - bugfix: The Junkie quirk gives you the addiction you ask it for + - bugfix: Ghost role mobspawner bans work again + - spellcheck: Users of a Gaseous holoparasite no longer appear to repeatedly catch + fire when they are not. + - bugfix: You can unbuckle people from wheelchairs again +2026-05-15: + JohnFulpWillard: + - bugfix: Stat panel's "Toggle Stat Panel" button now works. + - bugfix: People who re-enter their body can now exit again by moving. + lelandkemble: + - spellcheck: The Moon path armor knowledge's description has been made more clear +2026-05-16: + Aliceee2ch: + - map: Genetics Lab was made less secure and more public on every map, try it out! + Melbert: + - balance: 'Spacer: Reduction to cold damage increased from 20% to 33%' + - balance: 'Spacer: Reduction to pressure damage increased from 20% to 33%' + - balance: 'Spacer: Zero gravity drift speed increased from 20% to 25%' + - balance: 'Spacer: Zero gravity floating speed increased from 10% to 15%' + - balance: 'Spacer: Move speed penalty on planetary maps reduced from 25% to 15%' + - balance: 'Spacer: Passive effects now trigger every second, rather than every + three seconds' + - balance: 'Spacer: Disgust healing modifier while in zero gravity increased from + 1x to 2x' + - balance: 'Spacer: Passive stun reduction in zero gravity changed from 3 seconds + per 3 seconds to 2 seconds per second' + - balance: 'Spacer: Passive stamina healing in zero gravity changed from 3 stamina + per 3 seconds to 4 stamina per second' + - balance: 'Spacer: Passive stun reduction in zero gravity now activates after 10 + seconds in zero gravity, down from 3 minutes' + - balance: 'Spacer: Passive stamina healing in zero gravity now activates after + 1 minute, down from 3 minutes' + - balance: 'Spacer: After being in zero gravity for 10 seconds, also reduces duration + of knockdown effects by 25%' + - refactor: Refactored bane, which is the bonus some items get to damage vs specific + mob types. Report any oddities or weird damage numbers you notice. + - balance: Flyswatter damage scales the same across all mob types (if you get a + +3 flyswatter you no longer one shot mothpeople) + - balance: Bonus damage from "bane" no longer ignore armor unless the weapon itself + does + - qol: All bane effects are now agnostic to combat mode, meaning they don't require + you be on combat mode to apply the bonus damage. + - qol: Item with bane effects have an indicator about their effect in their combat + label + - bugfix: sfx that plays when entering historian mode of a trophy case is no longer + mute +2026-05-17: + JohnFulpWillard: + - bugfix: Multiple crab17 crashes will now individually affect you and require you + to visit each one. + timothymtorres: + - bugfix: Fix holodeck mob organs and body parts not disappearing. Any holodeck + mob organs and body parts can also no longer be bioscrambled. +2026-05-18: + Grammi: + - qol: Guardian granters (holoparasites injectors, dusty shards, etc) now show if + they've been used on examine. + Hatterhat: + - bugfix: Bluespace launchpads are no longer invisible when deployed. + - bugfix: Briefcase launchpad remotes now have a functioning reset button. + - bugfix: Quantum pads now use their screwdrivered-open state when depowered. + - image: Deep fryers now have a sprite with an open maintenance panel instead of + becoming invisible when screwdrivered. + Melbert: + - qol: Thermite chemical reaction is tagged as "Damaging", making it easier to refer + to. + - rscadd: '[Icebox] Security saw a minor remapping, with most notably the removal + of the labor shuttle and the integration of the labor camp into the bottom floor + of the perma-brig.' + SmArtKar: + - bugfix: Stumps no longer give a reattachment moodlet to mobs + SyncIt21: + - qol: plumbing assimilator has higher heating coefficient to that of tier 3 chem + heater + emicchinya: + - spellcheck: Target Left arm, Right arm, Left leg and Cycle head keybinds are now + capitalized properly. + timothymtorres: + - map: Add human limbs to the holodeck medsim organ crate +2026-05-19: + ArcaneMusic: + - bugfix: Hydroponics trays will no longer produce pollen particles if the plant + in the tray has died. + - bugfix: Restocking a vending machine can no longer produce a zero credit holochip. + SmArtKar: + - bugfix: Fixed changeling tentacles not being able to fire + - bugfix: Pre-equipped shaft miners and handyman assistants now start with imprinted + PDAs like the rest of the job outfits. + TheRyeGuyWhoWillNowDie: + - map: fixed active turfs on shoe factory ruin + Wisemonster: + - rscadd: Added beartraps to the janitor closets of wawastation and icebox +2026-05-20: + JohnFulpWillard: + - bugfix: Mafia players now get sent back to their bodies again post-game. + - admin: Admin players aren't forcefully put back into aghosted bodies after using + a temporary body spawner. + - admin: Changing lobby music now updates for people in the lobby. + Melbert: + - bugfix: Fixed issues that arise from picking up two items cuffed to the same person + - bugfix: Fixed issues that arise from picking up two items cuffed to two different + people + - bugfix: Fixed issues that arise from traveling z-levels while having a cuffed + item + RusselNotSCP: + - qol: Aperitivo Liqueur's hunger inducing effect has been reduced + - qol: The Negroni and Spritz cocktails no longer induce hunger and now only reduce + overfull-ness + SmArtKar: + - bugfix: Fixed shale and siderite biomes not spawning any features or mobs +2026-05-21: + CabinetOnFire: + - bugfix: Fixes an issue were bots would try to blacklist qdeleted atoms + EnterTheJake: + - bugfix: Attaching a different head onto a Aura Heretic's body won't apply the + aura. + Wisemonster: + - code_imp: Nuclear reinforcements will now poll users with the mid-round nuke op + pref enabled, rather than the round-start pref. + lelandkemble: + - qol: Singularity beacon pulls singularities even if they were created after the + beacon's activation + - bugfix: right clicking an abandoned crate with a multitool no longer can blow + you up + - bugfix: Sealable biscuits can only be sealed once + mcbalaam: + - rscadd: Big Manipulators now use a single task loop instead of two separate point + loops. +2026-05-22: + SmArtKar: + - bugfix: Crematorium can no longer destroy indestructible objects + - code_imp: Cleaned up crematorium code + - bugfix: Bubblegun suicide no longer makes the user yell out HTML + - bugfix: Beepsky Smash beepskys now use proper text formatting + - code_imp: Cleaned up say span code in a few places + Y0SH1M4S73R: + - rscadd: Committing suicide with an empty soul shard seals your soul within it. + - balance: Taking damage from an attack while dosed with synthpax negates the pacification + from the synthpax for an amount of time equal to the damage taken, up to a maximum + of 5 seconds. + lelandkemble: + - bugfix: about a billion runtimes per round have been fixed, & you'll no longer + repeat what you said last when you're forced to speak + - bugfix: The dead can't drive +2026-05-23: + Higgin: + - bugfix: A single space twinkie no longer cures a virus or makes it harder to get + rid of one. + Melbert: + - refactor: Refactored how digitigrade and snouts render, report any oddities with + that + SmArtKar: + - bugfix: Having only midround clown ops (but not normal clown ops) enabled in antag + prefs now displays operative alias/species toggles + - admin: Added clown ops to the ban panel + - bugfix: Fixed materials runtiming whenever thrown by something other than a mob + - bugfix: Fixed custom pizzas having broken sprites and not preserving their ingredients + when sliced + - bugfix: Fixed plumbing ducts having weird shadows + - bugfix: Fixed certain reaction overheats being always treated as impure + - bugfix: Being shapeshifted while rolling midround traitor no longer robs you of + your uplink + SmArtKar, ArcaneMusic: + - balance: Bileworms now fire arcing shots instead of cross patterns, and can be + stunned by hitting them during the burrow animation. Their health has been slightly + buffed to compensate. + SyncIt21: + - bugfix: opening panel of boulder refinery with screwdriver or un-wrenching it + turns of its light + - bugfix: boulder refinery only takes in booster reagents and excludes others and + only outputs waste chemicals as intended + - bugfix: boulder refinery machines outputs waste reagents without rounding errors + in them + - qol: removed conveyer sprite from boulder smelter & pixel shifts the refiner so + you can see it's plumbing pipes properly + Time-Green: + - rscadd: Adds Interface Science! There's these strange contraptions in science, + who knows what they do? Figure it out, and make them usable! + lelandkemble: + - bugfix: Several ways you could become permanently immobile, primarily based around + lube & other methods of slipping, have been fixed + timothymtorres: + - map: Added a "Prison Block" holodeck simulation, accessible via the disabled safety/emagged + menu. + - code_imp: Fixed electric chairs to work, and they now bypass insulation from gloves + when executing a mob. + - code_imp: Added holodeck versions of brig lockers and windoors that allow anyone + with a station ID card to access them. + tontyGH: + - bugfix: Blunt/sharp weapons no longer slice through your coagulants when you are + dismembered + - bugfix: Burn weapons now remember that they cauterize instead of slice when dismembering +2026-05-24: + Holoo-1: + - bugfix: fixed camera static not being removed for console users when it was observed + by AI and console user + SyncIt21: + - qol: merged large welding tool tank with engi omnitool for engiborg + - bugfix: examining the omnitool will reveal details about its internal tool such + as multitool buffer, welding fuel left etc + TealSeer: + - image: lights on security cameras glow in the dark now + Wisemonster: + - bugfix: Fixed cyborg's recharging guns not recharging + levels0: + - rscadd: you can now trap dormant revenants in mirrors + - rscadd: haunted mirrors may very rarely appear roundstart + soulware1: + - rscadd: New reactions for water variants that make foam + - code_imp: New foam types that either slip or last longer or shorter +2026-05-25: + ElGitificador: + - sound: added sound feedback to supplexing a rod + Melbert: + - balance: 'Spacer: Bonus to drift speed no longer stacks with jetpack speed - only + the greater of the two effects is applied.' + SmArtKar: + - admin: Added conversion and deconversion logging to Lunatics +2026-05-26: + ArrisFairburne: + - qol: Added more description text to tank transfer valves so it's clearer what + can be done with them + - qol: Clicking on a tank with a tank transfer valve will now attach it directly + ElGitificador: + - sound: supplexing rods sound fix + EnterTheJake: + - bugfix: Traitor Wraith cloaking module now reactivates after the appropriate amount + of time has passed. + Fghj240: + - balance: mending touch can partially heal limbs + - balance: mending touch no longer always transfers critical wounds when powered + up + - bugfix: mending touch blood drain properly capped + - code_imp: removed unnecessary check from mending touch + - spellcheck: mending touch lose text reworded for clarity and it no longer assumes + you only have one hand. + FlufflesTheDog: + - bugfix: Fix an error when trying to use the cargo app with an id card lacking + a job + - bugfix: Fix sometimes spawning with a scarred eye despite not having the quirk + JohnFulpWillard: + - bugfix: pAIs can use their instruments. + SmArtKar: + - bugfix: Fixed inventory items being stuck in ghosts' screens + TheRyeGuyWhoWillNowDie: + - bugfix: the your mother hallucination for plasmapeople shows the plasmapersons + actual mother + Thunder12345: + - bugfix: The stray slow tile in Icebox perma has been removed. + Thunder12345 and Hugbug: + - bugfix: CQC can no longer steal backtank misters and other tethered items. + lelandkemble: + - qol: Scanned wounds stay scanned while being healed + - bugfix: Ghost of Poly possession pulses the purple aura like it's supposed to + strandsofivy: + - bugfix: AIs should be able to access request consoles correctly now. + timothymtorres: + - bugfix: Fix negative bloodloss effects being ignored by determined status + vinylspiders: + - bugfix: internal organs should not trigger needless updates in the char preview + anymore +2026-05-27: + SirNightKnight (sprites), JohnFulpWillard: + - rscdel: Deleted the "IC" tab of the stat panel. + - bugfix: Lightgeists can't emote or pull as intended. + - bugfix: Blob minions can't pull again. + - qol: Martial Art users now have an action button for their artstyle-related businesses, + rather than it being in the stat panel. + - qol: You can now right-click the move up/down UI buttons to look in the direction + without moving. + theselfish, INFRARED_BARON: + - rscadd: The Captain now has a Bicorne, and matching attire... +2026-05-28: + 1393F: + - spellcheck: Some references to the cult flagellant robes have been removed + FalloutFalconPlays, Ben10Omintrix: + - rscadd: Adds an element for Runescape hitsplats + LT3: + - rscadd: Janitors now have perfect aim when throwing things into disposal units + Melbert: + - code_imp: The "power failure" event should be less laggy. + - bugfix: Fixed APCs reporting an incorrect duration during "power failure" events. + Previously, the reported duration was half of the expected time. You may see + the timer go up to 4 minutes now - however in practice, the duration of the + event is unchanged. + - bugfix: Fixed saboteur effect on APCs being 2x the expected duration - very similar + to the aforementioned APC issue. + SmArtKar: + - balance: Mining mobs now prioritize humans over basicmobs, with exception of red + and black raptors - those are prioritized over humans instead. + Wisemonster: + - rscadd: Added a flash to the QM's locker + lelandkemble: + - spellcheck: Maximum quality food is referred to as "Divine" rather than "Godlike" + mcbalaam: + - bugfix: Vote panel doesn't close for the admin cancelling the vote now + timothymtorres: + - bugfix: Fix limping not switching legs when using a cane + - rscadd: Podpeople blood can now be restored by E-Z Nutrient, which functions similarly + to iron pills for humans. + - rscadd: Plant nutriment (Liquid Earthsquake, Robust Harvest, E-Z Nutrient, Left + 4 Zed, Enduro Grow) now heals toxin damage for mobs with the MOB_PLANT biotype. +2026-05-29: + SmArtKar: + - bugfix: Fixed Gene Stim missing an icon in ling UI + Wisemonster: + - bugfix: Starting boulder refineries and smelters should start facing the correct + direction. + lelandkemble: + - qol: Support holoparasites can teleport things between two station Z-levels + - bugfix: Support holoparasite teleportation no longer runtimes when attempting + to teleport a turf + - bugfix: Bitrunners no longer take double damage in-domain, and do take damage + to their real bodies + - balance: For every living, connected bitrunner remaining in a domain, bitrunning + glitches will take five times longer to escape. + - bugfix: You can no longer softlock any virtual domain that uses points by crowbarring + the reward turf before the crate spawns. + timothymtorres: + - rscadd: The heart organ now controls how fast or slow the blood rate is regenerated + for a mob. The health of the heart organ also affects the blood rate, so the + more damage it takes, the less blood it pumps. +2026-05-30: + ArcaneMusic: + - balance: Non-boss ore vents may no longer contain bluespace crystals and diamonds. + - balance: All ore vents now have a flat 7% chance to spawn an artifact boulder. + - balance: There are now 2 new artifact boulder types, which may contain 1-5 sheets + worth of bluespace crystals or diamonds respectively. These boulders may have + their rare ore boosted via chemical boosting. + - balance: ore distribution in vents have been adjusted to accommodate for bluespace + and diamonds being removed from vents accordingly. + - spellcheck: ' Ore vents now explain the artifact boulder mechanic on examine.' + Melbert: + - refactor: Refactored dna injectors (both the ones that change appearance and activate + mutations), report any oddities with them like failing to revert your appearance + or mutations not applying correctly + - code_imp: Ever so slightly changed how diseases tick, report any oddities + - code_imp: Ever so slightly changed how some species mechanics tick, like golems + and slimes, report any oddities + - code_imp: The code behind printing appearance modifying dna injectors from genetics + has changed, report any oddities + - code_imp: Some backend transformation sting code changed slightly, report any + oddities + - code_imp: Zombie "idle" groaning is now tied to the tongue rather than the species + itself + - admin: Force-injecting someone with HARS give an admin alert, the same as force-injecting + someone with Monkey + - bugfix: Several methods of copying DNA (including transformation sting) mistakenly + copied "active mutations", this has been fixed + NiklasNeighbor: + - qol: gives the voidwalker nightvision. Why wasn't this a thing before?? + TelevisionStatic: + - rscadd: Adds an autolathe circuit board as one of the purchasable goodies in the + cargo market. + Thunder12345: + - bugfix: The honkbot on the casino emergency shuttle has been told not to abandon + its post. + Wisemonster: + - qol: Debug bluespace rpeds now come stocked with their respective tier of mega + cells + lelandkemble: + - bugfix: Patrol bounties properly pay those who complete them +2026-05-31: + Hatterhat: + - bugfix: Xenomorph queens are no longer slowed down by their own giant tails, by + virtue of also being giant. + Melbert: + - bugfix: Fix mutators printed from genetics diff --git a/html/changelogs/archive/2026-06.yml b/html/changelogs/archive/2026-06.yml new file mode 100644 index 00000000000..9f55dcb4588 --- /dev/null +++ b/html/changelogs/archive/2026-06.yml @@ -0,0 +1,51 @@ +2026-06-01: + Glamyrio: + - bugfix: Renamed 2 cameras on MetaStation; first cam was with wrong name and second + one was a badnamed + SmArtKar: + - refactor: Refactors inventory UI to be completely datum and vis_contents-based + - bugfix: Observers should no longer see doubled up inventory UIs + TheRyeGuyWhoWillNowDie: + - rscadd: Added the limper quirk, which makes you limp. + - bugfix: storage module of holding now triggers bluespace interference as intended + - refactor: teleporter interference checks check an item flag rather than hard type-checking + bags of holding + - spellcheck: Securiy + lelandkemble: + - balance: The RNG instant kill via organ removal of the mech drill has been removed, + and replaced with a very high wounding chance +2026-06-02: + Iajret: + - bugfix: Mending touch works once again + Melbert: + - bugfix: Cutting an airlock's ID wire prevents ID usage again (instead of changing + the door to all access) + - map: Roundstart nuclear operatives now spawn in the nuke base elevator, rather + than in the base itself. This change was done so we could reduce the lag from + loading the nuke base during round startup. + SmArtKar: + - bugfix: Fixed spilled flour not containing any flour + - balance: You can make toolboxes out of meat and paper again + - balance: Lavaland tendrils have been reworked into a full fledged miniboss instead + of a simple mob spawner. + - balance: Lavaland mobs minimum spawn separation distance has been lowered from + 12 to 7 + TheRyeGuyWhoWillNowDie: + - bugfix: jaws of recovery are blacklisted from crafting the jaws of recovery + Wisemonster: + - bugfix: Fixed Nebula's boulder refinery being constantly spaced. + Y0SH1M4S73R: + - bugfix: Non-square paint canvases and Nanopaint projects correctly save to icons. + - bugfix: You can no longer enter empty filenames when saving Nanopaint files. + - spellcheck: User-provided modular computer filenames are now checked against the + pda IC filter. + lelandkemble: + - balance: Bitrunners can't back out of domains via the ladder while bitrunning + glitches remain in them + necromanceranne: + - spellcheck: Adds some additional deep lore to some of the pistols in the game. + FInd your favourite and see if I cared to add one. + - spellcheck: Rewrote the lore for contractor batons and stun batons. + - code_imp: Repathed Liberators. This has no bearing on their function. + - code_imp: Rechambers Regal Condors in .45 and 10mm Reaper rounds to .45 Reaper + rounds. This has no impact on their function. diff --git a/html/statbrowser.js b/html/statbrowser.js index d0f98fc60f7..2292f199096 100644 --- a/html/statbrowser.js +++ b/html/statbrowser.js @@ -10,33 +10,35 @@ if (!Array.prototype.includes) { } if (!String.prototype.trim) { String.prototype.trim = function () { - return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ""); + return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); }; } // Status panel implementation ------------------------------------------------ //status_tab_parts expects a list to be returned, to which we'll send a list within a list //with just "loading" to not appear broken. -var status_tab_parts = [["Loading..."]]; +var status_tab_parts = [['Loading...']]; var current_tab = null; //mc_tab_parts expects a list to be returned, to which we'll send a list within a list //with just "loading" to not appear broken. -var mc_tab_parts = [["Loading..."]]; +var mc_tab_parts = [['Loading...']]; var href_token = null; var verb_tabs = []; -var verbs = [["", ""]]; // list with a list inside +var verbs = [['', '']]; // list with a list inside var tickets = []; -var interviewManager = { status: "", interviews: [] }; +var interviewManager = { status: '', interviews: [] }; var sdql2 = []; var permanent_tabs = []; // tabs that won't be cleared by wipes var turfcontents = []; -var turfname = ""; +var turfname = ''; var imageRetryDelay = 500; var imageRetryLimit = 50; -var menu = document.getElementById("menu"); -var statcontentdiv = document.getElementById("statcontent"); +var menu = document.getElementById('menu'); +var statcontentdiv = document.getElementById('statcontent'); var storedimages = []; var split_admin_tabs = false; +//The 'default' tab that everyone should have, that we swap to if the tab you're on is deleted or anything similar. +var defaultTab = 'Status'; // Any BYOND commands that could result in the client's focus changing go through this // to ensure that when we relinquish our focus, we don't do it after the result of @@ -46,18 +48,18 @@ function run_after_focus(callback) { } function createStatusTab(name) { - if (name.indexOf(".") != -1) { - var splitName = name.split("."); - if (split_admin_tabs && splitName[0] === "Admin") name = splitName[1]; + if (name.indexOf('.') != -1) { + var splitName = name.split('.'); + if (split_admin_tabs && splitName[0] === 'Admin') name = splitName[1]; else name = splitName[0]; } - if (document.getElementById(name) || name.trim() == "") { + if (document.getElementById(name) || name.trim() == '') { return; } if (!verb_tabs.includes(name) && !permanent_tabs.includes(name)) { return; } - var button = document.createElement("DIV"); + var button = document.createElement('DIV'); button.onclick = function () { tab_change(name); this.blur(); @@ -65,7 +67,7 @@ function createStatusTab(name) { }; button.id = name; button.textContent = name; - button.className = "button"; + button.className = 'button'; //ORDERING ALPHABETICALLY button.style.order = { Status: 1, MC: 2 }[name] || name.charCodeAt(0); //END ORDERING @@ -87,7 +89,7 @@ function removeStatusTab(name) { } function sortVerbs() { - verbs.sort(function (a, b) { + verbs.sort((a, b) => { var selector = a[0] == b[0] ? 1 : 0; if (a[selector].toUpperCase() < b[selector].toUpperCase()) { return 1; @@ -143,13 +145,13 @@ function check_verbs() { function verbs_cat_check(cat) { var tabCat = cat; - if (cat.indexOf(".") != -1) { - var splitName = cat.split("."); - if (split_admin_tabs && splitName[0] === "Admin") tabCat = splitName[1]; + if (cat.indexOf('.') != -1) { + var splitName = cat.split('.'); + if (split_admin_tabs && splitName[0] === 'Admin') tabCat = splitName[1]; else tabCat = splitName[0]; } var verbs_in_cat = 0; - var verbcat = ""; + var verbcat = ''; if (!verb_tabs.includes(tabCat)) { removeStatusTab(tabCat); return; @@ -157,13 +159,12 @@ function verbs_cat_check(cat) { for (var v = 0; v < verbs.length; v++) { var part = verbs[v]; verbcat = part[0]; - if (verbcat.indexOf(".") != -1) { - var splitName = verbcat.split("."); - if (split_admin_tabs && splitName[0] === "Admin") verbcat = splitName[1]; + if (verbcat.indexOf('.') != -1) { + var splitName = verbcat.split('.'); + if (split_admin_tabs && splitName[0] === 'Admin') verbcat = splitName[1]; else verbcat = splitName[0]; } - if (verbcat != tabCat || verbcat.trim() == "") { - continue; + if (verbcat != tabCat || verbcat.trim() == '') { } else { verbs_in_cat = 1; break; // we only need one @@ -171,7 +172,7 @@ function verbs_cat_check(cat) { } if (verbs_in_cat != 1) { removeStatusTab(tabCat); - if (current_tab == tabCat) tab_change("Status"); + if (current_tab == tabCat) tab_change(defaultTab); } } @@ -182,14 +183,14 @@ function findVerbindex(name, verblist) { } } function wipe_verbs() { - verbs = [["", ""]]; + verbs = [['', '']]; verb_tabs = []; checkStatusTab(); // remove all empty verb tabs } function update_verbs() { wipe_verbs(); - Byond.sendMessage("Update-Verbs"); + Byond.sendMessage('Update-Verbs'); } function SendTabsToByond() { @@ -201,159 +202,158 @@ function SendTabsToByond() { } function SendTabToByond(tab) { - Byond.sendMessage("Send-Tabs", { tab: tab }); + Byond.sendMessage('Send-Tabs', { tab: tab }); } //Byond can't have this tab anymore since we're removing it function TakeTabFromByond(tab) { - Byond.sendMessage("Remove-Tabs", { tab: tab }); + Byond.sendMessage('Remove-Tabs', { tab: tab }); } function tab_change(tab) { if (tab == current_tab) return; if (document.getElementById(current_tab)) - document.getElementById(current_tab).className = "button"; // disable active on last button + document.getElementById(current_tab).className = 'button'; // disable active on last button current_tab = tab; set_byond_tab(tab); if (document.getElementById(tab)) - document.getElementById(tab).className = "button active"; // make current button active + document.getElementById(tab).className = 'button active'; // make current button active var verb_tabs_thingy = verb_tabs.includes(tab); - statcontentdiv.className = "statcontent"; - if (tab == "Status") { + statcontentdiv.className = 'statcontent'; + if (tab == 'Status') { draw_status(); - } else if (tab == "MC") { + } else if (tab == 'MC') { draw_mc(); } else if (verb_tabs_thingy) { draw_verbs(tab); - } else if (tab == "Debug Stat Panel") { + } else if (tab == 'Debug Stat Panel') { draw_debug(); - } else if (tab == "Tickets") { + } else if (tab == 'Tickets') { draw_tickets(); draw_interviews(); - } else if (tab == "SDQL2") { + } else if (tab == 'SDQL2') { draw_sdql2(); } else if (tab == turfname) { draw_listedturf(); } else { - statcontentdiv.textContext = "Loading..."; + statcontentdiv.textContext = 'Loading...'; } Byond.winset(Byond.windowId, { - "is-visible": true, + 'is-visible': true, }); } function set_byond_tab(tab) { - Byond.sendMessage("Set-Tab", { tab: tab }); + Byond.sendMessage('Set-Tab', { tab: tab }); } function draw_debug() { - statcontentdiv.textContent = ""; - var wipeverbstabs = document.createElement("div"); - var link = document.createElement("a"); - link.onclick = function () { + statcontentdiv.textContent = ''; + var wipeverbstabs = document.createElement('div'); + var link = document.createElement('a'); + link.onclick = () => { wipe_verbs(); }; - link.textContent = "Wipe All Verbs"; + link.textContent = 'Wipe All Verbs'; wipeverbstabs.appendChild(link); - document.getElementById("statcontent").appendChild(wipeverbstabs); - var wipeUpdateVerbsTabs = document.createElement("div"); - var updateLink = document.createElement("a"); - updateLink.onclick = function () { + document.getElementById('statcontent').appendChild(wipeverbstabs); + var wipeUpdateVerbsTabs = document.createElement('div'); + var updateLink = document.createElement('a'); + updateLink.onclick = () => { update_verbs(); }; - updateLink.textContent = "Wipe and Update All Verbs"; + updateLink.textContent = 'Wipe and Update All Verbs'; wipeUpdateVerbsTabs.appendChild(updateLink); - document.getElementById("statcontent").appendChild(wipeUpdateVerbsTabs); - var text = document.createElement("div"); - text.textContent = "Verb Tabs:"; - document.getElementById("statcontent").appendChild(text); - var table1 = document.createElement("table"); + document.getElementById('statcontent').appendChild(wipeUpdateVerbsTabs); + var text = document.createElement('div'); + text.textContent = 'Verb Tabs:'; + document.getElementById('statcontent').appendChild(text); + var table1 = document.createElement('table'); for (var i = 0; i < verb_tabs.length; i++) { var part = verb_tabs[i]; // Hide subgroups except admin subgroups if they are split - if (verb_tabs[i].lastIndexOf(".") != -1) { - var splitName = verb_tabs[i].split("."); - if (split_admin_tabs && splitName[0] === "Admin") part = splitName[1]; + if (verb_tabs[i].lastIndexOf('.') != -1) { + var splitName = verb_tabs[i].split('.'); + if (split_admin_tabs && splitName[0] === 'Admin') part = splitName[1]; else continue; } - var tr = document.createElement("tr"); - var td1 = document.createElement("td"); + var tr = document.createElement('tr'); + var td1 = document.createElement('td'); td1.textContent = part; - var a = document.createElement("a"); - a.onclick = (function (part) { - return function () { - removeStatusTab(part); - }; + var a = document.createElement('a'); + a.onclick = ((part) => () => { + removeStatusTab(part); })(part); - a.textContent = " Delete Tab " + part; + a.textContent = ' Delete Tab ' + part; td1.appendChild(a); tr.appendChild(td1); table1.appendChild(tr); } - document.getElementById("statcontent").appendChild(table1); - var header2 = document.createElement("div"); - header2.textContent = "Verbs:"; - document.getElementById("statcontent").appendChild(header2); - var table2 = document.createElement("table"); + document.getElementById('statcontent').appendChild(table1); + var header2 = document.createElement('div'); + header2.textContent = 'Verbs:'; + document.getElementById('statcontent').appendChild(header2); + var table2 = document.createElement('table'); for (var v = 0; v < verbs.length; v++) { var part2 = verbs[v]; - var trr = document.createElement("tr"); - var tdd1 = document.createElement("td"); + var trr = document.createElement('tr'); + var tdd1 = document.createElement('td'); tdd1.textContent = part2[0]; - var tdd2 = document.createElement("td"); + var tdd2 = document.createElement('td'); tdd2.textContent = part2[1]; trr.appendChild(tdd1); trr.appendChild(tdd2); table2.appendChild(trr); } - document.getElementById("statcontent").appendChild(table2); - var text3 = document.createElement("div"); - text3.textContent = "Permanent Tabs:"; - document.getElementById("statcontent").appendChild(text3); - var table3 = document.createElement("table"); + document.getElementById('statcontent').appendChild(table2); + var text3 = document.createElement('div'); + text3.textContent = 'Permanent Tabs:'; + document.getElementById('statcontent').appendChild(text3); + var table3 = document.createElement('table'); for (var i = 0; i < permanent_tabs.length; i++) { var part3 = permanent_tabs[i]; - var trrr = document.createElement("tr"); - var tddd1 = document.createElement("td"); + var trrr = document.createElement('tr'); + var tddd1 = document.createElement('td'); tddd1.textContent = part3; trrr.appendChild(tddd1); table3.appendChild(trrr); } - document.getElementById("statcontent").appendChild(table3); + document.getElementById('statcontent').appendChild(table3); } + function draw_status() { - if (!document.getElementById("Status")) { - createStatusTab("Status"); - current_tab = "Status"; + if (!document.getElementById('Status')) { + createStatusTab('Status'); + current_tab = 'Status'; } - statcontentdiv.textContent = ""; - var table = document.createElement("table"); + statcontentdiv.textContent = ''; + var table = document.createElement('table'); for (var i = 0; i < status_tab_parts.length; i++) { var part = status_tab_parts[i]; if (!Array.isArray(part)) { - var div = document.createElement("div"); - if (part.trim() == "") { - table.appendChild(document.createElement("br")); + var div = document.createElement('div'); + if (part.trim() == '') { + table.appendChild(document.createElement('br')); } else { div.textContent = part; table.appendChild(div); } } else { var div; - if (part[0].trim() == "same_line") { - var a = document.createElement("a"); - a.href = "byond://?" + part[2]; + if (part[0].trim() == 'same_line') { + var a = document.createElement('a'); + a.href = 'byond://?' + part[2]; a.textContent = part[1]; div.appendChild(a); } else { - div = document.createElement("div"); - if (part[0].trim() == "") { - table.appendChild(document.createElement("br")); + div = document.createElement('div'); + if (part[0].trim() == '') { + table.appendChild(document.createElement('br')); } else { div.textContent = part[0]; if (part[2]) { - var a = document.createElement("a"); - a.href = "byond://?" + part[2]; + var a = document.createElement('a'); + a.href = 'byond://?' + part[2]; a.textContent = part[1]; div.appendChild(a); } @@ -362,29 +362,29 @@ function draw_status() { } } } - document.getElementById("statcontent").appendChild(table); + document.getElementById('statcontent').appendChild(table); if (verb_tabs.length == 0 || !verbs) { - Byond.command("Fix-Stat-Panel"); + Byond.command('Fix-Stat-Panel'); } } function draw_mc() { - statcontentdiv.textContent = ""; - statcontentdiv.className = "mcstatcontent"; - var table = document.createElement("table"); + statcontentdiv.textContent = ''; + statcontentdiv.className = 'mcstatcontent'; + var table = document.createElement('table'); for (var i = 0; i < mc_tab_parts.length; i++) { var part = mc_tab_parts[i]; - var tr = document.createElement("tr"); - var td0 = document.createElement("td"); - td0.className = "monospace"; + var tr = document.createElement('tr'); + var td0 = document.createElement('td'); + td0.className = 'monospace'; td0.textContent = part[0]; - var td1 = document.createElement("td"); + var td1 = document.createElement('td'); td1.textContent = part[1]; - var td2 = document.createElement("td"); + var td2 = document.createElement('td'); if (part[3]) { - var a = document.createElement("a"); + var a = document.createElement('a'); a.href = - "byond://?_src_=vars;admin_token=" + href_token + ";Vars=" + part[3]; + 'byond://?_src_=vars;admin_token=' + href_token + ';Vars=' + part[3]; a.textContent = part[2]; td2.appendChild(a); } else { @@ -395,14 +395,14 @@ function draw_mc() { tr.appendChild(td2); table.appendChild(tr); } - document.getElementById("statcontent").appendChild(table); + document.getElementById('statcontent').appendChild(table); } function remove_tickets() { if (tickets) { tickets = []; - removePermanentTab("Tickets"); - if (current_tab == "Tickets") tab_change("Status"); + removePermanentTab('Tickets'); + if (current_tab == 'Tickets') tab_change(defaultTab); } checkStatusTab(); } @@ -410,8 +410,8 @@ function remove_tickets() { function remove_sdql2() { if (sdql2) { sdql2 = []; - removePermanentTab("SDQL2"); - if (current_tab == "SDQL2") tab_change("Status"); + removePermanentTab('SDQL2'); + if (current_tab == 'SDQL2') tab_change(defaultTab); } checkStatusTab(); } @@ -427,55 +427,55 @@ function iconError(e) { if (current_tab != turfname) { return; } - setTimeout(function () { + setTimeout(() => { var node = e.target; - var current_attempts = Number(node.getAttribute("data-attempts")) || 0; + var current_attempts = Number(node.getAttribute('data-attempts')) || 0; if (current_attempts > imageRetryLimit) { return; } var src = node.src; node.src = null; - node.src = src + "#" + current_attempts; - node.setAttribute("data-attempts", current_attempts + 1); + node.src = src + '#' + current_attempts; + node.setAttribute('data-attempts', current_attempts + 1); draw_listedturf(); }, imageRetryDelay); } function draw_listedturf() { - statcontentdiv.textContent = ""; - var table = document.createElement("table"); + statcontentdiv.textContent = ''; + var table = document.createElement('table'); for (var i = 0; i < turfcontents.length; i++) { var part = turfcontents[i]; - var clickfunc = (function (part) { + var clickfunc = ((part) => { // The outer function is used to close over a fresh "part" variable, // rather than every onmousedown getting the "part" of the last entry. - return function (e) { + return (e) => { e.preventDefault(); - clickcatcher = "byond://?src=" + part[1]; + clickcatcher = 'byond://?src=' + part[1]; switch (e.button) { case 1: - clickcatcher += ";statpanel_item_click=middle"; + clickcatcher += ';statpanel_item_click=middle'; break; case 2: - clickcatcher += ";statpanel_item_click=right"; + clickcatcher += ';statpanel_item_click=right'; break; default: - clickcatcher += ";statpanel_item_click=left"; + clickcatcher += ';statpanel_item_click=left'; } if (e.shiftKey) { - clickcatcher += ";statpanel_item_shiftclick=1"; + clickcatcher += ';statpanel_item_shiftclick=1'; } if (e.ctrlKey) { - clickcatcher += ";statpanel_item_ctrlclick=1"; + clickcatcher += ';statpanel_item_ctrlclick=1'; } if (e.altKey) { - clickcatcher += ";statpanel_item_altclick=1"; + clickcatcher += ';statpanel_item_altclick=1'; } window.location.href = clickcatcher; }; })(part); if (storedimages[part[1]] == null && part[2]) { - var img = document.createElement("img"); + var img = document.createElement('img'); img.src = part[2]; img.id = part[1]; storedimages[part[1]] = part[2]; @@ -483,51 +483,51 @@ function draw_listedturf() { img.onmousedown = clickfunc; table.appendChild(img); } else { - var img = document.createElement("img"); + var img = document.createElement('img'); img.onerror = iconError; img.onmousedown = clickfunc; img.src = storedimages[part[1]]; img.id = part[1]; table.appendChild(img); } - var b = document.createElement("div"); - var clickcatcher = ""; - b.className = "link"; + var b = document.createElement('div'); + var clickcatcher = ''; + b.className = 'link'; b.onmousedown = clickfunc; b.textContent = part[0]; table.appendChild(b); - table.appendChild(document.createElement("br")); + table.appendChild(document.createElement('br')); } - document.getElementById("statcontent").appendChild(table); + document.getElementById('statcontent').appendChild(table); } function remove_listedturf() { removePermanentTab(turfname); checkStatusTab(); if (current_tab == turfname) { - tab_change("Status"); + tab_change(defaultTab); } } function remove_mc() { - removePermanentTab("MC"); - if (current_tab == "MC") { - tab_change("Status"); + removePermanentTab('MC'); + if (current_tab == 'MC') { + tab_change(defaultTab); } } function draw_sdql2() { - statcontentdiv.textContent = ""; - var table = document.createElement("table"); + statcontentdiv.textContent = ''; + var table = document.createElement('table'); for (var i = 0; i < sdql2.length; i++) { var part = sdql2[i]; - var tr = document.createElement("tr"); - var td1 = document.createElement("td"); + var tr = document.createElement('tr'); + var td1 = document.createElement('td'); td1.textContent = part[0]; - var td2 = document.createElement("td"); + var td2 = document.createElement('td'); if (part[2]) { - var a = document.createElement("a"); - a.href = "byond://?src=" + part[2] + ";statpanel_item_click=left"; + var a = document.createElement('a'); + a.href = 'byond://?src=' + part[2] + ';statpanel_item_click=left'; a.textContent = part[1]; td2.appendChild(a); } else { @@ -537,34 +537,34 @@ function draw_sdql2() { tr.appendChild(td2); table.appendChild(tr); } - document.getElementById("statcontent").appendChild(table); + document.getElementById('statcontent').appendChild(table); } function draw_tickets() { - statcontentdiv.textContent = ""; - var table = document.createElement("table"); + statcontentdiv.textContent = ''; + var table = document.createElement('table'); if (!tickets) { return; } for (var i = 0; i < tickets.length; i++) { var part = tickets[i]; - var tr = document.createElement("tr"); - var td1 = document.createElement("td"); + var tr = document.createElement('tr'); + var td1 = document.createElement('td'); td1.textContent = part[0]; - var td2 = document.createElement("td"); + var td2 = document.createElement('td'); if (part[2]) { - var a = document.createElement("a"); + var a = document.createElement('a'); a.href = - "byond://?_src_=holder;admin_token=" + + 'byond://?_src_=holder;admin_token=' + href_token + - ";ahelp=" + + ';ahelp=' + part[2] + - ";ahelp_action=ticket;statpanel_item_click=left;action=ticket"; + ';ahelp_action=ticket;statpanel_item_click=left;action=ticket'; a.textContent = part[1]; td2.appendChild(a); } else if (part[3]) { - var a = document.createElement("a"); - a.href = "byond://?src=" + part[3] + ";statpanel_item_click=left"; + var a = document.createElement('a'); + a.href = 'byond://?src=' + part[3] + ';statpanel_item_click=left'; a.textContent = part[1]; td2.appendChild(a); } else { @@ -574,33 +574,33 @@ function draw_tickets() { tr.appendChild(td2); table.appendChild(tr); } - document.getElementById("statcontent").appendChild(table); + document.getElementById('statcontent').appendChild(table); } function draw_interviews() { - var body = document.createElement("div"); - var header = document.createElement("h3"); - header.textContent = "Interviews"; + var body = document.createElement('div'); + var header = document.createElement('h3'); + header.textContent = 'Interviews'; body.appendChild(header); - var manDiv = document.createElement("div"); - manDiv.className = "interview_panel_controls"; - var manLink = document.createElement("a"); - manLink.textContent = "Open Interview Manager Panel"; + var manDiv = document.createElement('div'); + manDiv.className = 'interview_panel_controls'; + var manLink = document.createElement('a'); + manLink.textContent = 'Open Interview Manager Panel'; manLink.href = - "byond://?_src_=holder;admin_token=" + + 'byond://?_src_=holder;admin_token=' + href_token + - ";interview_man=1;statpanel_item_click=left"; + ';interview_man=1;statpanel_item_click=left'; manDiv.appendChild(manLink); body.appendChild(manDiv); // List interview stats - var statsDiv = document.createElement("table"); - statsDiv.className = "interview_panel_stats"; + var statsDiv = document.createElement('table'); + statsDiv.className = 'interview_panel_stats'; for (var key in interviewManager.status) { - var d = document.createElement("div"); - var tr = document.createElement("tr"); - var stat_name = document.createElement("td"); - var stat_text = document.createElement("td"); + var d = document.createElement('div'); + var tr = document.createElement('tr'); + var stat_name = document.createElement('td'); + var stat_text = document.createElement('td'); stat_name.textContent = key; stat_text.textContent = interviewManager.status[key]; tr.appendChild(stat_name); @@ -608,94 +608,94 @@ function draw_interviews() { statsDiv.appendChild(tr); } body.appendChild(statsDiv); - document.getElementById("statcontent").appendChild(body); + document.getElementById('statcontent').appendChild(body); // List interviews if any are open - var table = document.createElement("table"); - table.className = "interview_panel_table"; + var table = document.createElement('table'); + table.className = 'interview_panel_table'; if (!interviewManager) { return; } for (var i = 0; i < interviewManager.interviews.length; i++) { var part = interviewManager.interviews[i]; - var tr = document.createElement("tr"); - var td = document.createElement("td"); - var a = document.createElement("a"); - a.textContent = part["status"]; + var tr = document.createElement('tr'); + var td = document.createElement('td'); + var a = document.createElement('a'); + a.textContent = part['status']; a.href = - "byond://?_src_=holder;admin_token=" + + 'byond://?_src_=holder;admin_token=' + href_token + - ";interview=" + - part["ref"] + - ";statpanel_item_click=left"; + ';interview=' + + part['ref'] + + ';statpanel_item_click=left'; td.appendChild(a); tr.appendChild(td); table.appendChild(tr); } - document.getElementById("statcontent").appendChild(table); + document.getElementById('statcontent').appendChild(table); } function make_verb_onclick(command) { - return function () { - run_after_focus(function () { + return () => { + run_after_focus(() => { Byond.command(command); }); }; } function draw_verbs(cat) { - statcontentdiv.textContent = ""; - var table = document.createElement("div"); + statcontentdiv.textContent = ''; + var table = document.createElement('div'); var additions = {}; // additional sub-categories to be rendered - table.className = "grid-container"; + table.className = 'grid-container'; sortVerbs(); - if (split_admin_tabs && cat.lastIndexOf(".") != -1) { - var splitName = cat.split("."); - if (splitName[0] === "Admin") cat = splitName[1]; + if (split_admin_tabs && cat.lastIndexOf('.') != -1) { + var splitName = cat.split('.'); + if (splitName[0] === 'Admin') cat = splitName[1]; } verbs.reverse(); // sort verbs backwards before we draw for (var i = 0; i < verbs.length; ++i) { var part = verbs[i]; var name = part[0]; - if (split_admin_tabs && name.lastIndexOf(".") != -1) { - var splitName = name.split("."); - if (splitName[0] === "Admin") name = splitName[1]; + if (split_admin_tabs && name.lastIndexOf('.') != -1) { + var splitName = name.split('.'); + if (splitName[0] === 'Admin') name = splitName[1]; } var command = part[1]; if ( command && name.lastIndexOf(cat, 0) != -1 && - (name.length == cat.length || name.charAt(cat.length) == ".") + (name.length == cat.length || name.charAt(cat.length) == '.') ) { - var subCat = name.lastIndexOf(".") != -1 ? name.split(".")[1] : null; + var subCat = name.lastIndexOf('.') != -1 ? name.split('.')[1] : null; if (subCat && !additions[subCat]) { - var newTable = document.createElement("div"); - newTable.className = "grid-container"; + var newTable = document.createElement('div'); + newTable.className = 'grid-container'; additions[subCat] = newTable; } - var a = document.createElement("a"); - a.href = "#"; - a.onclick = make_verb_onclick(command.replace(/\s/g, "-")); - a.className = "grid-item"; - var t = document.createElement("span"); + var a = document.createElement('a'); + a.href = '#'; + a.onclick = make_verb_onclick(command.replace(/\s/g, '-')); + a.className = 'grid-item'; + var t = document.createElement('span'); t.textContent = command; - t.className = "grid-item-text"; + t.className = 'grid-item-text'; a.appendChild(t); (subCat ? additions[subCat] : table).appendChild(a); } } // Append base table to view - var content = document.getElementById("statcontent"); + var content = document.getElementById('statcontent'); content.appendChild(table); // Append additional sub-categories if relevant for (var cat in additions) { - if (additions.hasOwnProperty(cat)) { + if (Object.hasOwn(additions, cat)) { // do addition here - var header = document.createElement("h3"); + var header = document.createElement('h3'); header.textContent = cat; content.appendChild(header); content.appendChild(additions[cat]); @@ -704,51 +704,51 @@ function draw_verbs(cat) { } function set_theme(which) { - if (which == "light") { - document.body.className = ""; - document.documentElement.className = "light"; - } else if (which == "dark") { - document.body.className = "dark"; - document.documentElement.className = "dark"; + if (which == 'light') { + document.body.className = ''; + document.documentElement.className = 'light'; + } else if (which == 'dark') { + document.body.className = 'dark'; + document.documentElement.className = 'dark'; } } function set_font_size(size) { - document.body.style.setProperty("font-size", size); + document.body.style.setProperty('font-size', size); } function set_tabs_style(style) { - if (style == "default") { - menu.classList.add("menu-wrap"); - menu.classList.remove("tabs-classic"); - } else if (style == "classic") { - menu.classList.add("menu-wrap"); - menu.classList.add("tabs-classic"); - } else if (style == "scrollable") { - menu.classList.remove("menu-wrap"); - menu.classList.remove("tabs-classic"); + if (style == 'default') { + menu.classList.add('menu-wrap'); + menu.classList.remove('tabs-classic'); + } else if (style == 'classic') { + menu.classList.add('menu-wrap'); + menu.classList.add('tabs-classic'); + } else if (style == 'scrollable') { + menu.classList.remove('menu-wrap'); + menu.classList.remove('tabs-classic'); } } function restoreFocus() { - run_after_focus(function () { - Byond.winset("map", { + run_after_focus(() => { + Byond.winset('map', { focus: true, }); }); } function getCookie(cname) { - var name = cname + "="; - var ca = document.cookie.split(";"); + var name = cname + '='; + var ca = document.cookie.split(';'); for (var i = 0; i < ca.length; i++) { var c = ca[i]; - while (c.charAt(0) == " ") c = c.substring(1); + while (c.charAt(0) == ' ') c = c.substring(1); if (c.indexOf(name) === 0) { return decoder(c.substring(name.length, c.length)); } } - return ""; + return ''; } function add_verb_list(payload) { @@ -758,9 +758,9 @@ function add_verb_list(payload) { var part = to_add[i]; if (!part[0]) continue; var category = part[0]; - if (category.indexOf(".") != -1) { - var splitName = category.split("."); - if (split_admin_tabs && splitName[0] === "Admin") category = splitName[1]; + if (category.indexOf('.') != -1) { + var splitName = category.split('.'); + if (split_admin_tabs && splitName[0] === 'Admin') category = splitName[1]; else category = splitName[0]; } if (findVerbindex(part[1], verbs)) continue; @@ -777,19 +777,19 @@ function add_verb_list(payload) { } } -document.addEventListener("mouseup", restoreFocus); -document.addEventListener("keyup", restoreFocus); +document.addEventListener('mouseup', restoreFocus); +document.addEventListener('keyup', restoreFocus); if (!current_tab) { - addPermanentTab("Status"); - tab_change("Status"); + addPermanentTab(defaultTab); + tab_change(defaultTab); } -window.onload = function () { - Byond.sendMessage("Update-Verbs"); +window.onload = () => { + Byond.sendMessage('Update-Verbs'); }; -Byond.subscribeTo("remove_verb_list", function (v) { +Byond.subscribeTo('remove_verb_list', (v) => { var to_remove = v; for (var i = 0; i < to_remove.length; i++) { remove_verb(to_remove[i]); @@ -801,13 +801,13 @@ Byond.subscribeTo("remove_verb_list", function (v) { // passes a 2D list of (verbcategory, verbname) creates tabs and adds verbs to respective list // example (IC, Say) -Byond.subscribeTo("init_verbs", function (payload) { +Byond.subscribeTo('init_verbs', (payload) => { wipe_verbs(); // remove all verb categories so we can replace them checkStatusTab(); // remove all status tabs verb_tabs = payload.panel_tabs; verb_tabs.sort(); // sort it var do_update = false; - var cat = ""; + var cat = ''; for (var i = 0; i < verb_tabs.length; i++) { cat = verb_tabs[i]; createStatusTab(cat); // create a category if the verb doesn't exist yet @@ -825,8 +825,8 @@ Byond.subscribeTo("init_verbs", function (payload) { SendTabsToByond(); }); -Byond.subscribeTo("update_stat", function (payload) { - status_tab_parts = [payload.ping_str]; +Byond.subscribeTo('update_stat', (payload) => { + status_tab_parts = []; var parsed = payload.global_data; @@ -838,44 +838,44 @@ Byond.subscribeTo("update_stat", function (payload) { for (var i = 0; i < parsed.length; i++) if (parsed[i] != null) status_tab_parts.push(parsed[i]); - if (current_tab == "Status") { + if (current_tab == 'Status') { draw_status(); - } else if (current_tab == "Debug Stat Panel") { + } else if (current_tab == 'Debug Stat Panel') { draw_debug(); } }); -Byond.subscribeTo("update_mc", function (payload) { +Byond.subscribeTo('update_mc', (payload) => { mc_tab_parts = payload.mc_data; - mc_tab_parts.splice(0, 0, ["", "Location:", payload.coord_entry]); + mc_tab_parts.splice(0, 0, ['', 'Location:', payload.coord_entry]); - if (!verb_tabs.includes("MC")) { - verb_tabs.push("MC"); + if (!verb_tabs.includes('MC')) { + verb_tabs.push('MC'); } - createStatusTab("MC"); + createStatusTab('MC'); - if (current_tab == "MC") { + if (current_tab == 'MC') { draw_mc(); } }); -Byond.subscribeTo("create_debug", function () { - if (!document.getElementById("Debug Stat Panel")) { - addPermanentTab("Debug Stat Panel"); +Byond.subscribeTo('create_debug', () => { + if (!document.getElementById('Debug Stat Panel')) { + addPermanentTab('Debug Stat Panel'); } else { - removePermanentTab("Debug Stat Panel"); + removePermanentTab('Debug Stat Panel'); } }); -Byond.subscribeTo("create_listedturf", function (TN) { +Byond.subscribeTo('create_listedturf', (TN) => { remove_listedturf(); // remove the last one if we had one turfname = TN; addPermanentTab(turfname); tab_change(turfname); }); -Byond.subscribeTo("remove_admin_tabs", function () { +Byond.subscribeTo('remove_admin_tabs', () => { href_token = null; remove_mc(); remove_tickets(); @@ -883,66 +883,66 @@ Byond.subscribeTo("remove_admin_tabs", function () { remove_interviews(); }); -Byond.subscribeTo("update_listedturf", function (TC) { +Byond.subscribeTo('update_listedturf', (TC) => { turfcontents = TC; if (current_tab == turfname) { draw_listedturf(); } }); -Byond.subscribeTo("update_interviews", function (I) { +Byond.subscribeTo('update_interviews', (I) => { interviewManager = I; - if (current_tab == "Tickets") { + if (current_tab == 'Tickets') { draw_interviews(); } }); -Byond.subscribeTo("update_split_admin_tabs", function (status) { +Byond.subscribeTo('update_split_admin_tabs', (status) => { status = status == true; if (split_admin_tabs !== status) { if (split_admin_tabs === true) { - removeStatusTab("Events"); - removeStatusTab("Fun"); - removeStatusTab("Game"); + removeStatusTab('Events'); + removeStatusTab('Fun'); + removeStatusTab('Game'); } update_verbs(); } split_admin_tabs = status; }); -Byond.subscribeTo("add_admin_tabs", function (ht) { +Byond.subscribeTo('add_admin_tabs', (ht) => { href_token = ht; - addPermanentTab("MC"); - addPermanentTab("Tickets"); + addPermanentTab('MC'); + addPermanentTab('Tickets'); }); -Byond.subscribeTo("update_sdql2", function (S) { +Byond.subscribeTo('update_sdql2', (S) => { sdql2 = S; - if (sdql2.length > 0 && !verb_tabs.includes("SDQL2")) { - verb_tabs.push("SDQL2"); - addPermanentTab("SDQL2"); + if (sdql2.length > 0 && !verb_tabs.includes('SDQL2')) { + verb_tabs.push('SDQL2'); + addPermanentTab('SDQL2'); } - if (current_tab == "SDQL2") { + if (current_tab == 'SDQL2') { draw_sdql2(); } }); -Byond.subscribeTo("update_tickets", function (T) { +Byond.subscribeTo('update_tickets', (T) => { tickets = T; - if (!verb_tabs.includes("Tickets")) { - verb_tabs.push("Tickets"); - addPermanentTab("Tickets"); + if (!verb_tabs.includes('Tickets')) { + verb_tabs.push('Tickets'); + addPermanentTab('Tickets'); } - if (current_tab == "Tickets") { + if (current_tab == 'Tickets') { draw_tickets(); } }); -Byond.subscribeTo("remove_listedturf", remove_listedturf); +Byond.subscribeTo('remove_listedturf', remove_listedturf); -Byond.subscribeTo("remove_sdql2", remove_sdql2); +Byond.subscribeTo('remove_sdql2', remove_sdql2); -Byond.subscribeTo("remove_mc", remove_mc); +Byond.subscribeTo('remove_mc', remove_mc); -Byond.subscribeTo("add_verb_list", add_verb_list); +Byond.subscribeTo('add_verb_list', add_verb_list); diff --git a/icons/blanks/480x480.dmi b/icons/blanks/480x480.dmi new file mode 100644 index 00000000000..3f006394a15 Binary files /dev/null and b/icons/blanks/480x480.dmi differ diff --git a/icons/effects/beam.dmi b/icons/effects/beam.dmi index a4a9bbb8443..c9723f51e2b 100644 Binary files a/icons/effects/beam.dmi and b/icons/effects/beam.dmi differ diff --git a/icons/effects/cut.dmi b/icons/effects/cut.dmi index 0252704d2bb..aa2865afb0b 100644 Binary files a/icons/effects/cut.dmi and b/icons/effects/cut.dmi differ diff --git a/icons/effects/hitsplats.dmi b/icons/effects/hitsplats.dmi new file mode 100644 index 00000000000..b501854b6cc Binary files /dev/null and b/icons/effects/hitsplats.dmi differ diff --git a/icons/effects/interaction_points.dmi b/icons/effects/interaction_points.dmi deleted file mode 100644 index 5523727247c..00000000000 Binary files a/icons/effects/interaction_points.dmi and /dev/null differ diff --git a/icons/effects/lighting_object.dmi b/icons/effects/lighting_object.dmi index d2e50395872..f2d5960d91b 100644 Binary files a/icons/effects/lighting_object.dmi and b/icons/effects/lighting_object.dmi differ diff --git a/icons/effects/mapping_helpers.dmi b/icons/effects/mapping_helpers.dmi index d7ee50ebe8d..1a6984cdd90 100644 Binary files a/icons/effects/mapping_helpers.dmi and b/icons/effects/mapping_helpers.dmi differ diff --git a/icons/effects/ore_visuals.dmi b/icons/effects/ore_visuals.dmi index a27dbc30a3b..855186d7ad9 100644 Binary files a/icons/effects/ore_visuals.dmi and b/icons/effects/ore_visuals.dmi differ diff --git a/icons/effects/random_spawners.dmi b/icons/effects/random_spawners.dmi index 4d816c6df80..014a14ca4b1 100644 Binary files a/icons/effects/random_spawners.dmi and b/icons/effects/random_spawners.dmi differ diff --git a/icons/effects/tasks.dmi b/icons/effects/tasks.dmi new file mode 100644 index 00000000000..58d398649b5 Binary files /dev/null and b/icons/effects/tasks.dmi differ diff --git a/icons/effects/vent_overlays.dmi b/icons/effects/vent_overlays.dmi index 375117f4c79..c1e676591e7 100644 Binary files a/icons/effects/vent_overlays.dmi and b/icons/effects/vent_overlays.dmi differ diff --git a/icons/hud/actions.dmi b/icons/hud/actions.dmi index 071ba38f726..6d51cc55534 100644 Binary files a/icons/hud/actions.dmi and b/icons/hud/actions.dmi differ diff --git a/icons/hud/screen_voidwalker.dmi b/icons/hud/screen_voidwalker.dmi index 7eb522053be..a4a5c5acd09 100644 Binary files a/icons/hud/screen_voidwalker.dmi and b/icons/hud/screen_voidwalker.dmi differ diff --git a/icons/map_icons/items/_item.dmi b/icons/map_icons/items/_item.dmi index e3ea03c6c65..16535bf205f 100644 Binary files a/icons/map_icons/items/_item.dmi and b/icons/map_icons/items/_item.dmi differ diff --git a/icons/mob/actions/backgrounds.dmi b/icons/mob/actions/backgrounds.dmi index ecbda704fe1..1256caf05b4 100644 Binary files a/icons/mob/actions/backgrounds.dmi and b/icons/mob/actions/backgrounds.dmi differ diff --git a/icons/mob/clothing/belt_mirror.dmi b/icons/mob/clothing/belt_mirror.dmi index 06b8b4e1d9b..81eef910392 100644 Binary files a/icons/mob/clothing/belt_mirror.dmi and b/icons/mob/clothing/belt_mirror.dmi differ diff --git a/icons/mob/clothing/head/costume.dmi b/icons/mob/clothing/head/costume.dmi index ea18067ebc1..ac776302e25 100644 Binary files a/icons/mob/clothing/head/costume.dmi and b/icons/mob/clothing/head/costume.dmi differ diff --git a/icons/mob/clothing/head/hats.dmi b/icons/mob/clothing/head/hats.dmi index 712dbad93e6..e29206ddc65 100644 Binary files a/icons/mob/clothing/head/hats.dmi and b/icons/mob/clothing/head/hats.dmi differ diff --git a/icons/mob/clothing/head/spacehelm.dmi b/icons/mob/clothing/head/spacehelm.dmi index b623fa0beea..54ae7250398 100644 Binary files a/icons/mob/clothing/head/spacehelm.dmi and b/icons/mob/clothing/head/spacehelm.dmi differ diff --git a/icons/mob/clothing/mask.dmi b/icons/mob/clothing/mask.dmi index 25f10c4b648..c55785d0412 100644 Binary files a/icons/mob/clothing/mask.dmi and b/icons/mob/clothing/mask.dmi differ diff --git a/icons/mob/clothing/neck.dmi b/icons/mob/clothing/neck.dmi index a44781036a0..6dad4d75a7b 100644 Binary files a/icons/mob/clothing/neck.dmi and b/icons/mob/clothing/neck.dmi differ diff --git a/icons/mob/clothing/under/captain.dmi b/icons/mob/clothing/under/captain.dmi index 49de8ab784e..05f6b707c01 100644 Binary files a/icons/mob/clothing/under/captain.dmi and b/icons/mob/clothing/under/captain.dmi differ diff --git a/icons/mob/clothing/under/syndicate.dmi b/icons/mob/clothing/under/syndicate.dmi index 0e9d8dfc91b..f2ea936badd 100644 Binary files a/icons/mob/clothing/under/syndicate.dmi and b/icons/mob/clothing/under/syndicate.dmi differ diff --git a/icons/mob/human/species/ghost.dmi b/icons/mob/human/species/ghost.dmi index f22d3fc386c..42185e3db54 100644 Binary files a/icons/mob/human/species/ghost.dmi and b/icons/mob/human/species/ghost.dmi differ diff --git a/icons/mob/inhands/64x64_lefthand.dmi b/icons/mob/inhands/64x64_lefthand.dmi index 25b5feddc22..b2e48a848b2 100644 Binary files a/icons/mob/inhands/64x64_lefthand.dmi and b/icons/mob/inhands/64x64_lefthand.dmi differ diff --git a/icons/mob/inhands/64x64_righthand.dmi b/icons/mob/inhands/64x64_righthand.dmi index f3a9caa9183..9ab5cb39381 100644 Binary files a/icons/mob/inhands/64x64_righthand.dmi and b/icons/mob/inhands/64x64_righthand.dmi differ diff --git a/icons/mob/inhands/equipment/custodial_lefthand.dmi b/icons/mob/inhands/equipment/custodial_lefthand.dmi index 2350998aa95..d70aa537619 100644 Binary files a/icons/mob/inhands/equipment/custodial_lefthand.dmi and b/icons/mob/inhands/equipment/custodial_lefthand.dmi differ diff --git a/icons/mob/inhands/equipment/custodial_righthand.dmi b/icons/mob/inhands/equipment/custodial_righthand.dmi index df4738e3fd2..fce559bdfea 100644 Binary files a/icons/mob/inhands/equipment/custodial_righthand.dmi and b/icons/mob/inhands/equipment/custodial_righthand.dmi differ diff --git a/icons/mob/inhands/equipment/tools_lefthand.dmi b/icons/mob/inhands/equipment/tools_lefthand.dmi index c8936fde8da..adaedb6483f 100644 Binary files a/icons/mob/inhands/equipment/tools_lefthand.dmi and b/icons/mob/inhands/equipment/tools_lefthand.dmi differ diff --git a/icons/mob/inhands/equipment/tools_righthand.dmi b/icons/mob/inhands/equipment/tools_righthand.dmi index 192413a739f..454a225c82a 100644 Binary files a/icons/mob/inhands/equipment/tools_righthand.dmi and b/icons/mob/inhands/equipment/tools_righthand.dmi differ diff --git a/icons/mob/silicon/aibots.dmi b/icons/mob/silicon/aibots.dmi index fa4c11f891a..2df5bce43a3 100644 Binary files a/icons/mob/silicon/aibots.dmi and b/icons/mob/silicon/aibots.dmi differ diff --git a/icons/mob/simple/animal.dmi b/icons/mob/simple/animal.dmi index e09af620e94..52073541f89 100644 Binary files a/icons/mob/simple/animal.dmi and b/icons/mob/simple/animal.dmi differ diff --git a/icons/mob/simple/arachnoid.dmi b/icons/mob/simple/arachnoid.dmi index 7e15fde6852..35e5212b817 100644 Binary files a/icons/mob/simple/arachnoid.dmi and b/icons/mob/simple/arachnoid.dmi differ diff --git a/icons/mob/simple/lavaland/bileworm.dmi b/icons/mob/simple/lavaland/bileworm.dmi index e3072364e93..e3206d648d5 100644 Binary files a/icons/mob/simple/lavaland/bileworm.dmi and b/icons/mob/simple/lavaland/bileworm.dmi differ diff --git a/icons/mob/simple/lavaland/bileworm_jump.dmi b/icons/mob/simple/lavaland/bileworm_jump.dmi new file mode 100644 index 00000000000..5f7491f1aa1 Binary files /dev/null and b/icons/mob/simple/lavaland/bileworm_jump.dmi differ diff --git a/icons/mob/simple/lavaland/bileworm_old.dmi b/icons/mob/simple/lavaland/bileworm_old.dmi new file mode 100644 index 00000000000..8337f6cc4f1 Binary files /dev/null and b/icons/mob/simple/lavaland/bileworm_old.dmi differ diff --git a/icons/mob/simple/lavaland/lavaland_monsters.dmi b/icons/mob/simple/lavaland/lavaland_monsters.dmi index 3f5eb9cbd3b..f338fab310a 100644 Binary files a/icons/mob/simple/lavaland/lavaland_monsters.dmi and b/icons/mob/simple/lavaland/lavaland_monsters.dmi differ diff --git a/icons/mob/simple/lavaland/tendril.dmi b/icons/mob/simple/lavaland/tendril.dmi new file mode 100644 index 00000000000..0bbd0ccbe21 Binary files /dev/null and b/icons/mob/simple/lavaland/tendril.dmi differ diff --git a/icons/mob/simple/mob.dmi b/icons/mob/simple/mob.dmi index 74b90ffd95b..d34276cd3f3 100644 Binary files a/icons/mob/simple/mob.dmi and b/icons/mob/simple/mob.dmi differ diff --git a/icons/mob/telegraphing/telegraph.dmi b/icons/mob/telegraphing/telegraph.dmi index fb8b7bc83fd..1483234c763 100644 Binary files a/icons/mob/telegraphing/telegraph.dmi and b/icons/mob/telegraphing/telegraph.dmi differ diff --git a/icons/obj/chairs.dmi b/icons/obj/chairs.dmi index b1432f16701..26a1861af2f 100644 Binary files a/icons/obj/chairs.dmi and b/icons/obj/chairs.dmi differ diff --git a/icons/obj/clothing/head/costume.dmi b/icons/obj/clothing/head/costume.dmi index 9e3ad9e212c..fce68eb8f21 100644 Binary files a/icons/obj/clothing/head/costume.dmi and b/icons/obj/clothing/head/costume.dmi differ diff --git a/icons/obj/clothing/head/hats.dmi b/icons/obj/clothing/head/hats.dmi index b30c0c81ace..6ba6906d2aa 100644 Binary files a/icons/obj/clothing/head/hats.dmi and b/icons/obj/clothing/head/hats.dmi differ diff --git a/icons/obj/clothing/head/spacehelm.dmi b/icons/obj/clothing/head/spacehelm.dmi index 05362ab689f..5bf888d1216 100644 Binary files a/icons/obj/clothing/head/spacehelm.dmi and b/icons/obj/clothing/head/spacehelm.dmi differ diff --git a/icons/obj/clothing/masks.dmi b/icons/obj/clothing/masks.dmi index a2dac17cc8b..cb9c4a72e8d 100644 Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ diff --git a/icons/obj/clothing/modsuit/mod_modules.dmi b/icons/obj/clothing/modsuit/mod_modules.dmi index 7ff5dcd95a9..4e4b07b70ff 100644 Binary files a/icons/obj/clothing/modsuit/mod_modules.dmi and b/icons/obj/clothing/modsuit/mod_modules.dmi differ diff --git a/icons/obj/clothing/neck.dmi b/icons/obj/clothing/neck.dmi index 0b19dff85b0..6fc8b054ca5 100644 Binary files a/icons/obj/clothing/neck.dmi and b/icons/obj/clothing/neck.dmi differ diff --git a/icons/obj/clothing/under/captain.dmi b/icons/obj/clothing/under/captain.dmi index 335ce733253..8192379d101 100644 Binary files a/icons/obj/clothing/under/captain.dmi and b/icons/obj/clothing/under/captain.dmi differ diff --git a/icons/obj/clothing/under/syndicate.dmi b/icons/obj/clothing/under/syndicate.dmi index de712a41f6b..49407a02d4f 100644 Binary files a/icons/obj/clothing/under/syndicate.dmi and b/icons/obj/clothing/under/syndicate.dmi differ diff --git a/icons/obj/devices/tool.dmi b/icons/obj/devices/tool.dmi index 9075c0d2063..5a4f58b0de3 100644 Binary files a/icons/obj/devices/tool.dmi and b/icons/obj/devices/tool.dmi differ diff --git a/icons/obj/doors/airlocks/syndicate/highsec.dmi b/icons/obj/doors/airlocks/syndicate/highsec.dmi new file mode 100644 index 00000000000..fe54b6826cc Binary files /dev/null and b/icons/obj/doors/airlocks/syndicate/highsec.dmi differ diff --git a/icons/obj/doors/syndicateshutters.dmi b/icons/obj/doors/syndicateshutters.dmi new file mode 100644 index 00000000000..ea4453bf0cc Binary files /dev/null and b/icons/obj/doors/syndicateshutters.dmi differ diff --git a/icons/obj/fluff/flora/rocks.dmi b/icons/obj/fluff/flora/rocks.dmi index b972fef0e7e..098f0b03fbb 100644 Binary files a/icons/obj/fluff/flora/rocks.dmi and b/icons/obj/fluff/flora/rocks.dmi differ diff --git a/icons/obj/machines/camera.dmi b/icons/obj/machines/camera.dmi index 0b0ba30483c..48fbc621f27 100644 Binary files a/icons/obj/machines/camera.dmi and b/icons/obj/machines/camera.dmi differ diff --git a/icons/obj/machines/kitchen.dmi b/icons/obj/machines/kitchen.dmi index 2cc92972f9e..33084157361 100644 Binary files a/icons/obj/machines/kitchen.dmi and b/icons/obj/machines/kitchen.dmi differ diff --git a/icons/obj/machines/mining_machines.dmi b/icons/obj/machines/mining_machines.dmi index c1a4076e3a2..a895f18da00 100644 Binary files a/icons/obj/machines/mining_machines.dmi and b/icons/obj/machines/mining_machines.dmi differ diff --git a/icons/obj/machines/telepad.dmi b/icons/obj/machines/telepad.dmi index b06436ebd63..c7f72d09d51 100644 Binary files a/icons/obj/machines/telepad.dmi and b/icons/obj/machines/telepad.dmi differ diff --git a/icons/obj/mining_zones/artefacts.dmi b/icons/obj/mining_zones/artefacts.dmi index 86cfdcd7624..1e9325be8d0 100644 Binary files a/icons/obj/mining_zones/artefacts.dmi and b/icons/obj/mining_zones/artefacts.dmi differ diff --git a/icons/obj/mining_zones/ash_flora.dmi b/icons/obj/mining_zones/ash_flora.dmi index d796c200071..5d64b1b931b 100644 Binary files a/icons/obj/mining_zones/ash_flora.dmi and b/icons/obj/mining_zones/ash_flora.dmi differ diff --git a/icons/obj/mining_zones/terrain.dmi b/icons/obj/mining_zones/terrain.dmi index f46a677296b..edbd2958a69 100644 Binary files a/icons/obj/mining_zones/terrain.dmi and b/icons/obj/mining_zones/terrain.dmi differ diff --git a/icons/obj/ore.dmi b/icons/obj/ore.dmi index 81a7cb03fdf..8cb07a5312d 100644 Binary files a/icons/obj/ore.dmi and b/icons/obj/ore.dmi differ diff --git a/icons/obj/science/gizmos.dmi b/icons/obj/science/gizmos.dmi new file mode 100644 index 00000000000..30792121a2c Binary files /dev/null and b/icons/obj/science/gizmos.dmi differ diff --git a/icons/obj/service/hand_of_god_structures.dmi b/icons/obj/service/hand_of_god_structures.dmi index cbbc36d7718..e9d94cef78f 100644 Binary files a/icons/obj/service/hand_of_god_structures.dmi and b/icons/obj/service/hand_of_god_structures.dmi differ diff --git a/icons/obj/service/hydroponics/seeds.dmi b/icons/obj/service/hydroponics/seeds.dmi index e180060041b..d08fbb8541d 100644 Binary files a/icons/obj/service/hydroponics/seeds.dmi and b/icons/obj/service/hydroponics/seeds.dmi differ diff --git a/icons/obj/signboards.dmi b/icons/obj/signboards.dmi new file mode 100644 index 00000000000..c1db06ee9b7 Binary files /dev/null and b/icons/obj/signboards.dmi differ diff --git a/icons/obj/stack_objects.dmi b/icons/obj/stack_objects.dmi index 80845395803..8504bbc4690 100644 Binary files a/icons/obj/stack_objects.dmi and b/icons/obj/stack_objects.dmi differ diff --git a/icons/obj/watercloset.dmi b/icons/obj/watercloset.dmi index c8bee528558..1f23f5ac45e 100644 Binary files a/icons/obj/watercloset.dmi and b/icons/obj/watercloset.dmi differ diff --git a/icons/obj/weapons/guns/ammo.dmi b/icons/obj/weapons/guns/ammo.dmi index 1eb10778228..06eb704f52d 100644 Binary files a/icons/obj/weapons/guns/ammo.dmi and b/icons/obj/weapons/guns/ammo.dmi differ diff --git a/icons/obj/weapons/guns/magic.dmi b/icons/obj/weapons/guns/magic.dmi index 34256a71060..23ef6874986 100644 Binary files a/icons/obj/weapons/guns/magic.dmi and b/icons/obj/weapons/guns/magic.dmi differ diff --git a/icons/obj/weapons/guns/projectiles.dmi b/icons/obj/weapons/guns/projectiles.dmi index 333f8da065d..19bdf00bac9 100644 Binary files a/icons/obj/weapons/guns/projectiles.dmi and b/icons/obj/weapons/guns/projectiles.dmi differ diff --git a/icons/obj/weapons/naval_cannon.dmi b/icons/obj/weapons/naval_cannon.dmi new file mode 100644 index 00000000000..bf6f956defe Binary files /dev/null and b/icons/obj/weapons/naval_cannon.dmi differ diff --git a/icons/obj/weapons/restraints.dmi b/icons/obj/weapons/restraints.dmi index ddd3bf96436..aa24ef81c40 100644 Binary files a/icons/obj/weapons/restraints.dmi and b/icons/obj/weapons/restraints.dmi differ diff --git a/icons/turf/debug.dmi b/icons/turf/debug.dmi index 4bc24f6c787..6864dd09e6c 100644 Binary files a/icons/turf/debug.dmi and b/icons/turf/debug.dmi differ diff --git a/icons/turf/floors/shale.dmi b/icons/turf/floors/shale.dmi new file mode 100644 index 00000000000..e7bdc5af6f6 Binary files /dev/null and b/icons/turf/floors/shale.dmi differ diff --git a/icons/turf/floors/shale.png b/icons/turf/floors/shale.png new file mode 100644 index 00000000000..3bc0d0247d5 Binary files /dev/null and b/icons/turf/floors/shale.png differ diff --git a/icons/turf/walls/red_wall.png.toml b/icons/turf/floors/shale.png.toml similarity index 56% rename from icons/turf/walls/red_wall.png.toml rename to icons/turf/floors/shale.png.toml index 917dc8ee377..2b6b33e54e2 100644 --- a/icons/turf/walls/red_wall.png.toml +++ b/icons/turf/floors/shale.png.toml @@ -1,14 +1,14 @@ -output_name = "red_wall" +output_name = "shale" template = "bitmask/diagonal_32x32.toml" [icon_size] -x = 40 -y = 40 +x = 48 +y = 48 [output_icon_size] -x = 40 -y = 40 +x = 48 +y = 48 [cut_pos] -x = 20 -y = 20 \ No newline at end of file +x = 24 +y = 24 diff --git a/icons/turf/floors/shale_variants.dmi b/icons/turf/floors/shale_variants.dmi new file mode 100644 index 00000000000..3a6b6981227 Binary files /dev/null and b/icons/turf/floors/shale_variants.dmi differ diff --git a/icons/turf/floors/siderite.dmi b/icons/turf/floors/siderite.dmi new file mode 100644 index 00000000000..570ddb23c91 Binary files /dev/null and b/icons/turf/floors/siderite.dmi differ diff --git a/icons/turf/floors/siderite.png b/icons/turf/floors/siderite.png new file mode 100644 index 00000000000..989acc29e06 Binary files /dev/null and b/icons/turf/floors/siderite.png differ diff --git a/icons/turf/floors/siderite.png.toml b/icons/turf/floors/siderite.png.toml new file mode 100644 index 00000000000..70f87a5c0ff --- /dev/null +++ b/icons/turf/floors/siderite.png.toml @@ -0,0 +1,14 @@ +output_name = "siderite" +template = "bitmask/diagonal_32x32.toml" + +[icon_size] +x = 48 +y = 48 + +[output_icon_size] +x = 48 +y = 48 + +[cut_pos] +x = 24 +y = 24 diff --git a/icons/turf/floors/siderite_variants.dmi b/icons/turf/floors/siderite_variants.dmi new file mode 100644 index 00000000000..2d4c03d12b0 Binary files /dev/null and b/icons/turf/floors/siderite_variants.dmi differ diff --git a/icons/turf/floors/water_lavaland.dmi b/icons/turf/floors/water_lavaland.dmi new file mode 100644 index 00000000000..9e206b8e471 Binary files /dev/null and b/icons/turf/floors/water_lavaland.dmi differ diff --git a/icons/turf/floors/water_lavaland.png b/icons/turf/floors/water_lavaland.png new file mode 100644 index 00000000000..ee89d32d717 Binary files /dev/null and b/icons/turf/floors/water_lavaland.png differ diff --git a/icons/turf/floors/water_lavaland.png.toml b/icons/turf/floors/water_lavaland.png.toml new file mode 100644 index 00000000000..2b77ebfc7ec --- /dev/null +++ b/icons/turf/floors/water_lavaland.png.toml @@ -0,0 +1,2 @@ +output_name = "water_lavaland" +template = "bitmask/diagonal_32x32.toml" diff --git a/icons/turf/mining.dmi b/icons/turf/mining.dmi index 4138f08a6bf..79f41ca92ab 100644 Binary files a/icons/turf/mining.dmi and b/icons/turf/mining.dmi differ diff --git a/icons/turf/walls/red_rock.dmi b/icons/turf/walls/red_rock.dmi new file mode 100644 index 00000000000..1496a01b4d6 Binary files /dev/null and b/icons/turf/walls/red_rock.dmi differ diff --git a/icons/turf/walls/red_rock.png b/icons/turf/walls/red_rock.png new file mode 100644 index 00000000000..38432c09431 Binary files /dev/null and b/icons/turf/walls/red_rock.png differ diff --git a/icons/turf/walls/red_rock.png.toml b/icons/turf/walls/red_rock.png.toml new file mode 100644 index 00000000000..dff64064068 --- /dev/null +++ b/icons/turf/walls/red_rock.png.toml @@ -0,0 +1,14 @@ +output_name = "red_rock" +template = "bitmask/diagonal_32x32.toml" + +[icon_size] +x = 48 +y = 48 + +[output_icon_size] +x = 48 +y = 48 + +[cut_pos] +x = 24 +y = 24 diff --git a/icons/turf/walls/red_wall.dmi b/icons/turf/walls/red_wall.dmi deleted file mode 100644 index 8dc959f36cb..00000000000 Binary files a/icons/turf/walls/red_wall.dmi and /dev/null differ diff --git a/icons/turf/walls/red_wall.png b/icons/turf/walls/red_wall.png deleted file mode 100644 index 312386a5377..00000000000 Binary files a/icons/turf/walls/red_wall.png and /dev/null differ diff --git a/icons/turf/walls/reinforced_rock.dmi b/icons/turf/walls/reinforced_rock.dmi index e00e5148204..dcfeef557cd 100644 Binary files a/icons/turf/walls/reinforced_rock.dmi and b/icons/turf/walls/reinforced_rock.dmi differ diff --git a/icons/turf/walls/reinforced_rock.png b/icons/turf/walls/reinforced_rock.png index 544a877ec1a..3fac4157f2d 100644 Binary files a/icons/turf/walls/reinforced_rock.png and b/icons/turf/walls/reinforced_rock.png differ diff --git a/icons/turf/walls/shale.dmi b/icons/turf/walls/shale.dmi new file mode 100644 index 00000000000..8af895c3dbd Binary files /dev/null and b/icons/turf/walls/shale.dmi differ diff --git a/icons/turf/walls/shale.png b/icons/turf/walls/shale.png new file mode 100644 index 00000000000..05f3331b224 Binary files /dev/null and b/icons/turf/walls/shale.png differ diff --git a/icons/turf/walls/shale.png.toml b/icons/turf/walls/shale.png.toml new file mode 100644 index 00000000000..2b6b33e54e2 --- /dev/null +++ b/icons/turf/walls/shale.png.toml @@ -0,0 +1,14 @@ +output_name = "shale" +template = "bitmask/diagonal_32x32.toml" + +[icon_size] +x = 48 +y = 48 + +[output_icon_size] +x = 48 +y = 48 + +[cut_pos] +x = 24 +y = 24 diff --git a/interface/interface.dm b/interface/interface.dm index cdf929c5efa..5f0378d5dd5 100644 --- a/interface/interface.dm +++ b/interface/interface.dm @@ -120,13 +120,24 @@ if(prefs.lastchangelog != GLOB.changelog_hash) prefs.lastchangelog = GLOB.changelog_hash prefs.save_preferences() - winset(src, "infobuttons.changelog", "font-style=;") /client/verb/hotkeys_help() set name = "Hotkeys Help" - set category = "OOC" + set hidden = TRUE if(!GLOB.hotkeys_tgui) GLOB.hotkeys_tgui = new /datum/hotkeys_help() GLOB.hotkeys_tgui.ui_interact(mob) + +/client/verb/emote_panel() + set name = "Emote Panel" + set hidden = TRUE + + if(!isliving(mob)) + to_chat(mob, span_notice("You can only use this while you're alive!")) + return + + if(!GLOB.emote_panel) + GLOB.emote_panel = new /datum/emote_panel() + GLOB.emote_panel.ui_interact(mob) diff --git a/interface/menu.dm b/interface/menu.dm deleted file mode 100644 index ec9719e8236..00000000000 --- a/interface/menu.dm +++ /dev/null @@ -1,19 +0,0 @@ -/* -/datum/verbs/menu/Example/verb/Example() - set name = "" //if this starts with @ the verb is not created and name becomes the command to invoke. - set desc = "" //desc is the text given to this entry in the menu - //You can not use src in these verbs. It will be the menu at compile time, but the client at runtime. -*/ - -GLOBAL_LIST_EMPTY(menulist) - -/datum/verbs/menu - var/default //default checked type. - //Set to true to append our children to our parent, - //Rather then add us as a node (used for having more then one checkgroups in the same menu) - -/datum/verbs/menu/GetList() - return GLOB.menulist - -/datum/verbs/menu/HandleVerb(list/entry, verbpath, client/C) - return list2params(entry) diff --git a/interface/skin.dmf b/interface/skin.dmf index 86647d13523..ed16afd6222 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -8,41 +8,6 @@ macro "default" name = "SHIFT+UP" command = ".winset :map.right-click=true" - -menu "menu" - elem - name = "&File" - command = "" - saved-params = "is-checked" - elem "reconnectbutton" - name = "&Reconnect" - command = ".reconnect" - category = "&File" - saved-params = "is-checked" - elem - name = "&Quit\tAlt-F4" - command = ".quit" - category = "&File" - saved-params = "is-checked" - elem "help-menu" - name = "&Help" - command = "" - saved-params = "is-checked" - elem - name = "&Admin Help\tF1" - command = "adminhelp" - category = "&Help" - saved-params = "is-checked" - elem - name = "&Hotkeys" - command = "Hotkeys-Help" - category = "&Help" - saved-params = "is-checked" - elem "Use Internet Routing Relay" - name = "Internet Routing Relays" - command = "go2relay" - saved-params = "is-checked" - window "mainwindow" elem "mainwindow" type = MAIN @@ -55,7 +20,6 @@ window "mainwindow" statusbar = false icon = 'modular_zubbers\\icons\\UI_Icons\\common\\bubber_32.png' macro = "default" - menu = "menu" elem "split" type = CHILD pos = 0,0 @@ -160,26 +124,150 @@ window "info_and_buttons" splitter = 2 show-splitter = false +window "infobuttons" + elem "infobuttons" + type = MAIN + pos = 291,0 + size = 676x30 + anchor1 = 0,0 + anchor2 = 100,100 + background-color = none + saved-params = "pos;size;is-minimized;is-maximized" + is-pane = true + outer-size = 692x88 + outer-pos = 291,0 + inner-size = 676x30 + inner-pos = 8,31 + screen-size = 1920x1040 + elem "options" + type = BUTTON + pos = 0,5 + size = 88x27 + anchor1 = 0,0 + anchor2 = 15,100 + background-color = none + saved-params = "is-checked" + text = "Menu" + command = "open-escape-menu" + elem "hotkeys" + type = BUTTON + pos = 92,5 + size = 88x27 + anchor1 = 15,0 + anchor2 = 29,100 + background-color = none + saved-params = "is-checked" + text = "Hotkeys" + command = "Hotkeys-Help" + elem "emotes" + type = BUTTON + pos = 185,5 + size = 88x27 + anchor1 = 29,0 + anchor2 = 43,100 + background-color = none + saved-params = "is-checked" + text = "Emotes" + command = "Emote-Panel" + elem "fullscreen-toggle" + type = BUTTON + pos = 277,5 + size = 88x27 + anchor1 = 43,0 + anchor2 = 57,100 + background-color = none + saved-params = "is-checked" + text = "Fullscreen" + command = "fullscreen" + elem "reconnect" + type = BUTTON + pos = 369,5 + size = 88x27 + anchor1 = 57,0 + anchor2 = 71,100 + background-color = none + saved-params = "is-checked" + text = "Reconnect" + command = ".reconnect" + elem "chat" + type = BUTTON + pos = 560,5 + size = 112x27 + anchor1 = 85,0 + anchor2 = 99,100 + background-color = none + saved-params = "is-checked" + text = "Toggle Stat Panel" + command = "toggle-stat-panel" + window "infowindow" elem "infowindow" type = MAIN - pos = 281,0 + pos = 281,5 size = 640x475 anchor1 = -1,-1 anchor2 = -1,-1 saved-params = "pos;size;is-minimized;is-maximized" is-pane = true - elem "info" + elem "info_split" type = CHILD pos = 0,5 + anchor1 = 0,0 + anchor2 = 100,100 + size = 640x475 + is-vert = false + splitter = 97.5 + background-color = #ffc41f + show-splitter = false + saved-params = "splitter" + left = "info" + right = "input_buttons" + +window "info" + elem "info_main" + type = MAIN + pos = 0,0 + size = 640x475 + anchor1 = 0,0 + anchor2 = 100,100 + saved-params = "pos;size;is-minimized;is-maximized" + is-pane = true + elem "info_child" + type = CHILD + pos = 0,0 size = 640x475 anchor1 = 0,0 anchor2 = 100,100 saved-params = "splitter" + splitter = 40 + background-color = #202020 left = "statwindow" right = "outputwindow" is-vert = false +window "input_buttons" + elem "input_buttons_main" + type = MAIN + pos = 0,0 + size = 640x475 + anchor1 = 0,0 + anchor2 = 100,100 + saved-params = "pos;size;is-minimized;is-maximized" + is-pane = true + elem "input_buttons_child" + type = CHILD + pos = 0,0 + size = 640x475 + anchor1 = 0,0 + anchor2 = 100,100 + background-color = #ffc41f + saved-params = "splitter" + left = "inputwindow" + right = "inputbuttons" + is-vert = true + splitter = 70 + show-splitter = false + window "outputwindow" elem "outputwindow" type = MAIN @@ -189,19 +277,14 @@ window "outputwindow" anchor2 = -1,-1 saved-params = "pos;size;is-minimized;is-maximized" is-pane = true - elem "output_input_child" + elem "output_selector_screen" type = CHILD - pos = 0,0 size = 640x475 anchor1 = 0,0 anchor2 = 100,100 - background-color = #ffc41f saved-params = "splitter" + background-color = #ffc41f left = "output_selector" - right = "input_and_buttons" - is-vert = false - splitter = 96 - show-splitter = false window "output_selector" elem "output_selector" @@ -221,27 +304,6 @@ window "output_selector" saved-params = "splitter" left = "output_legacy" is-vert = false - -window "input_and_buttons" - elem "input_and_buttons" - type = MAIN - pos = 291,0 - size = 640x20 - anchor1 = -1,-1 - anchor2 = -1,-1 - saved-params = "pos;size;is-minimized;is-maximized" - is-pane = true - elem "input_buttons_child" - type = CHILD - pos = 0,0 - size = 640x20 - anchor1 = 0,0 - anchor2 = 100,100 - background-color = #ffc41f - saved-params = "splitter" - left = "inputwindow" - right = "inputbuttons" - is-vert = true splitter = 80 show-splitter = false @@ -249,16 +311,16 @@ window "inputwindow" elem "inputwindow" type = MAIN pos = 575,0 - size = 520x25 - anchor1 = -1,-1 - anchor2 = -1,-1 + size = 480x25 + anchor1 = 0,0 + anchor2 = 70,100 background-color = none saved-params = "pos;size;is-minimized;is-maximized" is-pane = true elem "input" type = INPUT pos = 0,0 - size = 520x20 + size = 480x20 anchor1 = 0,0 anchor2 = 100,100 is-default = true @@ -270,8 +332,8 @@ window "inputbuttons" elem "inputbuttons" type = MAIN pos = 291,0 - size = 120x25 - anchor1 = 0,0 + size = 160x25 + anchor1 = 70,0 anchor2 = 100,100 saved-params = "pos;size;is-minimized;is-maximized" is-pane = true @@ -280,38 +342,51 @@ window "inputbuttons" pos = 0,0 size = 40x20 anchor1 = 0,0 - anchor2 = 33,100 + anchor2 = 25,100 font-size = 4 border = line saved-params = "is-checked" text = "Say" - command = ".winset \"saybutton.is-checked=true ? input.command=\"!say \\\"\" : input.command=\"\"saybutton.is-checked=true ? mebutton.is-checked=false\"\"saybutton.is-checked=true ? oocbutton.is-checked=false\"" + command = ".winset \"saybutton.is-checked=true ? input.command=\"!say \\\"\" : input.command=\"\"saybutton.is-checked=true ? mebutton.is-checked=false\"\"saybutton.is-checked=true ? oocbutton.is-checked=false\"\"saybutton.is-checked=true ? whisperbutton.is-checked=false\"" + is-flat = true + button-type = pushbox + elem "whisperbutton" + type = BUTTON + pos = 40,0 + size = 40x20 + anchor1 = 25,0 + anchor2 = 50,100 + font-size = 4 + border = line + saved-params = "is-checked" + text = "Whisper" + command = ".winset \"whisperbutton.is-checked=true ? input.command=\"!say \\\"#\" : input.command=\"\"whisperbutton.is-checked=false ? saybutton.is-checked=false\"\"whisperbutton.is-checked=true ? mebutton.is-checked=false\"\"whisperbutton.is-checked=true ? oocbutton.is-checked=false\"" is-flat = true button-type = pushbox elem "mebutton" type = BUTTON - pos = 40,0 + pos = 80,0 size = 40x20 - anchor1 = 33,0 - anchor2 = 66,100 + anchor1 = 50,0 + anchor2 = 75,100 font-size = 4 border = line saved-params = "is-checked" text = "Me" - command = ".winset \"mebutton.is-checked=true ? input.command=\"!me \\\"\" : input.command=\"\"mebutton.is-checked=true ? saybutton.is-checked=false\"\"mebutton.is-checked=true ? oocbutton.is-checked=false\"" + command = ".winset \"mebutton.is-checked=true ? input.command=\"!me \\\"\" : input.command=\"\"mebutton.is-checked=true ? saybutton.is-checked=false\"\"mebutton.is-checked=true ? oocbutton.is-checked=false\"\"mebutton.is-checked=true ? whisperbutton.is-checked=false\"" is-flat = true button-type = pushbox elem "oocbutton" type = BUTTON - pos = 80,0 + pos = 120,0 size = 40x20 - anchor1 = 66,0 + anchor1 = 75,0 anchor2 = 100,100 font-size = 4 border = line saved-params = "is-checked" text = "OOC" - command = ".winset \"oocbutton.is-checked=true ? input.command=\"!ooc \\\"\" : input.command=\"\"oocbutton.is-checked=true ? mebutton.is-checked=false\"\"oocbutton.is-checked=true ? saybutton.is-checked=false\"" + command = ".winset \"oocbutton.is-checked=true ? input.command=\"!ooc \\\"\" : input.command=\"\"oocbutton.is-checked=true ? mebutton.is-checked=false\"\"oocbutton.is-checked=true ? saybutton.is-checked=false\"\"oocbutton.is-checked=true ? whisperbutton.is-checked=false\"" is-flat = true button-type = pushbox diff --git a/interface/stylesheet.dm b/interface/stylesheet.dm index b407520e616..7cb2cecfe49 100644 --- a/interface/stylesheet.dm +++ b/interface/stylesheet.dm @@ -137,121 +137,9 @@ h1.alert, h2.alert {color: #000000;} .clown {color: #FF69Bf; font-size: 3; font-family: "Comic Sans MS", cursive, sans-serif; font-weight: bold;} .singing {font-family: "Trebuchet MS", cursive, sans-serif; font-style: italic;} .his_grace {color: #15D512; font-family: "Courier New", cursive, sans-serif; font-style: italic;} -.hypnophrase {color: #3bb5d3; font-weight: bold; animation: hypnocolor 1500ms infinite; animation-direction: alternate;} - @keyframes hypnocolor { - 0% {color: #0d0d0d;} - 25% {color: #410194;} - 50% {color: #7f17d8;} - 75% {color: #410194;} - 100% {color: #3bb5d3;} -} -// SKYRAT EDIT ADDITION BEGIN +.hypnophrase {color: #3bb5d3; font-weight: bold;} -.velvet {color: #660015; font-weight: bold; animation: velvet 5000ms infinite;} - @keyframes velvet { - 0% {color: #400020; } - 40% {color: #FF0000; } - 50% {color: #FF8888; } - 60% {color: #FF0000; } - 100% {color: #400020; } -} - -.hexnut {color: #0099ff; font-weight: bold; animation: hexnut 5000ms infinite; animation-direction: alternate;} - @keyframes hexnut { - 0% {color: #0099ff;} - 35% {color: #a64dff;} - 50% {color: #00997a;} - 60% {color: #ffb31a;} - 100% {color: #ff33cc;} -} - -.glossy {color: #9b6000; font-weight: bold; animation: glossy 5000ms infinite;} - @keyframes glossy { - 0% {color: #9b6000} - 30% {color: #c88800} - 40% {color: #bdbd00} - 50% {color: #c88800} - 100% {color: #9b6000} -} - -.doyourjobidiot { - color: #c51e1e; - text-shadow: 0 0 4px #e22525; - font-size: 125%; - font-weight: bold; - animation: flashingfuckingwarning 250ms infinite; -} - -@keyframes flashingfuckingwarning { - 0% { - color: #c51e1e; - text-shadow: 0 0 4px #c51e1e; - } - - 50% { - color: #e22525; - text-shadow: 0 0 8px #e22525; - } - - 100% { - color: #c51e1e; - text-shadow: 0 0 4px #c51e1e; - } -} - - -.brass { - color: #BE8700; -} - -.big_brass { - color: #BE8700; - font-size: 3; - font-weight: bold; - font-style: italic; -} - -.clockyellow { - color: #DAAA18; - font-weight: bold; - font-style: italic; -} - -.clockgray { - color: #42474D; - font-weight: bold; - font-style: italic; -} - -.clockred { - color: #6E001A; - font-weight: bold; - font-style: italic; -} - -.brown { - color: #3d2009; -} - -.orange { - color: #b8761a; -} - -.yellow { - color: #c7b72c; -} - -.cyan { - color: #0ea1e6; -} -// SKYRAT EDIT ADDITION END - -.phobia {color: #dd0000; font-weight: bold; animation: phobia 750ms infinite;} - @keyframes phobia { - 0% {color: #0d0d0d;} - 50% {color: #dd0000;} - 100% {color: #0d0d0d;} -} +.phobia {color: #dd0000; font-weight: bold;} .icon {height: 1em; width: auto;} @@ -267,4 +155,6 @@ h1.alert, h2.alert {color: #000000;} .policy {color: #9730db; font-style: italic; text-align: center; font-size: 2;} .upside_down {display: inline; -moz-transform: scale(-1, -1); -webkit-transform: scale(-1, -1); -o-transform: scale(-1, -1); -ms-transform: scale(-1, -1); transform: scale(-1, -1);} + +.cyan {color: #bde0dc;} "} diff --git a/sound/attributions.txt b/sound/attributions.txt index ade4c8fe7e7..3e315731646 100644 --- a/sound/attributions.txt +++ b/sound/attributions.txt @@ -246,5 +246,7 @@ sound/effect/droplet.ogg -- "Drop - Water" By mattfinarelli -- https://freesound sound/effects/swapper/swap_A.ogg and swap_B.ogg by ArcaneMusic, License: Creative Commons 0, man-made mouth noises, slight cleanup in audacity. +sound/items/weapons/earthcracker_bang.mp3 by Jean Filho -- https://freesound.org/people/Jean_Filho/sounds/807381/ -- License: Creative Commons 0 + sound/machines/data_transmission.ogg -- Elements from Tim Verberne -- https://freesound.org/people/Tim_Verberne/sounds/558942/ -- License: Creative Commons 0 and samples from Ping.ogg from throughout the codebase. diff --git a/sound/items/weapons/earthcracker_bang.mp3 b/sound/items/weapons/earthcracker_bang.mp3 new file mode 100644 index 00000000000..7baaf2ac0ba Binary files /dev/null and b/sound/items/weapons/earthcracker_bang.mp3 differ diff --git a/sound/items/weapons/rust_sower_armbomb.ogg b/sound/items/weapons/rust_sower_armbomb.ogg index 0cc796ba2a8..c8ab60df71c 100644 Binary files a/sound/items/weapons/rust_sower_armbomb.ogg and b/sound/items/weapons/rust_sower_armbomb.ogg differ diff --git a/sound/items/weapons/rust_sower_explode.ogg b/sound/items/weapons/rust_sower_explode.ogg index 52b1cd8ec4c..7888cb0cefa 100644 Binary files a/sound/items/weapons/rust_sower_explode.ogg and b/sound/items/weapons/rust_sower_explode.ogg differ diff --git a/sound/machines/fire_alarm/FireAlarm1.ogg b/sound/machines/fire_alarm/FireAlarm1.ogg deleted file mode 100644 index 7ffecac8d88..00000000000 Binary files a/sound/machines/fire_alarm/FireAlarm1.ogg and /dev/null differ diff --git a/sound/machines/fire_alarm/FireAlarm2.ogg b/sound/machines/fire_alarm/FireAlarm2.ogg deleted file mode 100644 index 387bc64996c..00000000000 Binary files a/sound/machines/fire_alarm/FireAlarm2.ogg and /dev/null differ diff --git a/sound/machines/fire_alarm/FireAlarm3.ogg b/sound/machines/fire_alarm/FireAlarm3.ogg deleted file mode 100644 index caefb92a9c5..00000000000 Binary files a/sound/machines/fire_alarm/FireAlarm3.ogg and /dev/null differ diff --git a/sound/machines/fire_alarm/FireAlarm4.ogg b/sound/machines/fire_alarm/FireAlarm4.ogg deleted file mode 100644 index 3ee36928002..00000000000 Binary files a/sound/machines/fire_alarm/FireAlarm4.ogg and /dev/null differ diff --git a/sound/machines/fire_alarm/fire_alarm1.ogg b/sound/machines/fire_alarm/fire_alarm1.ogg new file mode 100644 index 00000000000..e33bdaa66be Binary files /dev/null and b/sound/machines/fire_alarm/fire_alarm1.ogg differ diff --git a/sound/machines/fire_alarm/fire_alarm2.ogg b/sound/machines/fire_alarm/fire_alarm2.ogg new file mode 100644 index 00000000000..7900d6c9a06 Binary files /dev/null and b/sound/machines/fire_alarm/fire_alarm2.ogg differ diff --git a/sound/machines/fire_alarm/fire_alarm3.ogg b/sound/machines/fire_alarm/fire_alarm3.ogg new file mode 100644 index 00000000000..7c09d2137aa Binary files /dev/null and b/sound/machines/fire_alarm/fire_alarm3.ogg differ diff --git a/sound/machines/fire_alarm/fire_alarm4.ogg b/sound/machines/fire_alarm/fire_alarm4.ogg new file mode 100644 index 00000000000..56569e7b9d4 Binary files /dev/null and b/sound/machines/fire_alarm/fire_alarm4.ogg differ diff --git a/sound/mobs/non-humanoids/stargazer/beam_loop_one.ogg b/sound/mobs/non-humanoids/stargazer/beam_loop_one.ogg index 957fb4cd175..b5602ca73e9 100644 Binary files a/sound/mobs/non-humanoids/stargazer/beam_loop_one.ogg and b/sound/mobs/non-humanoids/stargazer/beam_loop_one.ogg differ diff --git a/sound/mobs/non-humanoids/stargazer/beam_loop_two.ogg b/sound/mobs/non-humanoids/stargazer/beam_loop_two.ogg index 5d6d0004491..d9847481490 100644 Binary files a/sound/mobs/non-humanoids/stargazer/beam_loop_two.ogg and b/sound/mobs/non-humanoids/stargazer/beam_loop_two.ogg differ diff --git a/sound/mobs/non-humanoids/stargazer/beam_open.ogg b/sound/mobs/non-humanoids/stargazer/beam_open.ogg index 1f99c32c61c..7e79ebcbfa1 100644 Binary files a/sound/mobs/non-humanoids/stargazer/beam_open.ogg and b/sound/mobs/non-humanoids/stargazer/beam_open.ogg differ diff --git a/strings/gizmo_words.txt b/strings/gizmo_words.txt new file mode 100644 index 00000000000..e90a089ad23 --- /dev/null +++ b/strings/gizmo_words.txt @@ -0,0 +1,59 @@ +ba +be +bo +bi +ca +ce +co +ci +da +de +do +di +fa +fe +fo +fi +ga +ge +go +gi +ha +he +ho +hi +ja +je +jo +ji +ka +ke +ko +ki +la +le +lo +li +ma +me +mo +mi +na +ne +no +pa +pe +po +pi +ra +re +ro +ri +sa +se +so +si +wa +we +wo +wi diff --git a/strings/tcg/set_one.json b/strings/tcg/set_one.json index 6b73ff7a7eb..555f4568e6c 100644 --- a/strings/tcg/set_one.json +++ b/strings/tcg/set_one.json @@ -997,7 +997,7 @@ "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": "Sacrifice this card: reduce the cost of summoning your next 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 plasma.", "icon_state": "runtime", "power": "0", "resolve": "1", @@ -1337,7 +1337,7 @@ "id": "just_losses", "name": "Justifiable Casualties", "desc": "The beat is hell. Officers die. The strongest, they live.", - "rules": "Sacrifice two friendly creatures from the battlefield, then summon a creature from your hand at no mana cost.", + "rules": "Sacrifice two friendly creatures from the battlefield, then summon a creature from your hand at no plasma cost.", "icon_state": "just_losses", "power": "0", "resolve": "0", @@ -1352,7 +1352,7 @@ "id": "blue_warp", "name": "Bluespace Flux", "desc": "Despite being a revolutionary new technology, bluespace still has some... kinks that need sorted out.", - "rules": "While this card is active, once a round during the play phase each player may pay 2 mana to summon the top card from their deck.", + "rules": "While this card is active, once a round during the play phase each player may pay 2 plasma to summon the top card from their deck.", "icon_state": "blue_warp", "power": "0", "resolve": "0", @@ -1382,7 +1382,7 @@ "id": "eco_crash", "name": "Economy Crash", "desc": "So cargo sold 20 canisters of miasma, and now the galactic economy is experiencing what's known as 'a catastrophic collapse'.", - "rules": "All cards cost 1 extra mana to summon.", + "rules": "All cards cost 1 extra plasma to summon.", "icon_state": "eco_crash", "power": "0", "resolve": "0", @@ -1397,7 +1397,7 @@ "id": "black_gaia", "name": "Black Ambrosia Gaia", "desc": "If Ambrosia Gaia is the gold of Botany, the rare black variety is the platinum. Almost nobody has seen this illusive plant with their own eyes.", - "rules": "During the draw phase, you may sacrifice Ambrosia Gaia to gain 3 mana.", + "rules": "During the draw phase, you may sacrifice Ambrosia Gaia to gain 3 plasma.", "icon_state": "black_gaia", "power": "0", "resolve": "0", @@ -1570,7 +1570,7 @@ "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 4 mana.", + "rules": "Flip a coin. If heads, gain 4 plasma.", "icon_state": "bepis", "power": "0", "resolve": "0", diff --git a/strings/tcg/set_two.json b/strings/tcg/set_two.json index e7fe4fd1b49..f4c699c3606 100644 --- a/strings/tcg/set_two.json +++ b/strings/tcg/set_two.json @@ -43,7 +43,7 @@ "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: Summon a Xeno faction creature for 1 less mana.", + "rules": "{$Hivemind}. Tap: Summon a Xeno faction creature for 1 less plasma.", "icon_state": "xeno_drone", "power": 1, "resolve": 1, diff --git a/strings/tips.txt b/strings/tips.txt index d832de900b3..45942b20776 100644 --- a/strings/tips.txt +++ b/strings/tips.txt @@ -297,6 +297,7 @@ When hacking doors, cutting and mending a "test light wire" will restore power t When in doubt about technical issues, clear your cache (byond launcher > cogwheel > preferences > game prefs), update your BYOND, and relog. When placing floor tiles in space, you don't need to place down lattice if there is a piece of plating nearby. Where the space map levels connect is randomized every round, but are otherwise kept consistent within rounds. Remember that they are not necessarily bidirectional! +While the floor changer buttons allow you to move through vertical open space, you can also right-click it to look through open space and even glass floors without having to move! Working out improves your fitness which increases your size and faster times to fireman carry. Remember that a quality diet and sleep are essential! You can alt-click tank transfer valves to remove a tank from them. You can automatically extract and retract arm implants by 'activating' the empty hand they're on. This includes integrated toolsets, cursed katanas, and vorpal scythes. diff --git a/tgstation.dme b/tgstation.dme index 3dfb22ee6b3..37ebff4dff1 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -97,6 +97,7 @@ #include "code\__DEFINES\dye_keys.dm" #include "code\__DEFINES\economy.dm" #include "code\__DEFINES\electrified_buckle.dm" +#include "code\__DEFINES\event_logger.dm" #include "code\__DEFINES\events.dm" #include "code\__DEFINES\exosuit_fab.dm" #include "code\__DEFINES\experisci.dm" @@ -113,6 +114,7 @@ #include "code\__DEFINES\fov.dm" #include "code\__DEFINES\generators.dm" #include "code\__DEFINES\ghost.dm" +#include "code\__DEFINES\gizmo.dm" #include "code\__DEFINES\gradient.dm" #include "code\__DEFINES\gravity.dm" #include "code\__DEFINES\guardian_defines.dm" @@ -227,6 +229,7 @@ #include "code\__DEFINES\si.dm" #include "code\__DEFINES\sight.dm" #include "code\__DEFINES\skills.dm" +#include "code\__DEFINES\skin.dm" #include "code\__DEFINES\song.dm" #include "code\__DEFINES\sort_types.dm" #include "code\__DEFINES\sound.dm" @@ -707,6 +710,7 @@ #include "code\_globalvars\configuration.dm" #include "code\_globalvars\game_modes.dm" #include "code\_globalvars\genetics.dm" +#include "code\_globalvars\layers.dm" #include "code\_globalvars\lighting.dm" #include "code\_globalvars\logging.dm" #include "code\_globalvars\phobias.dm" @@ -884,7 +888,6 @@ #include "code\controllers\subsystem\mobs.dm" #include "code\controllers\subsystem\moods.dm" #include "code\controllers\subsystem\mouse_entered.dm" -#include "code\controllers\subsystem\nightshift.dm" #include "code\controllers\subsystem\npcpool.dm" #include "code\controllers\subsystem\ore_generation.dm" #include "code\controllers\subsystem\overlays.dm" @@ -1047,7 +1050,6 @@ #include "code\datums\stock_market_events.dm" #include "code\datums\tgs_event_handler.dm" #include "code\datums\verb_callbacks.dm" -#include "code\datums\verbs.dm" #include "code\datums\view.dm" #include "code\datums\visual_data.dm" #include "code\datums\voice_of_god_command.dm" @@ -1125,6 +1127,7 @@ #include "code\datums\ai\basic_mobs\generic_controllers.dm" #include "code\datums\ai\basic_mobs\basic_ai_behaviors\basic_attacking.dm" #include "code\datums\ai\basic_mobs\basic_ai_behaviors\befriend_target.dm" +#include "code\datums\ai\basic_mobs\basic_ai_behaviors\clear_key.dm" #include "code\datums\ai\basic_mobs\basic_ai_behaviors\climb_tree.dm" #include "code\datums\ai\basic_mobs\basic_ai_behaviors\emote_with_target.dm" #include "code\datums\ai\basic_mobs\basic_ai_behaviors\find_parent.dm" @@ -1186,6 +1189,8 @@ #include "code\datums\ai\basic_mobs\pet_commands\pet_follow_friend.dm" #include "code\datums\ai\basic_mobs\pet_commands\pet_use_targeted_ability.dm" #include "code\datums\ai\basic_mobs\pet_commands\play_dead.dm" +#include "code\datums\ai\basic_mobs\target_priority_strategies\_target_priority_strategy.dm" +#include "code\datums\ai\basic_mobs\target_priority_strategies\mining_strategies.dm" #include "code\datums\ai\basic_mobs\targeting_strategies\_targeting_strategy.dm" #include "code\datums\ai\basic_mobs\targeting_strategies\basic_targeting_strategy.dm" #include "code\datums\ai\basic_mobs\targeting_strategies\dont_target_friends.dm" @@ -1280,6 +1285,7 @@ #include "code\datums\components\atom_mounted.dm" #include "code\datums\components\aura_healing.dm" #include "code\datums\components\bakeable.dm" +#include "code\datums\components\bane.dm" #include "code\datums\components\banned_from_space.dm" #include "code\datums\components\basic_inhands.dm" #include "code\datums\components\basic_mob_attack_telegraph.dm" @@ -1335,6 +1341,7 @@ #include "code\datums\components\defaceable.dm" #include "code\datums\components\dejavu.dm" #include "code\datums\components\deployable.dm" +#include "code\datums\components\digitigrade_linb.dm" #include "code\datums\components\direct_explosive_trap.dm" #include "code\datums\components\earprotection.dm" #include "code\datums\components\echolocation.dm" @@ -1378,6 +1385,7 @@ #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\hitsplat.dm" #include "code\datums\components\holderloving.dm" #include "code\datums\components\holographic_nature.dm" #include "code\datums\components\houlihan_teleport.dm" @@ -1455,6 +1463,7 @@ #include "code\datums\components\religious_tool.dm" #include "code\datums\components\rename.dm" #include "code\datums\components\reskinnable_atom.dm" +#include "code\datums\components\revenant_prison.dm" #include "code\datums\components\revenge_ability.dm" #include "code\datums\components\rot.dm" #include "code\datums\components\scope.dm" @@ -1584,6 +1593,7 @@ #include "code\datums\components\pet_commands\pet_commands_basic.dm" #include "code\datums\components\plumbing\_plumbing.dm" #include "code\datums\components\plumbing\automated_iv.dm" +#include "code\datums\components\plumbing\boulder_reactions.dm" #include "code\datums\components\plumbing\buffer.dm" #include "code\datums\components\plumbing\chemical_acclimator.dm" #include "code\datums\components\plumbing\ductnet.dm" @@ -1626,6 +1636,7 @@ #include "code\datums\diseases\rhumba_beat.dm" #include "code\datums\diseases\transformation.dm" #include "code\datums\diseases\tuberculosis.dm" +#include "code\datums\diseases\verminous_plague.dm" #include "code\datums\diseases\weightlessness.dm" #include "code\datums\diseases\wizarditis.dm" #include "code\datums\diseases\advance\advance.dm" @@ -1686,7 +1697,6 @@ #include "code\datums\elements\attack_equip.dm" #include "code\datums\elements\attack_zone_randomiser.dm" #include "code\datums\elements\backblast.dm" -#include "code\datums\elements\bane.dm" #include "code\datums\elements\basic_allergenic_attack.dm" #include "code\datums\elements\basic_eating.dm" #include "code\datums\elements\basic_health_examine.dm" @@ -1694,6 +1704,7 @@ #include "code\datums\elements\beauty.dm" #include "code\datums\elements\bed_tucking.dm" #include "code\datums\elements\befriend_petting.dm" +#include "code\datums\elements\block_area_power_fail.dm" #include "code\datums\elements\block_turf_fingerprints.dm" #include "code\datums\elements\blocks_explosives.dm" #include "code\datums\elements\blood_limb_overlay.dm" @@ -1794,6 +1805,7 @@ #include "code\datums\elements\move_force_on_death.dm" #include "code\datums\elements\movement_turf_changer.dm" #include "code\datums\elements\movetype_handler.dm" +#include "code\datums\elements\moving_randomly.dm" #include "code\datums\elements\muffles_speech.dm" #include "code\datums\elements\nav_computer_icon.dm" #include "code\datums\elements\nerfed_pulling.dm" @@ -1956,8 +1968,11 @@ #include "code\datums\mapgen\CaveGenerator.dm" #include "code\datums\mapgen\JungleGenerator.dm" #include "code\datums\mapgen\biomes\_biome.dm" +#include "code\datums\mapgen\biomes\jungle.dm" +#include "code\datums\mapgen\biomes\lavaland.dm" #include "code\datums\mapgen\Cavegens\IcemoonCaves.dm" #include "code\datums\mapgen\Cavegens\LavalandGenerator.dm" +#include "code\datums\martial\_action.dm" #include "code\datums\martial\_martial.dm" #include "code\datums\martial\boxing.dm" #include "code\datums\martial\cqc.dm" @@ -2088,6 +2103,7 @@ #include "code\datums\quirks\negative_quirks\indebted.dm" #include "code\datums\quirks\negative_quirks\insanity.dm" #include "code\datums\quirks\negative_quirks\light_drinker.dm" +#include "code\datums\quirks\negative_quirks\limper.dm" #include "code\datums\quirks\negative_quirks\monophobia.dm" #include "code\datums\quirks\negative_quirks\mute.dm" #include "code\datums\quirks\negative_quirks\narcolepsy.dm" @@ -2461,9 +2477,9 @@ #include "code\game\machinery\big_manipulator\_defines.dm" #include "code\game\machinery\big_manipulator\big_manipulator.dm" #include "code\game\machinery\big_manipulator\big_manipulator_interactions.dm" -#include "code\game\machinery\big_manipulator\interaction_points.dm" #include "code\game\machinery\big_manipulator\interaction_priorities.dm" #include "code\game\machinery\big_manipulator\manipulator_arm.dm" +#include "code\game\machinery\big_manipulator\manipulator_tasks.dm" #include "code\game\machinery\big_manipulator\tasking.dm" #include "code\game\machinery\camera\camera.dm" #include "code\game\machinery\camera\camera_construction.dm" @@ -2546,6 +2562,7 @@ #include "code\game\machinery\dna_infuser\organ_sets\gondola_organs.dm" #include "code\game\machinery\dna_infuser\organ_sets\rat_organs.dm" #include "code\game\machinery\dna_infuser\organ_sets\roach_organs.dm" +#include "code\game\machinery\dna_infuser\organ_sets\stoat_organs.dm" #include "code\game\machinery\doors\airlock.dm" #include "code\game\machinery\doors\airlock_electronics.dm" #include "code\game\machinery\doors\brigdoors.dm" @@ -2645,6 +2662,7 @@ #include "code\game\objects\effects\decals\cleanable\fuel.dm" #include "code\game\objects\effects\decals\cleanable\mess.dm" #include "code\game\objects\effects\decals\cleanable\robots.dm" +#include "code\game\objects\effects\decals\cleanable\toxic.dm" #include "code\game\objects\effects\decals\turfdecal\dirt.dm" #include "code\game\objects\effects\decals\turfdecal\markings.dm" #include "code\game\objects\effects\decals\turfdecal\tilecoloring.dm" @@ -2819,6 +2837,7 @@ #include "code\game\objects\items\devices\chameleonproj.dm" #include "code\game\objects\items\devices\destabilizing_crystal.dm" #include "code\game\objects\items\devices\desynchronizer.dm" +#include "code\game\objects\items\devices\earthcracker.dm" #include "code\game\objects\items\devices\electroadaptive_pseudocircuit.dm" #include "code\game\objects\items\devices\flashlight.dm" #include "code\game\objects\items\devices\forcefieldprojector.dm" @@ -3218,10 +3237,11 @@ #include "code\game\objects\structures\icemoon\cave_entrance.dm" #include "code\game\objects\structures\lavaland\geyser.dm" #include "code\game\objects\structures\lavaland\gulag_vent.dm" -#include "code\game\objects\structures\lavaland\necropolis_tendril.dm" #include "code\game\objects\structures\lavaland\ore_vent.dm" #include "code\game\objects\structures\plaques\_plaques.dm" #include "code\game\objects\structures\plaques\static_plaques.dm" +#include "code\game\objects\structures\signboards\_signboard.dm" +#include "code\game\objects\structures\signboards\holosign.dm" #include "code\game\objects\structures\signs\_signs.dm" #include "code\game\objects\structures\signs\sign_eyechart.dm" #include "code\game\objects\structures\signs\signs_departments.dm" @@ -3305,6 +3325,7 @@ #include "code\modules\admin\chat_commands.dm" #include "code\modules\admin\check_antagonists.dm" #include "code\modules\admin\create_mob.dm" +#include "code\modules\admin\event_logger.dm" #include "code\modules\admin\force_event.dm" #include "code\modules\admin\fun_balloon.dm" #include "code\modules\admin\greyscale_modify_menu.dm" @@ -3347,6 +3368,7 @@ #include "code\modules\admin\smites\fireball.dm" #include "code\modules\admin\smites\ghost_control.dm" #include "code\modules\admin\smites\gib.dm" +#include "code\modules\admin\smites\hitsplat.dm" #include "code\modules\admin\smites\imaginary_friend_special.dm" #include "code\modules\admin\smites\immerse.dm" #include "code\modules\admin\smites\knot_shoes.dm" @@ -3426,6 +3448,7 @@ #include "code\modules\admin\verbs\spawnobjasmob.dm" #include "code\modules\admin\verbs\special_verbs.dm" #include "code\modules\admin\verbs\sprite_auditor.dm" +#include "code\modules\admin\verbs\appearance_debugger\appearance_debugger.dm" #include "code\modules\admin\verbs\lua\_hooks.dm" #include "code\modules\admin\verbs\lua\_wrappers.dm" #include "code\modules\admin\verbs\lua\helpers.dm" @@ -3693,6 +3716,7 @@ #include "code\modules\antagonists\heretic\magic\wolves_among_sheep.dm" #include "code\modules\antagonists\heretic\status_effects\buffs.dm" #include "code\modules\antagonists\heretic\status_effects\debuffs.dm" +#include "code\modules\antagonists\heretic\status_effects\dreams.dm" #include "code\modules\antagonists\heretic\status_effects\ghoul.dm" #include "code\modules\antagonists\heretic\status_effects\heretic_passive.dm" #include "code\modules\antagonists\heretic\status_effects\mark_effects.dm" @@ -4000,6 +4024,7 @@ #include "code\modules\awaymissions\mission_code\heretic\heretic_gateway_misc.dm" #include "code\modules\awaymissions\mission_code\heretic\heretic_gateway_spawners.dm" #include "code\modules\awaymissions\mission_code\heretic\heretic_gateway_tram.dm" +#include "code\modules\awaymissions\mission_code\heretic\naval_cannon.dm" #include "code\modules\awaymissions\mission_code\heretic\zlevel.dm" #include "code\modules\balloon_alert\balloon_alert.dm" #include "code\modules\basketball\basketball.dm" @@ -4023,7 +4048,6 @@ #include "code\modules\bitrunning\antagonists\netguardian.dm" #include "code\modules\bitrunning\components\avatar_connection.dm" #include "code\modules\bitrunning\components\avatar_gear.dm" -#include "code\modules\bitrunning\components\bitrunning_points.dm" #include "code\modules\bitrunning\components\glitch.dm" #include "code\modules\bitrunning\components\netpod_healing.dm" #include "code\modules\bitrunning\components\npc_friendly.dm" @@ -4271,6 +4295,7 @@ #include "code\modules\client\preferences\statpanel.dm" #include "code\modules\client\preferences\status_bar.dm" #include "code\modules\client\preferences\tgui.dm" +#include "code\modules\client\preferences\time.dm" #include "code\modules\client\preferences\tooltips.dm" #include "code\modules\client\preferences\trans_prosthetic.dm" #include "code\modules\client\preferences\ui_style.dm" @@ -4309,7 +4334,7 @@ #include "code\modules\client\preferences\species_features\pod.dm" #include "code\modules\client\preferences\species_features\vampire.dm" #include "code\modules\client\verbs\ooc.dm" -#include "code\modules\client\verbs\ping.dm" +#include "code\modules\client\verbs\stat_panel.dm" #include "code\modules\client\verbs\suicide.dm" #include "code\modules\client\verbs\typing.dm" #include "code\modules\client\verbs\who.dm" @@ -4497,6 +4522,7 @@ #include "code\modules\emote_panel\emote_panel.dm" #include "code\modules\error_handler\error_handler.dm" #include "code\modules\error_handler\error_viewer.dm" +#include "code\modules\escape_menu\admin_page.dm" #include "code\modules\escape_menu\details.dm" #include "code\modules\escape_menu\dimmer.dm" #include "code\modules\escape_menu\escape_menu.dm" @@ -4533,6 +4559,7 @@ #include "code\modules\events\market_crash.dm" #include "code\modules\events\mass_hallucination.dm" #include "code\modules\events\mice_migration.dm" +#include "code\modules\events\nightshift.dm" #include "code\modules\events\portal_storm.dm" #include "code\modules\events\processor_overload.dm" #include "code\modules\events\radiation_leak.dm" @@ -5105,6 +5132,7 @@ #include "code\modules\mapfluff\centcom\nuke_ops.dm" #include "code\modules\mapfluff\ruins\generic.dm" #include "code\modules\mapfluff\ruins\lavaland_ruin_code.dm" +#include "code\modules\mapfluff\ruins\shoe_factory.dm" #include "code\modules\mapfluff\ruins\icemoonruin_code\commsagent.dm" #include "code\modules\mapfluff\ruins\icemoonruin_code\cursed_spring.dm" #include "code\modules\mapfluff\ruins\icemoonruin_code\lavaland_incursion.dm" @@ -5339,6 +5367,11 @@ #include "code\modules\mob\living\basic\bots\cleanbot\cleanbot.dm" #include "code\modules\mob\living\basic\bots\cleanbot\cleanbot_abilities.dm" #include "code\modules\mob\living\basic\bots\cleanbot\cleanbot_ai.dm" +#include "code\modules\mob\living\basic\bots\ed209\ed209.dm" +#include "code\modules\mob\living\basic\bots\ed209\ed209_ability.dm" +#include "code\modules\mob\living\basic\bots\ed209\ed209_ai.dm" +#include "code\modules\mob\living\basic\bots\ed209\ed209_nukie_ai.dm" +#include "code\modules\mob\living\basic\bots\ed209\ed209_nukie_spawner.dm" #include "code\modules\mob\living\basic\bots\firebot\firebot.dm" #include "code\modules\mob\living\basic\bots\firebot\firebot_ai.dm" #include "code\modules\mob\living\basic\bots\honkbots\honkbot.dm" @@ -5351,6 +5384,12 @@ #include "code\modules\mob\living\basic\bots\repairbot\repairbot.dm" #include "code\modules\mob\living\basic\bots\repairbot\repairbot_abilities.dm" #include "code\modules\mob\living\basic\bots\repairbot\repairbot_ai.dm" +#include "code\modules\mob\living\basic\bots\secbot\secbot.dm" +#include "code\modules\mob\living\basic\bots\secbot\secbot_abilities.dm" +#include "code\modules\mob\living\basic\bots\secbot\secbot_ai.dm" +#include "code\modules\mob\living\basic\bots\secbot\secbot_subtypes.dm" +#include "code\modules\mob\living\basic\bots\secbot\super_beepsky.dm" +#include "code\modules\mob\living\basic\bots\secbot\super_beepsky_ai.dm" #include "code\modules\mob\living\basic\bots\vibebot\vibebot.dm" #include "code\modules\mob\living\basic\bots\vibebot\vibebot_abilities.dm" #include "code\modules\mob\living\basic\bots\vibebot\vibebot_ai.dm" @@ -5495,6 +5534,9 @@ #include "code\modules\mob\living\basic\lavaland\raptor\raptor_egg.dm" #include "code\modules\mob\living\basic\lavaland\raptor\raptor_food_trough.dm" #include "code\modules\mob\living\basic\lavaland\raptor\raptor_inheritance.dm" +#include "code\modules\mob\living\basic\lavaland\tendril\tendril.dm" +#include "code\modules\mob\living\basic\lavaland\tendril\tendril_actions.dm" +#include "code\modules\mob\living\basic\lavaland\tendril\tendril_ai.dm" #include "code\modules\mob\living\basic\lavaland\watcher\watcher.dm" #include "code\modules\mob\living\basic\lavaland\watcher\watcher_ai.dm" #include "code\modules\mob\living\basic\lavaland\watcher\watcher_gaze.dm" @@ -5827,10 +5869,7 @@ #include "code\modules\mob\living\simple_animal\bot\bot.dm" #include "code\modules\mob\living\simple_animal\bot\bot_announcement.dm" #include "code\modules\mob\living\simple_animal\bot\construction.dm" -#include "code\modules\mob\living\simple_animal\bot\ed209bot.dm" #include "code\modules\mob\living\simple_animal\bot\mulebot.dm" -#include "code\modules\mob\living\simple_animal\bot\secbot.dm" -#include "code\modules\mob\living\simple_animal\bot\SuperBeepsky.dm" #include "code\modules\mob\living\simple_animal\hostile\hostile.dm" #include "code\modules\mob\living\simple_animal\hostile\ooze.dm" #include "code\modules\mob\living\simple_animal\hostile\megafauna\_megafauna.dm" @@ -6188,6 +6227,22 @@ #include "code\modules\projectiles\guns\magic\arcane_barrage.dm" #include "code\modules\projectiles\guns\magic\staff.dm" #include "code\modules\projectiles\guns\magic\wand.dm" +#include "code\modules\projectiles\guns\magic\wands\wand_animate.dm" +#include "code\modules\projectiles\guns\magic\wands\wand_babel.dm" +#include "code\modules\projectiles\guns\magic\wands\wand_bald.dm" +#include "code\modules\projectiles\guns\magic\wands\wand_booze.dm" +#include "code\modules\projectiles\guns\magic\wands\wand_freeze.dm" +#include "code\modules\projectiles\guns\magic\wands\wand_hallucination.dm" +#include "code\modules\projectiles\guns\magic\wands\wand_levitate.dm" +#include "code\modules\projectiles\guns\magic\wands\wand_pax.dm" +#include "code\modules\projectiles\guns\magic\wands\wand_pizza.dm" +#include "code\modules\projectiles\guns\magic\wands\wand_plague.dm" +#include "code\modules\projectiles\guns\magic\wands\wand_prank.dm" +#include "code\modules\projectiles\guns\magic\wands\wand_rebel.dm" +#include "code\modules\projectiles\guns\magic\wands\wand_repulse.dm" +#include "code\modules\projectiles\guns\magic\wands\wand_swap.dm" +#include "code\modules\projectiles\guns\magic\wands\wand_tentacle.dm" +#include "code\modules\projectiles\guns\magic\wands\wand_zap.dm" #include "code\modules\projectiles\guns\special\blastcannon.dm" #include "code\modules\projectiles\guns\special\chem_gun.dm" #include "code\modules\projectiles\guns\special\grenade_launcher.dm" @@ -6341,6 +6396,12 @@ #include "code\modules\religion\rites.dm" #include "code\modules\religion\burdened\burdened_trauma.dm" #include "code\modules\religion\burdened\psyker.dm" +#include "code\modules\religion\dreams\banish_nightmare.dm" +#include "code\modules\religion\dreams\deaconize_dreamer.dm" +#include "code\modules\religion\dreams\dream_portent.dm" +#include "code\modules\religion\dreams\dream_projection.dm" +#include "code\modules\religion\dreams\dream_protection.dm" +#include "code\modules\religion\dreams\slumber_party.dm" #include "code\modules\religion\festival\festival_violin.dm" #include "code\modules\religion\festival\instrument_rites.dm" #include "code\modules\religion\honorbound\honorbound_rites.dm" @@ -6396,6 +6457,23 @@ #include "code\modules\research\experimentor\experimentor.dm" #include "code\modules\research\experimentor\experiments.dm" #include "code\modules\research\experimentor\wires.dm" +#include "code\modules\research\gizmo\gizmo_controller.dm" +#include "code\modules\research\gizmo\gizmo_interface.dm" +#include "code\modules\research\gizmo\gizmo_items.dm" +#include "code\modules\research\gizmo\gizmo_machines.dm" +#include "code\modules\research\gizmo\gizmo_spawner.dm" +#include "code\modules\research\gizmo\gizmo_voice.dm" +#include "code\modules\research\gizmo\gizmo_wires.dm" +#include "code\modules\research\gizmo\gizpuzzle.dm" +#include "code\modules\research\gizmo\gizmodes\giz_filler.dm" +#include "code\modules\research\gizmo\gizmodes\gizactives.dm" +#include "code\modules\research\gizmo\gizmodes\gizbad.dm" +#include "code\modules\research\gizmo\gizmodes\gizcopier.dm" +#include "code\modules\research\gizmo\gizmodes\gizlectric.dm" +#include "code\modules\research\gizmo\gizmodes\gizmisc.dm" +#include "code\modules\research\gizmo\gizmodes\gizmood.dm" +#include "code\modules\research\gizmo\gizmodes\gizmopper.dm" +#include "code\modules\research\gizmo\gizmodes\gizporter.dm" #include "code\modules\research\machinery\_production.dm" #include "code\modules\research\machinery\circuit_imprinter.dm" #include "code\modules\research\machinery\departmental_circuit_imprinter.dm" @@ -6565,6 +6643,7 @@ #include "code\modules\spells\spell_types\self\charge.dm" #include "code\modules\spells\spell_types\self\disable_tech.dm" #include "code\modules\spells\spell_types\self\forcewall.dm" +#include "code\modules\spells\spell_types\self\ghostliness.dm" #include "code\modules\spells\spell_types\self\lichdom.dm" #include "code\modules\spells\spell_types\self\mime_vow.dm" #include "code\modules\spells\spell_types\self\mutate.dm" @@ -6973,6 +7052,9 @@ #include "code\modules\wiremod\components\table\get_column.dm" #include "code\modules\wiremod\components\table\index_table.dm" #include "code\modules\wiremod\components\table\select.dm" +#include "code\modules\wiremod\components\usb\emitter.dm" +#include "code\modules\wiremod\components\usb\temperature_pump.dm" +#include "code\modules\wiremod\components\usb\thermomachine.dm" #include "code\modules\wiremod\components\utility\clock.dm" #include "code\modules\wiremod\components\utility\delay.dm" #include "code\modules\wiremod\components\utility\nfc_receive.dm" @@ -7040,7 +7122,6 @@ #include "code\modules\zombie\items.dm" #include "code\modules\zombie\organs.dm" #include "interface\interface.dm" -#include "interface\menu.dm" #include "interface\stylesheet.dm" #include "interface\skin.dmf" #include "interface\fonts\fonts_datum.dm" diff --git a/tgui/bun.lock b/tgui/bun.lock index 6dd4971b730..4e2a142f45b 100644 --- a/tgui/bun.lock +++ b/tgui/bun.lock @@ -54,7 +54,7 @@ "react": "^19.1.0", "react-dom": "^19.1.0", "react-json-tree": "^0.20.0", - "tgui-core": "^5.6.0", + "tgui-core": "^5.10.0", "tgui-dev-server": "workspace:*", }, }, @@ -78,7 +78,7 @@ "react": "^19.1.0", "react-dom": "^19.1.0", "tgui": "workspace:*", - "tgui-core": "^5.6.0", + "tgui-core": "^5.10.0", "tgui-dev-server": "workspace:*", "zod": "^4.2.1", }, @@ -91,7 +91,7 @@ "react": "^19.1.0", "react-dom": "^19.1.0", "tgui": "workspace:*", - "tgui-core": "^5.6.0", + "tgui-core": "^5.10.0", }, }, "packages/tgui-setup": { @@ -1076,7 +1076,7 @@ "tgui": ["tgui@workspace:packages/tgui"], - "tgui-core": ["tgui-core@5.6.0", "", { "dependencies": { "@floating-ui/react": "^0.27.16", "@nozbe/microfuzz": "^1.0.0" }, "peerDependencies": { "react": "^19.1.0", "react-dom": "^19.1.0" } }, "sha512-F1ezppIr0sLLaQDljOsp5lpESSnCzpnlTy0tY2U5y868it7Q5FpXKlpUeYHsRgVINWUi2O2KEOHBB7izJgIPAg=="], + "tgui-core": ["tgui-core@5.10.0", "", { "dependencies": { "@floating-ui/react": "^0.27.16", "@nozbe/microfuzz": "^1.0.0" }, "peerDependencies": { "react": "^19.1.0", "react-dom": "^19.1.0" } }, "sha512-sbw2zSdJM55M333CHP2HALoEh3LBF07HNPDEXIwPDTGu0TKEaBMvkRnQlLN81A5s9cLjS4DCIvYTTE1qUQENeQ=="], "tgui-dev-server": ["tgui-dev-server@workspace:packages/tgui-dev-server"], diff --git a/tgui/happydom.ts b/tgui/happydom.ts index 18a7051a49e..e3799b44740 100644 --- a/tgui/happydom.ts +++ b/tgui/happydom.ts @@ -2,4 +2,4 @@ import { GlobalRegistrator } from '@happy-dom/global-registrator'; GlobalRegistrator.register(); -import 'packages/tgui/__mocks__/setup.ts'; +import 'tgui/__mocks__/setup.ts'; diff --git a/tgui/packages/tgfont/static/tgfont.css b/tgui/packages/tgfont/static/tgfont.css index 0943837a2d8..6bdf310a502 100644 --- a/tgui/packages/tgfont/static/tgfont.css +++ b/tgui/packages/tgfont/static/tgfont.css @@ -14,18 +14,20 @@ } :root { - --tg-air-tank-slash: "ea01"; - --tg-air-tank: "ea02"; - --tg-bad-touch: "ea03"; - --tg-image-minus: "ea04"; - --tg-image-plus: "ea05"; - --tg-nanotrasen-logo: "ea06"; - --tg-non-binary: "ea07"; - --tg-prosthetic-full: "ea08"; - --tg-prosthetic-leg: "ea09"; - --tg-sound-minus: "ea0a"; - --tg-sound-plus: "ea0b"; - --tg-syndicate-logo: "ea0c"; + /* biome-ignore-start lint/suspicious/noUselessEscapeInString: The escapes are needed */ + --tg-air-tank-slash: "\ea01"; + --tg-air-tank: "\ea02"; + --tg-bad-touch: "\ea03"; + --tg-image-minus: "\ea04"; + --tg-image-plus: "\ea05"; + --tg-nanotrasen-logo: "\ea06"; + --tg-non-binary: "\ea07"; + --tg-prosthetic-full: "\ea08"; + --tg-prosthetic-leg: "\ea09"; + --tg-sound-minus: "\ea0a"; + --tg-sound-plus: "\ea0b"; + --tg-syndicate-logo: "\ea0c"; + /* biome-ignore-end lint/suspicious/noUselessEscapeInString: The escapes are needed */ } .tg-air-tank-slash::before { content: var(--tg-air-tank-slash); diff --git a/tgui/packages/tgui-chat-dark/index.ts b/tgui/packages/tgui-chat-dark/index.ts new file mode 100644 index 00000000000..dd105da9774 --- /dev/null +++ b/tgui/packages/tgui-chat-dark/index.ts @@ -0,0 +1 @@ +import '../tgui-panel/styles/tgchat/chat-dark.scss'; diff --git a/tgui/packages/tgui-panel/chat/renderer.tsx b/tgui/packages/tgui-panel/chat/renderer.tsx index 9e2fb95384e..bee627b36eb 100644 --- a/tgui/packages/tgui-panel/chat/renderer.tsx +++ b/tgui/packages/tgui-panel/chat/renderer.tsx @@ -48,7 +48,7 @@ export const TGUI_CHAT_ATTRIBUTES_TO_PROPS = { function createHighlightNode(text, color) { const node = document.createElement('span'); node.className = 'Chat__highlight'; - node.setAttribute('style', `background-color:${color}`); + node.setAttribute('style', `--highlight-color:${color}`); node.textContent = text; return node; } @@ -449,6 +449,10 @@ class ChatRenderer { ); if (highlighted && parser.highlightWholeMessage) { node.className += ' ChatMessage--highlighted'; + node.style.setProperty( + '--highlight-color', + parser.highlightColor, + ); } }); } diff --git a/tgui/packages/tgui-panel/package.json b/tgui/packages/tgui-panel/package.json index 5bc09bb7351..abc47fdd73b 100644 --- a/tgui/packages/tgui-panel/package.json +++ b/tgui/packages/tgui-panel/package.json @@ -9,7 +9,7 @@ "react": "^19.1.0", "react-dom": "^19.1.0", "tgui": "workspace:*", - "tgui-core": "^5.6.0", + "tgui-core": "^5.10.0", "tgui-dev-server": "workspace:*", "zod": "^4.2.1" }, diff --git a/tgui/packages/tgui-panel/ping/helpers.ts b/tgui/packages/tgui-panel/ping/helpers.ts index ff22c82abb4..f30441bc2fd 100644 --- a/tgui/packages/tgui-panel/ping/helpers.ts +++ b/tgui/packages/tgui-panel/ping/helpers.ts @@ -46,6 +46,7 @@ export function pingSuccess(roundtrip: number): void { failCount: 0, networkQuality, }); + Byond.sendMessage('ping/set', { ping: roundtrip }); store.set(lastPingedAtAtom, Date.now()); } diff --git a/tgui/packages/tgui-panel/settings/constants.ts b/tgui/packages/tgui-panel/settings/constants.ts index 0e076fc07f6..2e5056f785e 100644 --- a/tgui/packages/tgui-panel/settings/constants.ts +++ b/tgui/packages/tgui-panel/settings/constants.ts @@ -12,12 +12,16 @@ export const COLORS = { BG_SECOND: '#151515', BUTTON: '#404040', TEXT: '#A6A6A6', + TEXT_IMPORTANT: '#A6A6A6', + BG_IMPORTANT: '#492020', }, LIGHT: { BG_BASE: '#EEEEEE', BG_SECOND: '#FFFFFF', BUTTON: '#FFFFFF', TEXT: '#000000', + TEXT_IMPORTANT: '#A6A6A6', + BG_IMPORTANT: '#910707', }, } as const; diff --git a/tgui/packages/tgui-panel/settings/scaling.ts b/tgui/packages/tgui-panel/settings/scaling.ts index bd1b5250012..784a253876f 100644 --- a/tgui/packages/tgui-panel/settings/scaling.ts +++ b/tgui/packages/tgui-panel/settings/scaling.ts @@ -1,16 +1,16 @@ // This is the elements from the skin.dmf that we need to adjust the fontsize of const ELEMENTS_TO_ADJUST = [ - 'infobuttons.changelog', - 'infobuttons.rules', - 'infobuttons.wiki', - 'infobuttons.forum', - 'infobuttons.github', - 'infobuttons.report-issue', + 'infobuttons.options', + 'infobuttons.hotkeys', + 'infobuttons.emotes', 'infobuttons.fullscreen-toggle', + 'infobuttons.reconnect', + 'infobuttons.chat', 'inputwindow.input', 'inputbuttons.saybutton', 'inputbuttons.mebutton', 'inputbuttons.oocbutton', + 'inputbuttons.whisperbutton', 'mapwindow.status_bar', ]; @@ -33,8 +33,8 @@ export async function setDisplayScaling() { const PANE_SPLITTERS = { info_button_child: 2, - input_buttons_child: 80, - output_input_child: 96, + input_buttons_child: 70, + info_split: 97.5, }; export function setEditPaneSplitters(editing: boolean) { diff --git a/tgui/packages/tgui-panel/settings/themes.ts b/tgui/packages/tgui-panel/settings/themes.ts index e94aaf7be3a..036962e72b6 100644 --- a/tgui/packages/tgui-panel/settings/themes.ts +++ b/tgui/packages/tgui-panel/settings/themes.ts @@ -46,20 +46,18 @@ export function setClientTheme(name): void | Promise { 'mainwindow.background-color': themeColor.BG_BASE, 'split.background-color': themeColor.BG_BASE, // Buttons - 'changelog.background-color': themeColor.BUTTON, - 'changelog.text-color': themeColor.TEXT, - 'rules.background-color': themeColor.BUTTON, - 'rules.text-color': themeColor.TEXT, - 'wiki.background-color': themeColor.BUTTON, - 'wiki.text-color': themeColor.TEXT, - 'forum.background-color': themeColor.BUTTON, - 'forum.text-color': themeColor.TEXT, - 'github.background-color': themeColor.BUTTON, - 'github.text-color': themeColor.TEXT, - 'report-issue.background-color': themeColor.BUTTON, - 'report-issue.text-color': themeColor.TEXT, + 'options.background-color': themeColor.BUTTON, + 'options.text-color': themeColor.TEXT, + 'hotkeys.background-color': themeColor.BUTTON, + 'hotkeys.text-color': themeColor.TEXT, + 'emotes.background-color': themeColor.BUTTON, + 'emotes.text-color': themeColor.TEXT, 'fullscreen-toggle.background-color': themeColor.BUTTON, 'fullscreen-toggle.text-color': themeColor.TEXT, + 'reconnect.background-color': themeColor.BG_IMPORTANT, + 'reconnect.text-color': themeColor.TEXT_IMPORTANT, + 'chat.background-color': themeColor.BUTTON, + 'chat.text-color': themeColor.TEXT, // Status and verb tabs 'output.background-color': themeColor.BG_BASE, 'output.text-color': themeColor.TEXT, @@ -68,6 +66,8 @@ export function setClientTheme(name): void | Promise { 'saybutton.text-color': themeColor.TEXT, 'oocbutton.background-color': themeColor.BG_BASE, 'oocbutton.text-color': themeColor.TEXT, + 'whisperbutton.background-color': themeColor.BG_BASE, + 'whisperbutton.text-color': themeColor.TEXT, 'mebutton.background-color': themeColor.BG_BASE, 'mebutton.text-color': themeColor.TEXT, 'asset_cache_browser.background-color': themeColor.BG_BASE, diff --git a/tgui/packages/tgui-panel/styles/components/Chat.scss b/tgui/packages/tgui-panel/styles/components/Chat.scss index 76bfb8a282a..f5a3e6c6139 100644 --- a/tgui/packages/tgui-panel/styles/components/Chat.scss +++ b/tgui/packages/tgui-panel/styles/components/Chat.scss @@ -61,34 +61,25 @@ } } -.Chat__highlight { - color: var(--color-black); -} - .Chat__highlight--restricted { color: hsl(0, 0%, 100%); background-color: hsl(0, 100%, 33.3%); font-weight: bold; } +.Chat__highlight { + color: var(--highlight-color); + background: oklch(from var(--highlight-color) l c h / 15%); + border-radius: 2px; + padding: 0 2px; +} + .ChatMessage { word-wrap: break-word; } .ChatMessage--highlighted { - position: relative; - border-left: math.div(1em, 6) solid hsl(50, 100%, 63.5%); + background: oklch(from var(--highlight-color) l c h / 8%); + border-left: 2px solid var(--highlight-color); padding-left: 0.5em; - - &:after { - content: ''; - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - background-color: hsla(50, 100%, 63.5%, 0.1); - // Make this click-through since this is an overlay - pointer-events: none; - } } diff --git a/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss b/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss index 911cbe697a9..6a923a3fd21 100644 --- a/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss +++ b/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss @@ -955,6 +955,11 @@ em { display: inline-block; } +.cyan { + color: #bde0dc; + text-shadow: 0 0 6px #bde0dc; +} + .connectionClosed, .fatalError { background: red; diff --git a/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss b/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss index 2975a07cb22..c1c875311a8 100644 --- a/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss +++ b/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss @@ -267,6 +267,16 @@ a:visited { background: yellow; } +.Chat__highlight { + color: oklch(from var(--highlight-color) min(l, 0.45) c h); + background: oklch(from var(--highlight-color) min(l, 0.45) c h / 25%); +} + +.ChatMessage--highlighted { + border-left-color: oklch(from var(--highlight-color) min(l, 0.45) c h); + background: oklch(from var(--highlight-color) min(l, 0.45) c h / 14%); +} + h1, h2, h3, @@ -959,6 +969,11 @@ h2.alert { display: inline-block; } +.cyan { + color: #95afac; + text-shadow: 0 0 6px #95afac; +} + .connectionClosed, .fatalError { background: red; diff --git a/tgui/packages/tgui-say/ChannelIterator.test.ts b/tgui/packages/tgui-say/ChannelIterator.test.ts index 746aca3cfa9..674dd60c241 100644 --- a/tgui/packages/tgui-say/ChannelIterator.test.ts +++ b/tgui/packages/tgui-say/ChannelIterator.test.ts @@ -20,6 +20,7 @@ describe('ChannelIterator', () => { // SKYRAT EDIT ADDITION END expect(channelIterator.next()).toBe('OOC'); + expect(channelIterator.next()).toBe('Pray'); expect(channelIterator.next()).toBe('Say'); // Admin is blacklisted so it should be skipped }); diff --git a/tgui/packages/tgui-say/ChannelIterator.ts b/tgui/packages/tgui-say/ChannelIterator.ts index 1dcdeb27498..1916e7f3123 100644 --- a/tgui/packages/tgui-say/ChannelIterator.ts +++ b/tgui/packages/tgui-say/ChannelIterator.ts @@ -1,13 +1,4 @@ -export type Channel = - | 'Say' - | 'Radio' - | 'Me' - // SKYRAT EDIT ADDITION START - | 'Whis' - | 'LOOC' - // SKYRAT EDIT ADDITION END - | 'OOC' - | 'Admin'; +export type Channel = 'Say' | 'Radio' | 'Me' | 'Whis' | 'LOOC' | 'OOC' | 'Admin' | 'Pray'; // BUBBER EDIT: ADD 'Whis' and 'LOOC', CHANGE: export type Channel = 'Say' | 'Radio' | 'Me' | 'OOC' | 'Admin' | 'Pray'; /** * ### ChannelIterator @@ -17,19 +8,10 @@ export type Channel = */ export class ChannelIterator { private index: number = 0; - private readonly channels: Channel[] = [ - 'Say', - 'Radio', - 'Me', - // SKYRAT EDIT ADDITION - 'Whis', - 'LOOC', - // SKYRAT EDIT ADDITION - 'OOC', - 'Admin', - ]; private readonly blacklist: Channel[] = ['Admin']; - private readonly quiet: Channel[] = ['OOC', 'LOOC', 'Admin']; // SKYRAT EDIT CHANGE (Add LOOC) + private readonly quiet: Channel[] = ['OOC', 'LOOC', 'Admin', 'Pray']; // SKYRAT EDIT CHANGE (Add LOOC) + private readonly channels: Channel[] = ['Say', 'Radio', 'Me', 'OOC', 'Admin', 'Pray', 'Whis', 'LOOC']; // BUBBER EDIT CHANGE (Add Whis and LOOC) + public next(): Channel { if (this.blacklist.includes(this.channels[this.index])) { diff --git a/tgui/packages/tgui-say/package.json b/tgui/packages/tgui-say/package.json index 45f81711e6d..b11aa26b1c8 100644 --- a/tgui/packages/tgui-say/package.json +++ b/tgui/packages/tgui-say/package.json @@ -6,7 +6,7 @@ "react": "^19.1.0", "react-dom": "^19.1.0", "tgui": "workspace:*", - "tgui-core": "^5.6.0" + "tgui-core": "^5.10.0" }, "private": true } diff --git a/tgui/packages/tgui-say/styles/colors.scss b/tgui/packages/tgui-say/styles/colors.scss index d7c6f8ac4f5..e6495f4f59b 100644 --- a/tgui/packages/tgui-say/styles/colors.scss +++ b/tgui/packages/tgui-say/styles/colors.scss @@ -20,6 +20,7 @@ $_channel_map: ( 'Med': hsl(202, 83.6%, 64.1%), 'OOC': hsl(47.9, 100%, 40%), 'Ent': hsl(176.1, 20%, 45.1%), + 'Pray': hsl(214, 86%, 30%), 'Radio': hsl(132.8, 74.4%, 45.9%), 'Say': hsl(213.6, 37.9%, 74.1%), 'Sci': hsl(271.6, 91.7%, 76.5%), diff --git a/tgui/packages/tgui/interfaces/AccountingConsole/AuditScreen.tsx b/tgui/packages/tgui/interfaces/AccountingConsole/AuditScreen.tsx index 98a19e308b1..2885340059f 100644 --- a/tgui/packages/tgui/interfaces/AccountingConsole/AuditScreen.tsx +++ b/tgui/packages/tgui/interfaces/AccountingConsole/AuditScreen.tsx @@ -41,7 +41,7 @@ export const AuditScreen = () => { {purchase.vendor} - {purchase.stationtime || '00:00'} ST + {purchase.stationtime || '00:00'} PT ))} diff --git a/tgui/packages/tgui/interfaces/AccountingConsole/index.tsx b/tgui/packages/tgui/interfaces/AccountingConsole/index.tsx index 3e45671520f..622abff07aa 100644 --- a/tgui/packages/tgui/interfaces/AccountingConsole/index.tsx +++ b/tgui/packages/tgui/interfaces/AccountingConsole/index.tsx @@ -150,7 +150,7 @@ export const AccountingConsole = () => { diff --git a/tgui/packages/tgui/interfaces/AppearanceDebug/AppearanceBox.tsx b/tgui/packages/tgui/interfaces/AppearanceDebug/AppearanceBox.tsx new file mode 100644 index 00000000000..3264c9df34e --- /dev/null +++ b/tgui/packages/tgui/interfaces/AppearanceDebug/AppearanceBox.tsx @@ -0,0 +1,134 @@ +import { Box, Button, Image, Stack, Tooltip } from 'tgui-core/components'; +import { classes } from 'tgui-core/react'; +import type { Coordinates } from '../common/Connections'; +import { + getReadableLayer, + getReadablePlane, + isEmissive, + isEmissiveBlocker, +} from '.'; +import { + APPEARANCE_FLAGS, + type Appearance, + AppearanceType, + HiddenState, +} from './types'; +import { useAppearanceDebugContext } from './useAppearanceDebug'; + +export type AppearanceProps = { + appearance: Appearance; + position: Coordinates; + onClick: React.MouseEventHandler; +}; + +export function AppearanceBox(props: AppearanceProps) { + const { appearance, position, onClick } = props; + const { planeToText, layerToText, act } = useAppearanceDebugContext(); + + return ( + <> + {!!( + appearance.data.flags & + (APPEARANCE_FLAGS.KEEP_APART | APPEARANCE_FLAGS.KEEP_TOGETHER) + ) && ( + + act('swapMapViewHover', { id: appearance.data.id }) + } + style={{ + zIndex: -(999 - appearance.depth), + border: `3px solid ${appearance.data.flags & APPEARANCE_FLAGS.KEEP_APART ? (appearance.data.flags & APPEARANCE_FLAGS.KEEP_TOGETHER ? '#2a7dc6' : '#107e2e') : '#e9cb0c'}`, + borderRadius: '5px', + padding: '5px', + backgroundColor: `${appearance.data.flags & APPEARANCE_FLAGS.KEEP_APART ? (appearance.data.flags & APPEARANCE_FLAGS.KEEP_TOGETHER ? '#223c54' : '#13381c') : '#544b15'}`, + }} + > + {!!(appearance.data.flags & APPEARANCE_FLAGS.KEEP_APART) && + 'KEEP_APART'} + {!!( + appearance.data.flags & APPEARANCE_FLAGS.KEEP_APART && + appearance.data.flags & APPEARANCE_FLAGS.KEEP_TOGETHER + ) && ' | '} + {!!(appearance.data.flags & APPEARANCE_FLAGS.KEEP_TOGETHER) && + 'KEEP_TOGETHER'} + + )} + act('swapMapViewHover', { id: appearance.data.id })} + onClick={onClick} + style={{ zIndex: 1 }} + opacity={appearance.hidden === HiddenState.VisibleChild ? 0.7 : 1} + > + + + + {appearance.data.name || appearance.data.icon_state} + {isEmissive(appearance) + ? ' (Emissive)' + : isEmissiveBlocker(appearance) + ? ' (Emissive Blocker)' + : ''} + + + - - - adjustPoint(editingPoint.id, 'reset_atom_filters') - } + onClick={() => adjust('reset_atom_filters')} confirmContent="Reset?" icon="trash" /> @@ -569,59 +335,242 @@ const PointSection = (props: { } > - {editingPoint.item_filters.map((name: string, index: number) => { - return ( - - -
    {name}
    -
    - - + + + } + > + + {tasks_data.map((task, index) => { + const isActive = current_task === task.id; + const taskTypeKey = Object.keys(TASK_TYPE_LABELS).find((k) => + task.task_type.includes(k), + ) ?? 'wait'; + + return ( + + + + - {setting.name} - - - - + + + + + {editingTask && ( + setEditingTask(null)} + /> )} ); @@ -629,162 +578,78 @@ const PointSection = (props: { export const BigManipulator = () => { const { data, act } = useBackend(); - const { current_task, current_task_duration, pickup_points, dropoff_points } = - data; - - const [progressValue, setProgressValue] = useState(0); - const [progressKey, setProgressKey] = useState(0); - - useEffect(() => { - const isTaskActive = current_task !== 'IDLE' && current_task !== 'NO TASK'; - - if (isTaskActive) { - setProgressValue(0); - setProgressKey((prev) => prev + 1); - - setTimeout(() => { - setProgressValue(100); - }, 10); - } else { - setProgressValue(0); - setProgressKey((prev) => prev + 1); - } - }, [current_task, current_task_duration]); + const { active, stopping } = data; return ( - + - act('run_cycle')} + > + {!active ? 'Run' : stopping ? 'Stopping' : 'Stop'} + + } > -
    act('run_cycle')} + +
    +
    + + + + + + - } - > - - - -
    - -
    - - - + +
    - - {/*
    - - - - -
    No storage detected.
    -
    -
    - - - - - - -
    -
    */} - - act('create_pickup_point')} - act={act} - /> - - act('create_dropoff_point')} - act={act} - /> -
    + Write + +
    + + act('disk_clear')} + >Clear + + +
    + + ); diff --git a/tgui/packages/tgui/interfaces/BigManipulator/types.ts b/tgui/packages/tgui/interfaces/BigManipulator/types.ts index bf74ecd94ff..e220a453ffe 100644 --- a/tgui/packages/tgui/interfaces/BigManipulator/types.ts +++ b/tgui/packages/tgui/interfaces/BigManipulator/types.ts @@ -2,47 +2,54 @@ import type { BooleanLike } from 'tgui-core/react'; export interface PrioritySettings { name: string; - priority_width: number; active: BooleanLike; } -export type InteractionPoint = { +export type TaskType = + | 'Pick up...' + | 'Drop...' + | 'Throw...' + | 'Use...' + | 'Interact with...' + | 'Wait for...'; + +export interface ManipulatorTask { name: string; id: string; - turf: string; - mode: string; - filters: string[]; - item_filters: string[]; - filters_status: BooleanLike; - filtering_mode: number; - overflow_status: string; - worker_use_rmb: BooleanLike; - worker_combat_mode: BooleanLike; - settings_list: PrioritySettings[]; - throw_range: number; - worker_interaction: string; - use_post_interaction: string; -}; + task_type: string; + // cargo fields + turf?: string; + item_filters?: string[]; + filters_status?: BooleanLike; + filtering_mode?: number; + settings_list?: PrioritySettings[]; + // pickup only + pickup_eagerness?: string; + // dropoff only + interaction_mode?: string; + overflow_status?: string; + throw_range?: number; + worker_interaction?: string; + use_post_interaction?: string; + worker_use_rmb?: BooleanLike; + worker_combat_mode?: BooleanLike; + // interact only + // (worker_interaction, use_post_interaction, worker_use_rmb, worker_combat_mode shared with dropoff) + time?: number; +} export interface ManipulatorData { active: BooleanLike; - current_task: string; - current_task_duration: number; - + stopping: BooleanLike; + current_task: string | null; speed_multiplier: number; min_speed_multiplier: number; max_speed_multiplier: number; - highest_priority: BooleanLike; - interaction_mode: string; - settings_list: PrioritySettings[]; - throw_range: number; - item_as_filter: string; - selected_type: string; - delay_step: number; - - pickup_points: InteractionPoint[]; - dropoff_points: InteractionPoint[]; + tasks_data: ManipulatorTask[]; manipulator_position: string; - pickup_tasking: string; - dropoff_tasking: string; + tasking_strategy: string; + has_monkey: BooleanLike; + disk_inserted: BooleanLike; + disk_read_only: BooleanLike; + disk_task_count: number; } diff --git a/tgui/packages/tgui/interfaces/CellularEmporium.tsx b/tgui/packages/tgui/interfaces/CellularEmporium.tsx index 03bef8b4f48..e2885618076 100644 --- a/tgui/packages/tgui/interfaces/CellularEmporium.tsx +++ b/tgui/packages/tgui/interfaces/CellularEmporium.tsx @@ -24,6 +24,7 @@ type TypePath = string; type Ability = { name: string; desc: string; + icon: string; helptext: string; path: TypePath; genetic_point_required: number; @@ -41,14 +42,6 @@ type CellularEmporiumContext = { dna_count: number; }; -// ========== -// Helper: convert ability name to icon_state -// Example: "Augmented Eyesight" → "augmented_eyesight" -// ========== -const nameToIconState = (name: string): string => { - return name.toLowerCase().replace(/\s+/g, '_'); -}; - // ========== // Main Component // ========== @@ -252,8 +245,6 @@ const ItemList = (props: ItemListProps) => { ? `Cost: ${ability.dna_required} DNA` : `Cost: ${ability.genetic_point_required} DNA`; - const iconState = nameToIconState(ability.name); - return (
    @@ -281,7 +272,7 @@ const ItemList = (props: ItemListProps) => { top="0" left="0" icon="icons/mob/actions/actions_changeling.dmi" - icon_state={iconState} + icon_state={ability.icon} width={iconSize} fallback={} /> diff --git a/tgui/packages/tgui/interfaces/EventLogger/CategoryBar.tsx b/tgui/packages/tgui/interfaces/EventLogger/CategoryBar.tsx new file mode 100644 index 00000000000..865825cbd61 --- /dev/null +++ b/tgui/packages/tgui/interfaces/EventLogger/CategoryBar.tsx @@ -0,0 +1,35 @@ +import { Box, Button, Stack } from 'tgui-core/components'; + +import type { Category } from './types'; + +export type CategoryBarProps = { + categories: Category[]; + colors: Record; + act: (action: string, params?: object) => void; +}; + +export function CategoryBar(props: CategoryBarProps) { + const { categories, colors, act } = props; + if (!categories.length) { + return ( + + No categories logged yet. + + ); + } + return ( + + {categories.map((cat) => ( + + + + ))} + + ); +} diff --git a/tgui/packages/tgui/interfaces/EventLogger/ControlBar.tsx b/tgui/packages/tgui/interfaces/EventLogger/ControlBar.tsx new file mode 100644 index 00000000000..5207993b308 --- /dev/null +++ b/tgui/packages/tgui/interfaces/EventLogger/ControlBar.tsx @@ -0,0 +1,63 @@ +import { Box, Button, Stack } from 'tgui-core/components'; + +export type ControlBarProps = { + running: boolean; + zoom: number; + awaitingPick: boolean; + autoScroll: boolean; + onAutoScrollChange: (val: boolean) => void; + act: (action: string, params?: object) => void; +}; + +export function ControlBar(props: ControlBarProps) { + const { running, zoom, awaitingPick, autoScroll, onAutoScrollChange, act } = + props; + return ( + + + + + + + + + + + + + + + + Zoom: {zoom < 1 ? zoom.toFixed(1) : zoom}x + + + + ); +} diff --git a/tgui/packages/tgui/interfaces/EventLogger/InfoPanel.tsx b/tgui/packages/tgui/interfaces/EventLogger/InfoPanel.tsx new file mode 100644 index 00000000000..d153d0ed218 --- /dev/null +++ b/tgui/packages/tgui/interfaces/EventLogger/InfoPanel.tsx @@ -0,0 +1,150 @@ +import { useState } from 'react'; +import { Box, Button, LabeledList, Section, Stack } from 'tgui-core/components'; +import { sanitizeText } from '../../sanitize'; +import type { Track, TrackInfoEntry } from './types'; +import { CATEGORY_PALETTE } from './types'; + +export type InfoPanelProps = { + tracks: Track[]; + selectedRef: string | null; + selectedEventIds: Set; +}; + +export function InfoPanel(props: InfoPanelProps) { + const { tracks, selectedRef, selectedEventIds } = props; + const track = selectedRef ? tracks.find((t) => t.ref === selectedRef) : null; + + const [disabledInfoCats, setDisabledInfoCats] = useState>( + new Set(), + ); + + // Resolve which track_info snapshot to display and whether it's event-specific + let snapshotEntries: TrackInfoEntry[] | null = null; + let snapshotTrack: Track | null = null; + let isLatest = false; + + if (selectedEventIds.size > 0) { + // Find the highest-id selected event that carries a snapshot + let bestId = -1; + for (const t of tracks) { + for (const evt of t.events) { + if ( + selectedEventIds.has(evt.id) && + evt.track_info?.length && + evt.id > bestId + ) { + bestId = evt.id; + snapshotEntries = evt.track_info; + snapshotTrack = t; + } + } + } + } + + if (!snapshotEntries && track) { + let latestId = -1; + for (const evt of track.events) { + if (evt.track_info?.length && evt.id > latestId) { + latestId = evt.id; + snapshotEntries = evt.track_info; + } + } + if (snapshotEntries) { + snapshotTrack = track; + isLatest = true; + } + } + + const infoCategoryOrder: string[] = []; + const infoCategoryColors: Record = {}; + if (snapshotEntries) { + for (const entry of snapshotEntries) { + const cat = entry.category || 'Info'; + if (!infoCategoryColors[cat]) { + infoCategoryColors[cat] = + CATEGORY_PALETTE[infoCategoryOrder.length % CATEGORY_PALETTE.length]; + infoCategoryOrder.push(cat); + } + } + } + + function toggleInfoCat(cat: string) { + setDisabledInfoCats((prev) => { + const next = new Set(prev); + if (next.has(cat)) next.delete(cat); + else next.add(cat); + return next; + }); + } + + function renderSnapshot(entries: TrackInfoEntry[]) { + const grouped: Record = {}; + for (const entry of entries) { + const cat = entry.category || 'Info'; + if (disabledInfoCats.has(cat)) continue; + if (!grouped[cat]) grouped[cat] = []; + grouped[cat].push(entry); + } + return Object.entries(grouped).map(([cat, items]) => ( +
    + + {items.map((item) => ( + + + + ))} + +
    + )); + } + + const displayName = snapshotTrack?.name ?? track?.name ?? 'Track Info'; + + return ( +
    + {!track && !snapshotEntries ? ( + + No track selected. Click a row in the timeline. + + ) : !snapshotEntries ? ( + + No snapshot available. Events on this track do not carry info + snapshots. + + ) : ( + <> + {infoCategoryOrder.length > 1 && ( + + {infoCategoryOrder.map((cat) => ( + + + + ))} + + )} + {renderSnapshot(snapshotEntries)} + + )} +
    + ); +} diff --git a/tgui/packages/tgui/interfaces/EventLogger/SelectedEventsPanel.tsx b/tgui/packages/tgui/interfaces/EventLogger/SelectedEventsPanel.tsx new file mode 100644 index 00000000000..9867daa7a66 --- /dev/null +++ b/tgui/packages/tgui/interfaces/EventLogger/SelectedEventsPanel.tsx @@ -0,0 +1,117 @@ +import { useEffect, useRef } from 'react'; +import { Box, Button, Section } from 'tgui-core/components'; +import { sanitizeText } from '../../sanitize'; +import type { EventEntry, Track } from './types'; +import { + getEventPrimaryCoord, + LOG_TYPE_COLORS, + LOG_TYPE_LABELS, +} from './types'; + +type LogTypeBadgeProps = { log_type: string }; + +export function LogTypeBadge(props: LogTypeBadgeProps) { + const { log_type } = props; + return ( + + {LOG_TYPE_LABELS[log_type] || log_type.toUpperCase()} + + ); +} + +export type SelectedEventsPanelProps = { + tracks: Track[]; + selectedEventIds: Set; + act: (action: string, params?: object) => void; +}; + +export function SelectedEventsPanel(props: SelectedEventsPanelProps) { + const { tracks, selectedEventIds, act } = props; + const scrollRef = useRef(null); + + const eventById: Record = {}; + for (const track of tracks) { + for (const evt of track.events) { + eventById[evt.id] = evt; + } + } + + const selected = [...selectedEventIds] + .sort((a, b) => a - b) + .map((id) => eventById[id]) + .filter(Boolean); + + useEffect(() => { + if (scrollRef.current) { + scrollRef.current.scrollTop = scrollRef.current.scrollHeight; + } + }, [selectedEventIds.size]); + + return ( +
    +
    + {!selected.length ? ( + + No events selected. Click marks in the timeline. Hold Ctrl to select + multiple. + + ) : ( + selected.map((evt) => { + const coord = getEventPrimaryCoord(evt); + return ( + + + {coord && ( +
    +
    + ); +} diff --git a/tgui/packages/tgui/interfaces/EventLogger/Timeline.tsx b/tgui/packages/tgui/interfaces/EventLogger/Timeline.tsx new file mode 100644 index 00000000000..a6ace61f59d --- /dev/null +++ b/tgui/packages/tgui/interfaces/EventLogger/Timeline.tsx @@ -0,0 +1,432 @@ +import type { ReactNode } from 'react'; +import { useEffect, useRef, useState } from 'react'; + +export type TimelineMark = { + rowId: string; + tick: number; + color: string; + isCircle: boolean; + isSelected: boolean; + isMulti: boolean; + count: number; + tooltip: string; + tooltipHtml?: string | null; + data: T; +}; + +export type TimelineRow = { + id: string; + renderLabel: () => ReactNode; +}; + +export type TimelineProps = { + rows: TimelineRow[]; + marks: TimelineMark[]; + timeStart: number | null; + timeCurrent: number; + zoom: number; + running: boolean; + autoScroll: boolean; + /** Ticks between interval ruler lines (default 50 = 5 s at 10 t/s). */ + intervalTicks?: number; + /** How many ticks are in one second (default 10 as byond is in deciseconds). */ + ticksPerSecond?: number; + onMarkClick: (mark: TimelineMark, ctrl: boolean) => void; + onEmptyClick: () => void; + onZoomChange: (next: number) => void; +}; + +// Constants + +const LABEL_WIDTH = 240; +const ROW_HEIGHT = 36; +const RULER_HEIGHT = 20; +const MARK_RADIUS = 7; +const ZOOM_MAX = 40; + +// Component + +export function Timeline(props: TimelineProps) { + const { + rows, + marks, + timeStart, + timeCurrent, + zoom, + running, + autoScroll, + intervalTicks = 50, + ticksPerSecond = 10, + onMarkClick, + onEmptyClick, + onZoomChange, + } = props; + + const scrollRef = useRef(null); + const outerRef = useRef(null); + const anchorRef = useRef<{ tick: number; px: number } | null>(null); + const [containerWidth, setContainerWidth] = useState(0); + const [hoverTooltip, setHoverTooltip] = useState<{ + x: number; + y: number; + html: string; + } | null>(null); + + // Track container width so we can compute fit-zoom + useEffect(() => { + const el = outerRef.current; + if (!el) return; + const ro = new ResizeObserver((entries) => { + setContainerWidth(entries[0].contentRect.width); + }); + ro.observe(el); + return () => ro.disconnect(); + }, []); + + // Derived timing + + const elapsed = timeStart !== null ? Math.max(0, timeCurrent - timeStart) : 0; + + const contentAreaWidth = Math.max(0, containerWidth - LABEL_WIDTH); + + /** + * The virtual duration used for layout. Always at least contentAreaWidth ticks, + * so at 1x zoom (1px/tick) the timeline always fills the full viewport. + * As real elapsed time exceeds this, fitZoom drops below 1 and you can zoom out. + */ + const effectiveElapsed = Math.max(elapsed, contentAreaWidth); + + /** + * The zoom level at which the full timeline exactly fills the content area. + * fitZoom == 1 until elapsed overflows the viewport, then shrinks below 1. + */ + const fitZoom = + effectiveElapsed > 0 && contentAreaWidth > 0 + ? contentAreaWidth / effectiveElapsed + : 1; + + // Whenever the stored zoom is below fitZoom, bring it back up (e.g. on open). + useEffect(() => { + if (zoom < fitZoom) { + onZoomChange(fitZoom); + } + }, [fitZoom]); // eslint-disable-line react-hooks/estive-deps + + /** px per tick at current zoom — never less than fitZoom */ + const pxPerTick = Math.max(fitZoom, zoom); + + // Ruler interval: auto-double when lines get too close + let rulerInterval = intervalTicks; + const minRulerSpacingPx = 60; + while (rulerInterval * pxPerTick < minRulerSpacingPx) { + rulerInterval *= 2; + } + + /** Total content width in px — uses effectiveElapsed so ruler/rows fill the viewport */ + const contentWidth = effectiveElapsed * pxPerTick + rulerInterval * pxPerTick; + + // Auto-scroll: only scroll if the playhead would be off-screen to the right + + useEffect(() => { + if (!autoScroll || !running || !scrollRef.current) return; + const container = scrollRef.current; + const playheadLeft = elapsed * pxPerTick; + const visibleRight = container.scrollLeft + container.clientWidth; + if (playheadLeft > visibleRight) { + container.scrollLeft = playheadLeft - container.clientWidth + 40; + } + }); + + // Zoom on wheel + + function handleWheel(e: React.WheelEvent) { + e.preventDefault(); + const container = scrollRef.current; + if (!container) return; + + // Save anchor: which tick is under the mouse + const rect = container.getBoundingClientRect(); + const localX = Math.max(0, e.clientX - rect.left); + const mouseX = localX + container.scrollLeft; + const tickUnderMouse = mouseX / pxPerTick; + anchorRef.current = { tick: tickUnderMouse, px: localX }; + + const delta = e.deltaY > 0 ? -1 : 1; + let next: number; + if (pxPerTick < 1) { + next = pxPerTick + delta * 0.1; + } else { + next = pxPerTick + delta * 1; + } + // Floor is fitZoom so you can never see empty space past the end + next = Math.max(fitZoom, Math.min(ZOOM_MAX, parseFloat(next.toFixed(1)))); + onZoomChange(next); + } + + // Re-anchor scroll after zoom change + useEffect(() => { + const anchor = anchorRef.current; + const container = scrollRef.current; + if (!anchor || !container) return; + anchorRef.current = null; + container.scrollLeft = anchor.tick * pxPerTick - anchor.px; + }, [pxPerTick]); + + // Render + + const contentHeight = rows.length * ROW_HEIGHT + RULER_HEIGHT; + + // Build a map from rowId -> row index for fast position lookup + const rowIndex: Record = {}; + rows.forEach((row, i) => { + rowIndex[row.id] = i; + }); + + // Ruler tick labels + + const rulerLabels: { tick: number; label: string; leftPx: number }[] = []; + for (let t = 0; t <= effectiveElapsed + rulerInterval; t += rulerInterval) { + const seconds = t / ticksPerSecond; + const leftPx = Math.max(0, t * pxPerTick); + rulerLabels.push({ tick: t, label: `${seconds}s`, leftPx }); + } + + // Render ruler vertical guide lines (behind rows) + + const rulerGuides = rulerLabels.map(({ tick, leftPx }) => ( +
    + )); + + // Render mark dots grouped by row + + const markEls = marks.map((mark, i) => { + const idx = rowIndex[mark.rowId]; + if (idx === undefined) return null; + const tickOffset = timeStart !== null ? mark.tick - timeStart : mark.tick; + const rawLeft = Math.max(0, tickOffset * pxPerTick); + const topPx = RULER_HEIGHT + idx * ROW_HEIGHT + ROW_HEIGHT / 2; + + const size = mark.isMulti ? MARK_RADIUS * 2 + 4 : MARK_RADIUS * 2; + + return ( +
    { + e.stopPropagation(); + onMarkClick(mark, e.ctrlKey || e.metaKey); + }} + onMouseEnter={(e) => { + if (mark.tooltipHtml) { + setHoverTooltip({ + x: e.clientX, + y: e.clientY, + html: mark.tooltipHtml, + }); + } + }} + onMouseMove={(e) => { + if (mark.tooltipHtml) { + setHoverTooltip({ + x: e.clientX, + y: e.clientY, + html: mark.tooltipHtml, + }); + } + }} + onMouseLeave={() => setHoverTooltip(null)} + style={{ + position: 'absolute', + left: `${rawLeft - size / 2}px`, + top: `${topPx - size / 2}px`, + width: `${size}px`, + height: `${size}px`, + borderRadius: mark.isCircle ? '50%' : '2px', + background: mark.color, + opacity: mark.isSelected ? 1 : 0.75, + border: mark.isSelected + ? '2px solid #fff' + : '1px solid rgba(0,0,0,0.4)', + cursor: 'pointer', + zIndex: mark.isSelected ? 2 : 1, + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + fontSize: '9px', + fontWeight: 'bold', + color: '#000', + userSelect: 'none', + }} + > + {mark.isMulti && mark.count > 1 ? mark.count : null} +
    + ); + }); + + return ( +
    + {/* Row labels column */} +
    + {/* Ruler header space */} +
    + {/* Row labels */} + {rows.map((row) => ( +
    + {row.renderLabel()} +
    + ))} +
    + + {/* Scrollable content area */} +
    + {/* Inner content panel */} +
    + {/* Ruler strip */} +
    + {rulerLabels.map(({ tick, label, leftPx }) => ( +
    + {label} +
    + ))} +
    + {/* Row stripes + guides (behind marks) */} + {rulerGuides} + {rows.map((row, i) => ( +
    + ))} + {/* Marks */} + {markEls} + {/* Playhead */} + {!!running && timeStart !== null && ( +
    + )} +
    +
    + {hoverTooltip && ( +
    + )} +
    + ); +} diff --git a/tgui/packages/tgui/interfaces/EventLogger/index.tsx b/tgui/packages/tgui/interfaces/EventLogger/index.tsx new file mode 100644 index 00000000000..0b877328ec1 --- /dev/null +++ b/tgui/packages/tgui/interfaces/EventLogger/index.tsx @@ -0,0 +1,253 @@ +import { useState } from 'react'; +import { Stack } from 'tgui-core/components'; +import { useBackend } from '../../backend'; +import { Window } from '../../layouts'; +import { sanitizeText } from '../../sanitize'; + +import { CategoryBar } from './CategoryBar'; +import { ControlBar } from './ControlBar'; +import { InfoPanel } from './InfoPanel'; +import { SelectedEventsPanel } from './SelectedEventsPanel'; +import type { TimelineMark, TimelineRow } from './Timeline'; +import { Timeline } from './Timeline'; +import type { Category, EventEntry, EventLoggerData, Track } from './types'; +import { buildCategoryColors } from './types'; + +// Build the marks in the track + +function buildMarks( + tracks: Track[], + categories: Category[], + colors: Record, + timeStart: number | null, + selectedEventIds: Set, +): TimelineMark[] { + const marks: TimelineMark[] = []; + + const enabledCats = new Set( + categories.filter((c) => c.enabled).map((c) => c.name), + ); + + for (const track of tracks) { + // Group events by tick + const byTick: Map = new Map(); + for (const evt of track.events) { + if (!enabledCats.has(evt.category)) continue; + const existing = byTick.get(evt.tick); + if (existing) { + existing.push(evt); + } else { + byTick.set(evt.tick, [evt]); + } + } + + for (const [tick, evts] of byTick) { + const isSelected = evts.some((e) => selectedEventIds.has(e.id)); + const isMulti = evts.length > 1; + // Use first event's category color; if mixed, still use first + const color = colors[evts[0].category] || '#888'; + const isSpatial = evts.some((e) => e.log_type !== 'text'); + + marks.push({ + rowId: track.ref, + tick, + color, + isCircle: !isSpatial, + isSelected, + isMulti, + count: evts.length, + tooltip: isMulti + ? `${evts.length} events at tick ${tick - (timeStart ?? 0)}` + : evts[0].info.replace(/<[^>]*>/g, ''), + tooltipHtml: isMulti + ? null + : sanitizeText(evts[0].info, false, undefined, [ + 'style', + 'background', + ]), + data: evts, + }); + } + } + + return marks; +} + +// Event logger root + +export function EventLogger() { + const { act, data } = useBackend(); + const { + running, + time_start, + time_current, + categories, + tracks, + selected_ref, + awaiting_pick, + } = data; + + const [zoom, setZoom] = useState(1); + const [autoScroll, setAutoScroll] = useState(true); + const [selectedEventIds, setSelectedEventIds] = useState>( + new Set(), + ); + + const colors = buildCategoryColors(categories); + + const rows: TimelineRow[] = tracks.map((track) => ({ + id: track.ref, + renderLabel: () => ( +
    + ]*>/g, '')} + onClick={() => handleSelectTrack(track)} + dangerouslySetInnerHTML={{ __html: sanitizeText(track.name) }} + /> + +
    + ), + })); + + const marks = buildMarks( + tracks, + categories, + colors, + time_start, + selectedEventIds, + ); + + function handleSelectTrack(track: Track) { + act('select_track', { ref: track.ref }); + setSelectedEventIds(new Set()); + } + + function handleMarkClick(mark: TimelineMark, ctrl: boolean) { + const evtIds = mark.data.map((e) => e.id); + + // Find the track this mark belongs to so we can select it + const track = tracks.find((t) => t.ref === mark.rowId); + if (track && selected_ref !== track.ref) { + act('select_track', { ref: track.ref }); + } + + // Select events on server (for overlay rendering) + act('select_events', { ids: evtIds }); + + setSelectedEventIds((prev) => { + if (ctrl) { + // Toggle group: if all already selected, deselect; else add + const allSelected = evtIds.every((id) => prev.has(id)); + const next = new Set(prev); + if (allSelected) { + for (const id of evtIds) next.delete(id); + } else { + for (const id of evtIds) next.add(id); + } + return next; + } + // Replace selection + return new Set(evtIds); + }); + } + + return ( + + + + {/* Control bar */} + + + + + {/* Category toggles */} + + + + + {/* Timeline */} + +
    + + rows={rows} + marks={marks} + timeStart={time_start} + timeCurrent={time_current} + zoom={zoom} + running={running} + autoScroll={autoScroll} + onMarkClick={handleMarkClick} + onEmptyClick={() => { + setSelectedEventIds(new Set()); + act('select_events', { ids: [] }); + }} + onZoomChange={setZoom} + /> +
    +
    + + {/* Bottom row: track info + selected events */} + + + + + + + + + + +
    +
    +
    + ); +} diff --git a/tgui/packages/tgui/interfaces/EventLogger/types.ts b/tgui/packages/tgui/interfaces/EventLogger/types.ts new file mode 100644 index 00000000000..0b1e7bb4780 --- /dev/null +++ b/tgui/packages/tgui/interfaces/EventLogger/types.ts @@ -0,0 +1,140 @@ +// ── Palette / label constants ───────────────────────────────────────────────── + +export const CATEGORY_PALETTE: string[] = [ + '#4fc3f7', + '#81c784', + '#ffb74d', + '#e57373', + '#ba68c8', + '#4dd0e1', + '#fff176', + '#f06292', + '#a1887f', + '#90a4ae', +]; + +export const LOG_TYPE_LABELS: Record = { + text: 'TXT', + location: 'LOC', + turfs: 'TURF', + lines: 'LINE', + path: 'PATH', + maptext: 'MAPTXT', +}; + +export const LOG_TYPE_COLORS: Record = { + text: '#aaaaaa', + location: '#4fc3f7', + turfs: '#81c784', + lines: '#ffb74d', + path: '#ce93d8', + maptext: '#ffe082', +}; + +// ── Data types ──────────────────────────────────────────────────────────────── + +export type Category = { name: string; enabled: boolean }; + +export type TrackInfoEntry = { category: string; title: string; entry: string }; + +export type BaseEvent = { + id: number; + tick: number; + category: string; + log_type: 'text' | 'location' | 'turfs' | 'lines' | 'path' | 'maptext'; + info: string; + track_info?: TrackInfoEntry[]; +}; + +export type TextEvent = BaseEvent & { log_type: 'text' }; + +export type LocationEvent = BaseEvent & { + log_type: 'location'; + x: number; + y: number; + z: number; +}; + +export type TurfsEvent = BaseEvent & { + log_type: 'turfs'; + coords: Array<{ x: number; y: number; z: number }>; +}; + +export type LinesEvent = BaseEvent & { + log_type: 'lines'; + x1: number; + y1: number; + z1: number; + x2: number; + y2: number; + z2: number; +}; + +export type PathEvent = BaseEvent & { + log_type: 'path'; + coords: Array<{ x: number; y: number; z: number }>; +}; + +export type MapTextEvent = BaseEvent & { + log_type: 'maptext'; + x: number; + y: number; + z: number; + text: string; +}; + +export type EventEntry = + | TextEvent + | LocationEvent + | TurfsEvent + | LinesEvent + | PathEvent + | MapTextEvent; + +export type InfoPair = { title: string; entry: string }; + +export type Track = { + name: string; + ref: string; + events: EventEntry[]; + info: InfoPair[]; +}; + +export type EventLoggerData = { + running: boolean; + time_start: number | null; + time_current: number; + categories: Category[]; + tracks: Track[]; + selected_ref: string | null; + awaiting_pick: boolean; +}; + +// ── Helpers ─────────────────────────────────────────────────────────────────── + +export function buildCategoryColors( + categories: Category[], +): Record { + const map: Record = {}; + categories.forEach((cat, i) => { + map[cat.name] = CATEGORY_PALETTE[i % CATEGORY_PALETTE.length]; + }); + return map; +} + +export function getEventPrimaryCoord( + evt: EventEntry, +): { x: number; y: number; z: number } | null { + switch (evt.log_type) { + case 'location': + case 'maptext': + return { x: evt.x, y: evt.y, z: evt.z }; + case 'turfs': + case 'path': + return evt.coords.length > 0 ? evt.coords[0] : null; + case 'lines': + return { x: evt.x1, y: evt.y1, z: evt.z1 }; + default: + return null; + } +} diff --git a/tgui/packages/tgui/interfaces/HotkeysHelp.tsx b/tgui/packages/tgui/interfaces/HotkeysHelp.tsx index 21c980246c3..4f83f04a1e6 100644 --- a/tgui/packages/tgui/interfaces/HotkeysHelp.tsx +++ b/tgui/packages/tgui/interfaces/HotkeysHelp.tsx @@ -1,4 +1,4 @@ -import { Box, Section, Table, Tooltip } from 'tgui-core/components'; +import { Box, Button, Section, Table, Tooltip } from 'tgui-core/components'; import { useBackend } from '../backend'; import { Window } from '../layouts'; @@ -90,12 +90,19 @@ const KeyBinding = (props: KeyBindingBoxProps) => ( ); export const HotkeysHelp = (props) => { - const { data } = useBackend(); + const { act, data } = useBackend(); return ( - + -
    +
    act('open_keybindings')}> + Open Hotkey Settings + + } + > diff --git a/tgui/packages/tgui/interfaces/IntegratedCircuit/FundamentalTypes.jsx b/tgui/packages/tgui/interfaces/IntegratedCircuit/FundamentalTypes.jsx index 0595b965058..c86cd10d712 100644 --- a/tgui/packages/tgui/interfaces/IntegratedCircuit/FundamentalTypes.jsx +++ b/tgui/packages/tgui/interfaces/IntegratedCircuit/FundamentalTypes.jsx @@ -17,7 +17,7 @@ export const FUNDAMENTAL_DATA_TYPES = { setValue(value)} width="96px" /> @@ -121,7 +121,7 @@ export const FUNDAMENTAL_DATA_TYPES = { setValue(value)} width="64px" /> diff --git a/tgui/packages/tgui/interfaces/LaborClaimConsole.jsx b/tgui/packages/tgui/interfaces/LaborClaimConsole.jsx index 0cd5f682361..21e92eeffd1 100644 --- a/tgui/packages/tgui/interfaces/LaborClaimConsole.jsx +++ b/tgui/packages/tgui/interfaces/LaborClaimConsole.jsx @@ -5,20 +5,29 @@ import { Window } from '../layouts'; export const LaborClaimConsole = (props) => { const { act, data } = useBackend(); - const { can_go_home, id_points, ores, status_info, unclaimed_points } = data; + const { + can_go_home, + id_points, + ores, + status_info, + unclaimed_points, + shuttle_exists, + } = data; return (
    {status_info} - -
    - The nearby stacking machine will unload crates and collect smelted - materials, points will be calculated based on volume of delivered - materials. + Collect boulders and ores from the mining area and bring them to the + unloading machine. Then, pull the lever to smelt them into sheets. Use + the production console to dispense the sheets, and then bring bring + them to the claim console to earn points.
    - Please note that only sheets printed with our manufacturer's seal - of quality, such as those produced from the work camp furnace, will be - accepted as proof of labour. +
    + Boulders cannot be smelted directly, and will require additional + manual processing - strike them with a pickaxe to break them down + further. +
    +
    + Sheets smelted from the labor camp's furnace will be stamped with an + official seal of quality. Only stamped sheets can be claimed for + points - so don't bother trying to strip down tables and chairs for + bonus metal.
    diff --git a/tgui/packages/tgui/interfaces/LaunchpadConsole.tsx b/tgui/packages/tgui/interfaces/LaunchpadConsole.tsx index 30f9a0008b5..4ec0781bcf3 100644 --- a/tgui/packages/tgui/interfaces/LaunchpadConsole.tsx +++ b/tgui/packages/tgui/interfaces/LaunchpadConsole.tsx @@ -52,7 +52,7 @@ export function LaunchpadConsole(props) { const { launchpads = [], selected_id } = data; return ( - + {launchpads.length === 0 ? ( No Pads Connected diff --git a/tgui/packages/tgui/interfaces/LaunchpadRemote.tsx b/tgui/packages/tgui/interfaces/LaunchpadRemote.tsx index d56bfd1cc30..77c896803bb 100644 --- a/tgui/packages/tgui/interfaces/LaunchpadRemote.tsx +++ b/tgui/packages/tgui/interfaces/LaunchpadRemote.tsx @@ -17,8 +17,8 @@ export const LaunchpadRemote = (props) => { return ( diff --git a/tgui/packages/tgui/interfaces/MatMarket.tsx b/tgui/packages/tgui/interfaces/MatMarket.tsx index f87a788c2fe..516df55d06e 100644 --- a/tgui/packages/tgui/interfaces/MatMarket.tsx +++ b/tgui/packages/tgui/interfaces/MatMarket.tsx @@ -1,11 +1,13 @@ import { sortBy } from 'es-toolkit'; import { + Box, Button, Collapsible, Modal, NoticeBox, Section, Stack, + Tooltip, } from 'tgui-core/components'; import { formatMoney } from 'tgui-core/format'; import type { BooleanLike } from 'tgui-core/react'; @@ -20,7 +22,8 @@ type Material = { rarity: number; trend: string; price: number; - threshold: number; + min_threshold: number; + max_threshold: number; color: string; requested: number; elastic: number; @@ -56,17 +59,18 @@ export const MatMarket = (props) => { const multiplier = orderingPrive ? 1.1 : 1; return ( - + {!!catastrophe && }
    { ) } > - - - Buy orders for material sheets placed here will be ordered on the - next cargo shipment. -

    - To sell materials, please insert sheets or similar stacks of - materials. All minerals sold on the market directly are subject to - a scaling value decrease per material, but this will recover over - time. To prevent market manipulation, all registered traders can - buy a total of 10 full stacks of materials at a time. -

    - When selling materials, prices will be decreased based on the - elastic modifier of the material, which will recover over time. -

    - All new purchases will include the cost of the shipped crate, - which may be recycled afterwards. -
    -
    @@ -127,7 +113,7 @@ export const MatMarket = (props) => { (material, i) => (
    - + { Elasticity: {Math.round(material.elastic)}% - - Trading at {formatMoney(material.price)} cr. + + + Trading at
    {formatMoney(material.price)} cr.
    +
    +
    - {material.price < material.threshold ? ( + {material.price < material.min_threshold ? ( Material price critical!
    Trading temporarily suspended.
    ) : ( - {material.quantity || 'Zero'} sheets of{' '} - {material.name} trading.{' '} - {material.requested || 'Zero'} sheets ordered. + + {material.quantity || 'Zero'} sheets of{' '} + {material.name} trading.{' '} + + 0 ? 'lightblue' : 'white'} + > + {material.requested || 'Zero'} sheets ordered. + )} { - {material.requested > 0 && ( - x {material.requested} - )}
    ), )} + + + Buy orders for material sheets placed here will be ordered on the + next cargo shipment. +

    + To sell materials, please insert sheets or similar stacks of + materials. All minerals sold on the market directly are subject to + a scaling value decrease per material, but this will recover over + time. To prevent market manipulation, all registered traders can + buy a total of 10 full stacks of materials at a time. +

    + When selling materials, prices will be decreased based on the + elastic modifier of the material, which will recover over time. +

    + All new purchases will include the cost of the shipped crate, + which may be recycled afterwards. +
    +
    ); @@ -299,3 +325,16 @@ const MarketCrashModal = (props) => { ); }; + +type rangeTextProps = { + minPrice: number; + maxPrice: number; +} + +function rangeText(props: rangeTextProps) { + const {minPrice, maxPrice} = props; + return ( + "This material can be bought and sold between " + formatMoney(minPrice) + + " - " + formatMoney(maxPrice) + " cr." + ) +} diff --git a/tgui/packages/tgui/interfaces/NtosMessenger/index.tsx b/tgui/packages/tgui/interfaces/NtosMessenger/index.tsx index 241b9ebed86..b907e643f08 100644 --- a/tgui/packages/tgui/interfaces/NtosMessenger/index.tsx +++ b/tgui/packages/tgui/interfaces/NtosMessenger/index.tsx @@ -201,7 +201,7 @@ const ContactsScreen = (props: any) => { - SpaceMessenger V6.5.3 + SpaceMessenger V6.5.4 Bringing you spy-proof communications since 2467. @@ -368,6 +368,7 @@ const SendToAllSection = (props) => {