diff --git a/.github/workflows/discord_pr_announce.yml b/.github/workflows/discord_pr_announce.yml index ebaaa85d5608..a24f8bb2b778 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/run_linters.yml b/.github/workflows/run_linters.yml index a916e3969e0e..126f63b45262 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@93eac224fa5a1e835cc942d66c12ee373bc7fae9 + 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 3d60604fd018..bac532e7080f 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -38,9 +38,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, @@ -65,7 +67,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/_maps/RandomRuins/AnywhereRuins/shoe_factory.dmm b/_maps/RandomRuins/AnywhereRuins/shoe_factory.dmm new file mode 100644 index 000000000000..2bcfe8765f14 --- /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 +Kq +"} +(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 +EC +dx +YM +YM +YM +dx +dx +dx +dx +YM +dx +dx +dx +YM +dx +YM +dx +"} diff --git a/_maps/RandomRuins/SpaceRuins/bus.dmm b/_maps/RandomRuins/SpaceRuins/bus.dmm index 177654f63add..b725897aa360 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 349d32e62a3a..dd93e77a597b 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 78b403b3c122..5c9389cf0fbc 100644 --- a/_maps/RandomZLevels/heretic.dmm +++ b/_maps/RandomZLevels/heretic.dmm @@ -9494,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{ diff --git a/_maps/RandomZLevels/research.dmm b/_maps/RandomZLevels/research.dmm index c3513c00bfcc..66e00db43a65 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 f04f564a3d66..4ea337fddc7f 100644 --- a/_maps/map_files/CatwalkStation/CatwalkStation_2023.dmm +++ b/_maps/map_files/CatwalkStation/CatwalkStation_2023.dmm @@ -4231,12 +4231,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 +6925,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, @@ -10013,11 +10017,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" = ( @@ -14154,6 +14160,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" = ( @@ -19463,6 +19472,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."; @@ -30016,11 +30033,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" = ( @@ -32667,7 +32686,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) @@ -45384,6 +45403,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{ @@ -50553,6 +50578,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" = ( @@ -56153,6 +56181,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{ @@ -59624,13 +59658,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" = ( @@ -65844,7 +65878,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, @@ -66021,12 +66055,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" = ( @@ -67416,6 +67448,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) @@ -70223,7 +70260,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, @@ -75354,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, @@ -75420,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" = ( @@ -76832,6 +76861,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 @@ -80107,6 +80145,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, @@ -88976,6 +89026,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, @@ -89347,6 +89403,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, @@ -89597,7 +89658,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 }, @@ -90688,7 +90749,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" @@ -199829,9 +199890,9 @@ pSB lGA xSg pQI +xCP blo ayK -lwA vmk lwA lwA @@ -200086,10 +200147,10 @@ avc mIp iwQ sLK +rXI wrT toR wUi -wUi sfc avI sfc @@ -200341,11 +200402,11 @@ pSB avc pSB lnH -peQ +oTH hXr +mbh wrT rWg -lwA oPr lwA lwA @@ -200600,9 +200661,9 @@ pSB gLT peQ rCF +fiR wrT rWg -lwA oPr lwA lwA @@ -200855,10 +200916,10 @@ gkh oaF dKL lhy -peQ +oTH cCN +xHg wrT -bex iGo oPr lwA @@ -201113,10 +201174,10 @@ geK aPg jAO bEr -ucf -wrT -wrT +rCF +uvA wrT +rYh fQz kIE kIE @@ -201371,9 +201432,9 @@ cgX nwQ dKT ucX +bOF wrT -rYh -wrT +vmm mYL wrT wrT @@ -201629,7 +201690,7 @@ uKP uKP uKP wrT -rYh +wrT wrT cYX lVF @@ -201885,7 +201946,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 e183b08b3322..d2e8048ba442 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -3743,7 +3743,6 @@ /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) @@ -8209,10 +8208,11 @@ /area/station/service/library) "bXF" = ( /obj/effect/turf_decal/tile/brown/anticorner/contrasted, +/obj/machinery/brm, /obj/machinery/conveyor{ + dir = 8; id = "mining" }, -/obj/machinery/brm, /turf/open/floor/iron, /area/station/cargo/warehouse) "bXG" = ( @@ -17211,9 +17211,7 @@ }, /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" = ( @@ -18046,14 +18044,11 @@ /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 +/obj/machinery/bouldertech/refinery, +/obj/machinery/conveyor{ + dir = 8; + id = "mining" }, /turf/open/floor/iron, /area/station/cargo/warehouse) @@ -20598,12 +20593,14 @@ /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, +/obj/item/stack/ducts, +/obj/item/stack/ducts, +/obj/item/stack/ducts, /turf/open/floor/iron, /area/station/cargo/warehouse) "fdG" = ( @@ -20886,7 +20883,7 @@ /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, +/mob/living/basic/bot/secbot/beepsky/officer, /turf/open/floor/iron, /area/station/hallway/primary/starboard) "fgq" = ( @@ -22676,13 +22673,13 @@ /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, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/conveyor{ + dir = 8; + id = "mining" + }, /turf/open/floor/iron, /area/station/cargo/warehouse) "fCD" = ( @@ -27814,6 +27811,11 @@ /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) "gKI" = ( @@ -31249,11 +31251,9 @@ /turf/open/floor/iron/white, /area/station/medical/virology) "hGP" = ( -/obj/machinery/conveyor{ - dir = 8; - id = "mining" - }, -/obj/machinery/bouldertech/refinery, +/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) "hGW" = ( @@ -32201,7 +32201,7 @@ /obj/effect/turf_decal/stripes/corner{ dir = 4 }, -/mob/living/simple_animal/bot/secbot/beepsky/armsky, +/mob/living/basic/bot/secbot/beepsky/armsky, /turf/open/floor/iron/dark, /area/station/security/armory) "hTv" = ( @@ -48781,9 +48781,12 @@ /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, +/obj/machinery/bouldertech/refinery/smelter, +/obj/machinery/conveyor{ + dir = 8; + id = "mining" + }, /turf/open/floor/iron, /area/station/cargo/warehouse) "lXm" = ( @@ -64795,10 +64798,8 @@ /area/station/maintenance/port) "pVR" = ( /obj/structure/sign/poster/contraband/random/directional/south, -/obj/machinery/conveyor{ - dir = 10; - id = "mining" - }, +/obj/effect/turf_decal/tile/brown/anticorner/contrasted, +/obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/cargo/warehouse) "pWb" = ( @@ -75244,10 +75245,10 @@ /turf/closed/wall, /area/station/service/bar/backroom) "szC" = ( -/obj/machinery/conveyor{ - dir = 9; - id = "mining" +/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ + dir = 8 }, +/obj/effect/landmark/start/hangover, /turf/open/floor/iron, /area/station/cargo/warehouse) "szG" = ( @@ -82886,10 +82887,13 @@ /turf/open/floor/iron, /area/station/hallway/secondary/entry) "utQ" = ( -/obj/machinery/conveyor{ - dir = 8; - id = "mining" +/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) "utS" = ( @@ -83760,7 +83764,13 @@ }, /obj/machinery/light/small/directional/west, /obj/effect/turf_decal/delivery, -/obj/effect/landmark/start/hangover, +/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) "uDQ" = ( @@ -86418,11 +86428,8 @@ /turf/open/floor/plating, /area/station/maintenance/port/fore) "vnI" = ( -/obj/machinery/conveyor{ - dir = 8; - id = "mining" - }, -/obj/machinery/bouldertech/refinery/smelter, +/obj/effect/turf_decal/tile/brown/half/contrasted, +/obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/cargo/warehouse) "vnP" = ( @@ -90268,6 +90275,8 @@ dir = 1 }, /obj/effect/decal/cleanable/dirt, +/obj/structure/closet/crate, +/obj/effect/spawner/random/maintenance, /turf/open/floor/iron, /area/station/cargo/warehouse) "wlW" = ( @@ -93139,7 +93148,6 @@ /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 @@ -96417,7 +96425,7 @@ /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, +/mob/living/basic/bot/secbot/pingsky, /turf/open/floor/iron/grimy, /area/station/ai/satellite/interior) "xMX" = ( @@ -97164,6 +97172,7 @@ dir = 1 }, /obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/start/hangover, /turf/open/floor/iron, /area/station/cargo/warehouse) "xXw" = ( diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index 906ce11eee73..6c5bc14129cc 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -3582,7 +3582,7 @@ /area/station/maintenance/starboard/fore) "aXq" = ( /obj/item/bedsheet/red, -/mob/living/simple_animal/bot/secbot/beepsky, +/mob/living/basic/bot/secbot/beepsky, /turf/open/floor/plating, /area/station/maintenance/fore) "aXG" = ( @@ -3642,9 +3642,9 @@ /area/station/science/research) "aYM" = ( /obj/effect/turf_decal/bot, -/obj/structure/closet/crate, -/obj/item/coin/gold, /obj/item/radio/intercom/directional/north, +/obj/item/coin/gold, +/obj/structure/closet/crate, /turf/open/floor/iron, /area/mine/production) "aYQ" = ( @@ -5057,16 +5057,15 @@ /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/machinery/bouldertech/refinery/smelter{ + dir = 4 + }, +/obj/structure/railing/corner/end/flip{ + dir = 4 }, -/obj/effect/turf_decal/stripes/line, -/obj/machinery/light/small/directional/south, /turf/open/floor/iron, /area/mine/production) "brY" = ( @@ -7423,6 +7422,14 @@ "bXy" = ( /turf/open/openspace, /area/station/security/armory/upper) +"bXC" = ( +/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) "bXD" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -7980,14 +7987,14 @@ dir = 4 }, /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") }, +/obj/machinery/conveyor{ + dir = 10; + id = "mining_internal" + }, /turf/open/floor/iron, /area/mine/production) "ceO" = ( @@ -8628,9 +8635,12 @@ /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, +/obj/structure/railing/corner/end{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, /turf/open/floor/iron, /area/mine/production) "coZ" = ( @@ -14318,16 +14328,14 @@ /turf/open/floor/iron, /area/station/commons/storage/primary) "dTF" = ( -/obj/machinery/conveyor{ - dir = 10; - id = "mining_internal" - }, -/obj/effect/turf_decal/stripes/corner{ +/obj/structure/railing{ dir = 1 }, /obj/effect/turf_decal/stripes/line{ - dir = 6 + dir = 1 }, +/obj/effect/decal/cleanable/greenglow/waste, +/obj/effect/turf_decal/tile/brown/opposingcorners, /turf/open/floor/iron, /area/mine/production) "dTI" = ( @@ -14831,6 +14839,15 @@ /obj/structure/flora/rock/pile/icy/style_random, /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/underground/explored) +"ebn" = ( +/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) "ebr" = ( /turf/open/openspace, /area/station/engineering/atmos/storage) @@ -22300,15 +22317,13 @@ /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 = 9 + }, +/obj/structure/railing{ dir = 1 }, -/obj/effect/turf_decal/stripes/line, -/obj/machinery/bouldertech/refinery/smelter, +/obj/effect/turf_decal/tile/brown/opposingcorners, /turf/open/floor/iron, /area/mine/production) "gks" = ( @@ -23748,6 +23763,15 @@ dir = 4 }, /area/station/command/heads_quarters/rd) +"gEA" = ( +/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) "gEE" = ( /turf/open/openspace, /area/station/service/chapel) @@ -24011,7 +24035,7 @@ /turf/open/floor/plating, /area/station/maintenance/starboard/fore) "gJI" = ( -/mob/living/simple_animal/bot/secbot/beepsky/armsky, +/mob/living/basic/bot/secbot/beepsky/armsky, /obj/machinery/airalarm/directional/east, /turf/open/floor/iron/dark/textured, /area/station/security/armory) @@ -24224,6 +24248,10 @@ /obj/item/reagent_containers/dropper, /turf/open/floor/iron/cafeteria, /area/station/science/lab) +"gNm" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/mine/production) "gNC" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /obj/structure/sign/warning/secure_area/directional/north, @@ -27508,6 +27536,15 @@ /obj/structure/closet/secure_closet/medical2, /turf/open/floor/iron, /area/station/maintenance/port/fore) +"hKw" = ( +/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) "hKI" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -30314,6 +30351,13 @@ /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) +"izv" = ( +/obj/structure/rack, +/obj/item/stack/ducts{ + amount = 5 + }, +/turf/open/floor/iron, +/area/mine/production) "izw" = ( /obj/machinery/door/airlock/external{ name = "Solar Maintenance" @@ -33089,6 +33133,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/department/medical/morgue) +"jpW" = ( +/obj/machinery/airalarm/directional/west, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/mine/production) "jqc" = ( /obj/machinery/door/airlock/external{ glass = 1; @@ -34198,6 +34247,10 @@ }, /turf/open/floor/iron/cafeteria, /area/station/commons/dorms/laundry) +"jHr" = ( +/obj/effect/turf_decal/tile/brown/opposingcorners, +/turf/open/floor/iron, +/area/mine/production) "jHF" = ( /obj/item/trash/boritos/red, /obj/structure/cable, @@ -35421,14 +35474,17 @@ /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, +/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) "jXL" = ( @@ -43343,6 +43399,10 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, /turf/open/floor/engine, /area/station/maintenance/disposal/incinerator) +"mgE" = ( +/obj/machinery/light/small/directional/south, +/turf/open/floor/iron, +/area/mine/production) "mgS" = ( /obj/effect/spawner/structure/window/hollow/reinforced/middle{ dir = 4 @@ -45044,9 +45104,6 @@ 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, @@ -45949,7 +46006,7 @@ /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, +/mob/living/basic/bot/secbot/pingsky, /turf/open/floor/iron/dark, /area/station/ai/satellite/interior) "mXj" = ( @@ -46685,6 +46742,8 @@ /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) "ngn" = ( @@ -54952,6 +55011,8 @@ /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) "pqo" = ( @@ -58220,7 +58281,13 @@ /area/station/medical/virology) "qkI" = ( /obj/effect/decal/cleanable/dirt, -/obj/structure/railing/corner/end{ +/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, @@ -58840,6 +58907,10 @@ /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) "que" = ( @@ -61993,7 +62064,10 @@ /turf/open/floor/plating, /area/station/maintenance/port/aft) "rnl" = ( -/obj/structure/railing, +/obj/machinery/conveyor{ + dir = 8; + id = "mining_internal" + }, /turf/open/floor/iron, /area/mine/production) "rnp" = ( @@ -62897,7 +62971,7 @@ /obj/effect/turf_decal/tile/red{ dir = 1 }, -/mob/living/simple_animal/bot/secbot/beepsky{ +/mob/living/basic/bot/secbot/beepsky{ desc = "Powered by the tears and sweat of laborers."; name = "Prison Ofitser" }, @@ -67486,12 +67560,6 @@ /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" = ( @@ -72360,6 +72428,12 @@ }, /turf/open/floor/iron/dark, /area/station/medical/virology) +"ula" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/turf/open/floor/iron, +/area/mine/production) "ulj" = ( /obj/structure/flora/tree/pine/style_random, /obj/structure/flora/grass/green/style_random, @@ -74865,8 +74939,10 @@ /turf/open/floor/iron, /area/station/service/hydroponics) "uYF" = ( -/obj/structure/railing{ - dir = 6 +/obj/machinery/bouldertech/refinery, +/obj/machinery/conveyor{ + dir = 8; + id = "mining_internal" }, /turf/open/floor/iron, /area/mine/production) @@ -79736,6 +79812,9 @@ "wxN" = ( /turf/closed/wall/r_wall, /area/station/maintenance/solars/port/fore) +"wxP" = ( +/turf/open/floor/iron, +/area/mine/production) "wxT" = ( /obj/structure/railing{ dir = 1 @@ -84745,10 +84824,10 @@ }, /area/station/security/processing) "xQK" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 1 +/obj/machinery/conveyor/inverted{ + dir = 5; + id = "mining_internal" }, -/obj/structure/railing, /turf/open/floor/iron, /area/mine/production) "xQO" = ( @@ -84894,6 +84973,13 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/starboard/upper) +"xTE" = ( +/obj/machinery/conveyor{ + dir = 10; + id = "mining_internal" + }, +/turf/open/floor/iron, +/area/mine/production) "xTL" = ( /obj/effect/turf_decal/tile/blue, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -169808,9 +169894,9 @@ sht gOU gjq eJf -gjq -gjq -gjq +eJf +eJf +eJf gjq gjq gjq @@ -170064,9 +170150,9 @@ cMk wmR cMk cMk -eJf -eJf -eJf +bie +cMk +cMk faL eJf eJf @@ -170318,12 +170404,12 @@ bKE vpc kZu aYM -tDa +ebn sWU +jpW +wxP +izv cMk -cMk -gjq -gjq eJf gjq gjq @@ -170578,9 +170664,9 @@ fxY pql qkI coY +bXC +mgE cMk -gjq -gjq eJf gjq gjq @@ -170835,9 +170921,9 @@ vQy ngl xQK brX -cMk -gjq -gjq +xTE +gNm +uvM eJf gjq iDt @@ -171088,13 +171174,13 @@ tDa tDa tDa sWB -tDa -pql +gEA +hKw rnl gko -uvM -gjq -gjq +ula +jHr +cMk gnh iDt iDt diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 4bbff70a9e90..39a5c2d025db 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -299,7 +299,7 @@ /area/station/science/research) "agc" = ( /obj/effect/turf_decal/bot, -/mob/living/simple_animal/bot/secbot/beepsky/armsky, +/mob/living/basic/bot/secbot/beepsky/armsky, /turf/open/floor/iron/dark, /area/station/security/armory) "agi" = ( @@ -1976,6 +1976,15 @@ }, /turf/open/floor/wood, /area/station/commons/lounge) +"aKs" = ( +/obj/machinery/bouldertech/refinery{ + dir = 4 + }, +/obj/machinery/conveyor{ + id = "mining" + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "aKz" = ( /obj/structure/chair{ dir = 4 @@ -7389,7 +7398,12 @@ /turf/open/floor/plating, /area/station/science/robotics/mechbay) "cBZ" = ( -/obj/structure/railing, +/obj/machinery/bouldertech/refinery/smelter{ + dir = 4 + }, +/obj/machinery/conveyor{ + id = "mining" + }, /turf/open/floor/iron, /area/station/cargo/miningoffice) "cCM" = ( @@ -7891,6 +7905,8 @@ /area/station/commons/fitness) "cLj" = ( /obj/structure/cable, +/obj/structure/railing/corner, +/obj/effect/turf_decal/siding/white/corner, /turf/open/floor/iron, /area/station/cargo/miningoffice) "cLk" = ( @@ -8290,8 +8306,11 @@ /turf/open/floor/iron, /area/station/commons/dorms) "cUt" = ( -/obj/effect/turf_decal/stripes/line, -/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/conveyor{ + dir = 8; + id = "mining" + }, +/obj/machinery/brm, /turf/open/floor/iron, /area/station/cargo/miningoffice) "cUw" = ( @@ -10008,14 +10027,13 @@ /turf/open/floor/plating, /area/station/maintenance/starboard/greater) "dxo" = ( -/obj/structure/railing{ - dir = 6 +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 8 }, -/obj/effect/decal/cleanable/dirt/dust, -/obj/effect/turf_decal/stripes/corner{ - dir = 4 +/obj/effect/turf_decal/stripes/line{ + dir = 8 }, -/turf/open/floor/iron, +/turf/open/floor/iron/textured, /area/station/cargo/miningoffice) "dxq" = ( /obj/structure/chair{ @@ -17795,6 +17813,11 @@ /obj/machinery/vending/wardrobe/jani_wardrobe, /turf/open/floor/iron, /area/station/service/janitor) +"gjS" = ( +/obj/structure/cable, +/obj/effect/turf_decal/siding/white, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "gjZ" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 8 @@ -20983,15 +21006,14 @@ /turf/open/floor/carpet, /area/station/command/heads_quarters/captain/private) "hlE" = ( +/obj/machinery/light/small/directional/south, /obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 1 + dir = 8 }, -/obj/machinery/conveyor{ - dir = 8; - id = "mining" +/obj/effect/turf_decal/stripes/corner{ + dir = 1 }, -/obj/machinery/light/small/directional/south, -/turf/open/floor/iron, +/turf/open/floor/iron/textured, /area/station/cargo/miningoffice) "hlN" = ( /obj/structure/frame/machine{ @@ -25162,11 +25184,13 @@ /turf/open/floor/engine, /area/station/science/xenobiology) "iId" = ( -/obj/machinery/conveyor{ - id = "mining" +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 1 }, -/obj/machinery/brm, -/turf/open/floor/iron, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/iron/textured, /area/station/cargo/miningoffice) "iIf" = ( /obj/machinery/camera/directional/north{ @@ -27527,7 +27551,7 @@ /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, +/mob/living/basic/bot/secbot/pingsky, /turf/open/floor/iron/dark, /area/station/ai/satellite/interior) "jvQ" = ( @@ -29839,7 +29863,7 @@ /obj/effect/turf_decal/trimline/red/filled/line{ dir = 8 }, -/mob/living/simple_animal/bot/secbot/beepsky/officer, +/mob/living/basic/bot/secbot/beepsky/officer, /turf/open/floor/iron, /area/station/security/brig) "kho" = ( @@ -31899,6 +31923,16 @@ /turf/open/floor/iron, /area/station/commons/locker) "kRe" = ( +/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) "kRf" = ( @@ -33122,6 +33156,14 @@ }, /turf/open/floor/iron, /area/station/science/lab) +"lnv" = ( +/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) "lnH" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -37658,6 +37700,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/hallway/secondary/exit/departure_lounge) +"mRP" = ( +/obj/machinery/conveyor/inverted{ + dir = 5; + id = "mining" + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "mRY" = ( /obj/machinery/door/window/left/directional/north{ name = "Mass Driver"; @@ -44697,6 +44746,9 @@ /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) "pom" = ( @@ -48647,17 +48699,14 @@ /turf/closed/wall, /area/station/hallway/secondary/entry) "qHt" = ( -/obj/structure/railing{ - dir = 4 +/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ + dir = 1 }, /obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/machinery/conveyor_switch/oneway{ - id = "mining"; - dir = 1 + dir = 9 }, -/turf/open/floor/iron, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron/textured, /area/station/cargo/miningoffice) "qHK" = ( /obj/effect/spawner/random/structure/grille, @@ -49430,14 +49479,12 @@ /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, +/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) "qTz" = ( @@ -53721,6 +53768,16 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central) +"sqP" = ( +/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) "sqT" = ( /obj/machinery/atmospherics/components/tank/air/layer4, /turf/open/floor/plating, @@ -56156,10 +56213,10 @@ /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{ +/obj/structure/railing{ + dir = 6 + }, +/obj/effect/turf_decal/siding/white{ dir = 4 }, /turf/open/floor/iron, @@ -56281,9 +56338,11 @@ /area/station/maintenance/starboard/fore) "tkf" = ( /obj/structure/extinguisher_cabinet/directional/east, -/obj/machinery/conveyor{ - id = "mining" +/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) "tkg" = ( @@ -66279,10 +66338,9 @@ dir = 1 }, /obj/machinery/conveyor{ - dir = 8; + dir = 10; id = "mining" }, -/obj/machinery/bouldertech/refinery/smelter, /turf/open/floor/iron, /area/station/cargo/miningoffice) "wyV" = ( @@ -67655,14 +67713,8 @@ /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, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/turf_decal/tile/brown/opposingcorners, /turf/open/floor/iron, /area/station/cargo/miningoffice) "wZw" = ( @@ -69162,6 +69214,12 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/aft) +"xzf" = ( +/obj/structure/cable, +/obj/structure/railing, +/obj/effect/turf_decal/siding/white, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "xzj" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -70851,8 +70909,10 @@ /turf/open/floor/iron/dark, /area/station/engineering/atmos) "ydi" = ( -/obj/structure/railing/corner/end/flip, -/obj/effect/turf_decal/stripes/corner, +/obj/machinery/conveyor{ + dir = 8; + id = "mining" + }, /turf/open/floor/iron, /area/station/cargo/miningoffice) "ydj" = ( @@ -89388,7 +89448,7 @@ sLU aZj cSP cLj -kRe +sqP kRe tid qTf @@ -89644,9 +89704,9 @@ jXu jXu jXu hzb -cLj -kRe -kRe +xzf +mRP +aKs cBZ wyP hKg @@ -89901,7 +89961,7 @@ omV kts cuh jBp -cLj +lnv ydi qHt dxo @@ -90158,7 +90218,7 @@ cAf dve jXu pVV -cLj +gjS cUt iId tkf diff --git a/_maps/map_files/Mining/Lavaland.dmm b/_maps/map_files/Mining/Lavaland.dmm index 0e9b0facd410..3912d3676aac 100644 --- a/_maps/map_files/Mining/Lavaland.dmm +++ b/_maps/map_files/Mining/Lavaland.dmm @@ -972,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 }, @@ -2475,7 +2475,7 @@ cycle_id = "lavaland_living_north" }, /turf/open/floor/iron/textured_large, -/area/lavaland/surface/outdoors) +/area/mine/lounge) "mJ" = ( /obj/docking_port/stationary{ dwidth = 2; @@ -4172,7 +4172,7 @@ "wc" = ( /obj/effect/turf_decal/stripes/line, /turf/open/floor/iron/textured_large, -/area/lavaland/surface/outdoors) +/area/mine/lounge) "wg" = ( /obj/structure/chair/sofa/corp{ dir = 1 @@ -5075,10 +5075,6 @@ /obj/structure/sign/poster/official/report_crimes/directional/west, /turf/open/floor/iron/smooth, /area/mine/laborcamp) -"BW" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/lavaland/surface/outdoors) "Ce" = ( /turf/open/floor/plating, /area/mine/maintenance/public/south) @@ -8397,10 +8393,6 @@ /obj/structure/lattice/catwalk/mining, /turf/open/lava/smooth/lava_land_surface, /area/lavaland/surface/outdoors) -"VL" = ( -/obj/machinery/ore_silo, -/turf/closed/wall, -/area/mine/mechbay) "VO" = ( /obj/machinery/power/apc/auto_name/directional/south, /obj/structure/cable, @@ -43033,8 +43025,8 @@ iu pU aj aj -FH -BW +Zq +SP Zq kK Sm @@ -43804,8 +43796,8 @@ ZM ZM LB Ke -FH -BW +Zq +SP Zq Zq bL @@ -45846,7 +45838,7 @@ oA oA oA Vn -VL +QX QX vF QX diff --git a/_maps/map_files/NebulaStation/NebulaStation.dmm b/_maps/map_files/NebulaStation/NebulaStation.dmm index f1cc6623b14f..a56ce903b0c0 100644 --- a/_maps/map_files/NebulaStation/NebulaStation.dmm +++ b/_maps/map_files/NebulaStation/NebulaStation.dmm @@ -21177,6 +21177,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 @@ -30596,9 +30603,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 @@ -30609,6 +30613,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" = ( @@ -38567,6 +38572,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, @@ -42767,9 +42781,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" = ( @@ -45427,6 +45439,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) @@ -49658,6 +49678,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, @@ -57461,6 +57491,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" = ( @@ -63701,10 +63734,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 @@ -64466,17 +64495,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" = ( @@ -67090,7 +67112,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" = ( @@ -75875,6 +75897,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" = ( @@ -78651,6 +78676,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" = ( @@ -78692,14 +78718,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 }, @@ -83015,6 +83033,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"; @@ -85294,16 +85321,16 @@ /turf/open/floor/iron/white, /area/station/science/lab) "mFl" = ( -/obj/machinery/mining_weather_monitor/directional/east, -/obj/machinery/conveyor{ - id = "mining" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 +/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/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 @@ -86486,14 +86513,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" = ( @@ -88140,6 +88159,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 @@ -90036,6 +90058,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{ @@ -91609,7 +91645,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 }, @@ -92176,6 +92212,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, @@ -92702,6 +92746,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, @@ -96954,6 +97006,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, @@ -96968,6 +97028,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 @@ -105822,6 +105886,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 }, @@ -107299,11 +107364,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) @@ -108268,6 +108330,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{ @@ -110823,7 +110893,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, @@ -113518,7 +113588,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" = ( @@ -125854,6 +125924,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 @@ -127914,6 +127993,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, @@ -133443,6 +133529,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, @@ -140684,6 +140783,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 @@ -141756,6 +141863,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 @@ -142095,6 +142206,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 = 4 + }, +/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{ @@ -151845,6 +151965,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, @@ -153830,6 +153958,15 @@ }, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) +"wLi" = ( +/obj/machinery/bouldertech/refinery{ + dir = 4 + }, +/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, @@ -155669,11 +155806,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, @@ -156149,7 +156282,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{ @@ -161349,7 +161481,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 +161490,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 +194501,7 @@ gym fDY gJT cGO -juB +vNT lhE xeX jzQ @@ -194620,11 +194754,11 @@ gym gym gym gym -gym -gym gJT +rWS +fDY cGO -vNT +tHC xSw lCS xbk @@ -194877,11 +195011,11 @@ gym gym gym gym -gym -gym -fDY -bPw -bPw +rWS +nbS +oqM +nbS +nbS mFl pOD mOI @@ -195133,13 +195267,13 @@ gym gym gym gym -gym -gym -gym -gJT +dew gJT -bPw -bPw +nbS +oqz +nrD +wvQ +sDq kFj kFj kFj @@ -195391,13 +195525,13 @@ gym gym gym gym -gym -gym -gym -gym -ihJ -gJT -kFj +rWS +oqM +sTD +mmF +fIR +hoC +uWr grQ dsJ dec @@ -195647,13 +195781,13 @@ gym gym gym gym -gym -gym -gym -gym -gym -ihJ +dew rnW +nbS +pVC +wLi +uYW +uOS kFj tqY xsP @@ -195905,12 +196039,12 @@ gym gym gym gym -gym -gym -gym -gym -ihJ -gJT +rWS +nbS +nIe +gIP +dgS +nMH kFj ttj qwk @@ -196163,7 +196297,7 @@ gym gym gJT fDY -gJT +ewt oZM oZM oZM @@ -196420,7 +196554,7 @@ gym gJT nnP nnP -nnP +oZM oZM vxf rEU diff --git a/_maps/map_files/Vampire/runtimetown.dmm b/_maps/map_files/Vampire/runtimetown.dmm index 523885161ce3..5f3288e3573b 100644 --- a/_maps/map_files/Vampire/runtimetown.dmm +++ b/_maps/map_files/Vampire/runtimetown.dmm @@ -45,6 +45,13 @@ /obj/structure/roadsign/crosswalk, /turf/open/floor/plating/sidewalk/poor, /area/vtm/outside/pacificheights) +"bs" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/abstract/cargo_landing_spot, +/turf/open/misc/dirt, +/area/vtm/outside/supply) "bB" = ( /obj/structure/chair/wood/darkpack/red, /turf/open/floor/plating/rough, @@ -354,7 +361,6 @@ /obj/effect/decal/cleanable/trash{ icon_state = "trash5" }, -/obj/effect/spawner/random/occult/artifact, /turf/open/floor/wood/smooth/old, /area/vtm/interior/sewer) "hK" = ( @@ -400,7 +406,7 @@ /turf/closed/wall/vampwall/painted, /area/vtm/interior/shop) "iJ" = ( -/obj/effect/spawner/random/occult/artifact, +/mob/living/basic/pet/cat/darkpack/cain, /turf/open/floor/wood/smooth/old, /area/vtm/interior/sewer) "iK" = ( @@ -483,6 +489,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 5 }, +/obj/effect/abstract/cargo_landing_spot, /turf/open/misc/dirt, /area/vtm/outside/supply) "jQ" = ( @@ -593,7 +600,6 @@ /area/vtm/interior/techshop) "lM" = ( /obj/effect/decal/cleanable/trash, -/obj/effect/spawner/random/occult/artifact, /turf/open/floor/wood/smooth/old, /area/vtm/interior/sewer) "lN" = ( @@ -601,7 +607,10 @@ /area/vtm/outside/supply) "lU" = ( /obj/structure/table/wood, -/obj/item/vtm_artifact/key_of_alamut, +/obj/item/occult_artifact/vampire/key_of_alamut{ + pixel_x = -2; + pixel_y = 3 + }, /turf/open/floor/wood/smooth/old, /area/vtm/interior/sewer) "lX" = ( @@ -611,6 +620,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 10 }, +/obj/effect/abstract/cargo_landing_spot, /turf/open/misc/dirt, /area/vtm/outside/supply) "md" = ( @@ -875,7 +885,14 @@ /area/vtm/outside/pacificheights) "qY" = ( /obj/structure/table/wood, -/obj/item/vtm_artifact/bloodstar, +/obj/item/occult_artifact/vampire/bloodstone{ + pixel_x = 9; + pixel_y = 5 + }, +/obj/item/occult_artifact/vampire/daimonori{ + pixel_x = -5; + pixel_y = 4 + }, /turf/open/floor/wood/smooth/old, /area/vtm/interior/sewer) "ri" = ( @@ -1162,7 +1179,15 @@ /area/vtm/graveyard) "va" = ( /obj/structure/table/wood, -/obj/item/vtm_artifact/fae_charm, +/obj/effect/spawner/random/occult/artifact/werewolf_only{ + pixel_y = 4 + }, +/obj/effect/spawner/random/occult/artifact/werewolf_only{ + pixel_x = -6 + }, +/obj/effect/spawner/random/occult/artifact/werewolf_only{ + pixel_x = 7 + }, /turf/open/floor/wood/smooth/old, /area/vtm/interior/sewer) "vi" = ( @@ -1241,7 +1266,14 @@ /area/vtm/outside/supply) "wr" = ( /obj/structure/table/wood, -/obj/item/vtm_artifact/odious_chalice, +/obj/item/occult_artifact/vampire/odious_chalice{ + pixel_x = -3; + pixel_y = 7 + }, +/obj/item/occult_artifact/vampire/bloodstar{ + pixel_x = 12; + pixel_y = 4 + }, /turf/open/floor/wood/smooth/old, /area/vtm/interior/sewer) "wO" = ( @@ -1401,7 +1433,10 @@ /area/vtm/outside/pacificheights) "zF" = ( /obj/structure/table/wood, -/obj/item/vtm_artifact/weekapaug_thistle, +/obj/item/occult_artifact/vampire/weekapaug_thistle{ + pixel_x = -1; + pixel_y = 2 + }, /obj/machinery/light/directional/north, /turf/open/floor/wood/smooth/old, /area/vtm/interior/sewer) @@ -1645,6 +1680,11 @@ }, /turf/open/floor/plating/sidewalk, /area/vtm/interior/cog) +"DS" = ( +/obj/effect/decal/pallet, +/obj/effect/abstract/cargo_landing_spot, +/turf/open/misc/dirt, +/area/vtm/outside/supply) "DT" = ( /obj/machinery/fax/endron, /obj/structure/table/wood, @@ -2098,7 +2138,14 @@ /area/vtm/outside/supply) "Kz" = ( /obj/structure/table/wood, -/obj/item/vtm_artifact/heart_of_eliza, +/obj/item/occult_artifact/vampire/heart_of_eliza{ + pixel_x = -5; + pixel_y = 5 + }, +/obj/item/occult_artifact/vampire/fae_charm{ + pixel_x = 7; + pixel_y = 7 + }, /turf/open/floor/wood/smooth/old, /area/vtm/interior/sewer) "KB" = ( @@ -2174,9 +2221,21 @@ }, /turf/open/floor/plating/asphalt, /area/vtm/outside/pacificheights) +"LC" = ( +/obj/effect/turf_decal/stripes/line, +/obj/effect/abstract/cargo_landing_spot, +/turf/open/misc/dirt, +/area/vtm/outside/supply) "LG" = ( /obj/structure/table/wood, -/obj/item/vtm_artifact/daimonori, +/obj/item/occult_artifact/werewolf/dagger_of_retribution{ + pixel_x = -2; + pixel_y = 1 + }, +/obj/item/occult_artifact/werewolf/nyxs_bangle{ + pixel_x = 6; + pixel_y = 6 + }, /turf/open/floor/wood/smooth/old, /area/vtm/interior/sewer) "LL" = ( @@ -2299,8 +2358,10 @@ /area/vtm/outside/pacificheights) "Nb" = ( /obj/structure/table/wood, -/obj/item/vtm_artifact/tarulfang, -/mob/living/basic/pet/cat/darkpack/cain, +/obj/item/occult_artifact/vampire/tarulfang{ + pixel_x = 4; + pixel_y = 5 + }, /turf/open/floor/wood/smooth/old, /area/vtm/interior/sewer) "Nd" = ( @@ -2552,6 +2613,8 @@ "QD" = ( /obj/machinery/light/directional/north, /obj/effect/decal/cleanable/trash, +/obj/effect/spawner/random/occult/artifact, +/obj/ritual_rune/thaumaturgy/identification, /turf/open/floor/wood/smooth/old, /area/vtm/interior/sewer) "QJ" = ( @@ -2567,7 +2630,6 @@ /area/vtm/outside/pacificheights) "QN" = ( /obj/effect/decal/cleanable/litter, -/obj/effect/spawner/random/occult/artifact, /turf/open/floor/wood/smooth/old, /area/vtm/interior/sewer) "QR" = ( @@ -2638,7 +2700,6 @@ /obj/effect/decal/cleanable/trash{ icon_state = "trash7" }, -/obj/effect/spawner/random/occult/artifact, /turf/open/floor/wood/smooth/old, /area/vtm/interior/sewer) "RV" = ( @@ -2824,7 +2885,10 @@ /area/vtm/outside/pacificheights) "VH" = ( /obj/structure/table/wood, -/obj/item/vtm_artifact/galdjum, +/obj/item/occult_artifact/vampire/galdjum{ + pixel_x = 5; + pixel_y = 2 + }, /turf/open/floor/wood/smooth/old, /area/vtm/interior/sewer) "VJ" = ( @@ -2903,11 +2967,23 @@ /area/vtm/interior/clinic) "WB" = ( /obj/structure/table/wood, -/obj/item/vtm_artifact/mummywrap_fetish, +/obj/item/occult_artifact/vampire/mummywrap_fetish{ + pixel_x = -6; + pixel_y = 3 + }, /turf/open/floor/wood/smooth/old, /area/vtm/interior/sewer) "WD" = ( /obj/structure/table/reinforced, +/obj/effect/spawner/random/occult/artifact/vampire_only, +/obj/effect/spawner/random/occult/artifact/vampire_only{ + pixel_x = 7; + pixel_y = -3 + }, +/obj/effect/spawner/random/occult/artifact/vampire_only{ + pixel_x = -9; + pixel_y = -2 + }, /turf/open/floor/wood/smooth/old, /area/vtm/interior/sewer) "WH" = ( @@ -3059,7 +3135,17 @@ /area/vtm/outside/pacificheights) "YY" = ( /obj/structure/table/reinforced, -/obj/item/ritual_tome/arcane, +/obj/item/ritual_tome/arcane{ + pixel_y = 6 + }, +/obj/item/ritual_tome/necromancy{ + pixel_x = -4; + pixel_y = 2 + }, +/obj/item/ritual_tome/abyss{ + pixel_x = 4; + pixel_y = 2 + }, /turf/open/floor/wood/smooth/old, /area/vtm/interior/sewer) "Zc" = ( @@ -3252,7 +3338,7 @@ GF (3,1,1) = {" GF Ef -qY +zM LG va zM @@ -3456,9 +3542,9 @@ GF (6,1,1) = {" GF Ef -zM +qY RP -iJ +zd lU Ef JH @@ -3525,7 +3611,7 @@ GF GF Ef Nb -iJ +zd QN WB Ef @@ -3593,8 +3679,8 @@ GF GF Ef zF -iJ -iJ +zd +zd zd OP PO @@ -6337,7 +6423,7 @@ HJ Fs Wa Wa -Mn +bs Lb kj Wa @@ -6405,7 +6491,7 @@ ik Fs Wa Wa -Mn +bs Lb kj Wa @@ -6475,7 +6561,7 @@ Wa Wa Mn Lb -kj +LC Wa Lb Wa @@ -6543,7 +6629,7 @@ Wa Wa Mn Lb -kj +LC Wa Lb sR @@ -6816,7 +6902,7 @@ Wa Wa Lb Wa -sR +DS Lb Wa Wa @@ -6884,7 +6970,7 @@ Wa Wa Lb Wa -sR +DS Lb Wa Wa diff --git a/_maps/map_files/Vampire/special_fran/special_francisco.dmm b/_maps/map_files/Vampire/special_fran/special_francisco.dmm index b48337da4ffe..d529a094cc7e 100644 --- a/_maps/map_files/Vampire/special_fran/special_francisco.dmm +++ b/_maps/map_files/Vampire/special_fran/special_francisco.dmm @@ -17005,7 +17005,7 @@ "jQQ" = ( /obj/structure/table/modern, /obj/effect/turf_decal/siding/white/end, -/obj/item/vtm_artifact/heart_of_eliza{ +/obj/item/occult_artifact/vampire/heart_of_eliza{ anchored = 1 }, /turf/open/floor/plating/granite/black, @@ -33377,7 +33377,7 @@ /obj/effect/turf_decal/siding/white{ dir = 8 }, -/obj/item/vtm_artifact/fae_charm{ +/obj/item/occult_artifact/vampire/fae_charm{ anchored = 1 }, /turf/open/floor/plating/granite/black, diff --git a/_maps/map_files/Vampire/westfield_mall/westfield_mall.dmm b/_maps/map_files/Vampire/westfield_mall/westfield_mall.dmm index a8ab591c1819..fd44ab2adb89 100644 --- a/_maps/map_files/Vampire/westfield_mall/westfield_mall.dmm +++ b/_maps/map_files/Vampire/westfield_mall/westfield_mall.dmm @@ -10389,6 +10389,7 @@ /area/vtm/interior/sewer/nosferatu_town) "aIg" = ( /obj/effect/turf_decal/loading_area, +/obj/effect/abstract/cargo_landing_spot, /turf/open/misc/dirt, /area/vtm/westfield_mall/interior/supply) "aIh" = ( @@ -17832,6 +17833,10 @@ /obj/effect/decal/rugs, /turf/open/floor/iron/dark, /area/vtm/westfield_mall/interior/art_store) +"rtM" = ( +/obj/effect/abstract/cargo_landing_spot, +/turf/open/floor/plating/concrete, +/area/vtm/westfield_mall/interior/supply) "rus" = ( /obj/machinery/sprinkler, /turf/open/floor/wood/smooth/old, @@ -17909,6 +17914,11 @@ }, /turf/open/floor/plating/roofwalk, /area/vtm/westfield_mall) +"rSA" = ( +/obj/effect/decal/pallet, +/obj/effect/abstract/cargo_landing_spot, +/turf/open/floor/plating/concrete, +/area/vtm/westfield_mall/interior/supply) "rSN" = ( /obj/effect/turf_decal/bordur{ dir = 8 @@ -26043,11 +26053,11 @@ aFc (49,1,1) = {" aFc aOe -ars +rtM aZf aaV aZf -ars +rtM agx ars aNJ @@ -27263,7 +27273,7 @@ ars aZf aaV aZf -aiq +rSA aOe aeW aVT @@ -28171,7 +28181,7 @@ aFc (63,1,1) = {" aFc aOe -aiq +rSA aZf aaV aZf @@ -28783,7 +28793,7 @@ ars aZf aaV aZf -aiq +rSA aOe aeW aeW @@ -29999,7 +30009,7 @@ ars aZf aaV aIg -ars +rtM apX aOe aeW @@ -30151,7 +30161,7 @@ ars aZf aaV aIg -ars +rtM apX aOe aeW @@ -30455,7 +30465,7 @@ ars aXD aaV aZf -aiq +rSA aOe aeW aeW @@ -30907,7 +30917,7 @@ aFc (81,1,1) = {" aFc aOe -aiq +rSA aZf aaV aZf @@ -31667,7 +31677,7 @@ aFc (86,1,1) = {" aFc aOe -ars +rtM aZf aaV aZf @@ -32579,7 +32589,7 @@ aFc (92,1,1) = {" aFc aOe -ars +rtM aZf aaV aZf @@ -32731,7 +32741,7 @@ aFc (93,1,1) = {" aFc aOe -ars +rtM aZf aaV aZf diff --git a/_maps/map_files/debug/runtimestation.dmm b/_maps/map_files/debug/runtimestation.dmm index 66baca7acb26..9779a6622eec 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 a7879a5a0731..5e4af937de03 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 = 12 + pixel_y = 13 }, /obj/item/bodybag/environmental/nanotrasen{ pixel_x = 7; - pixel_y = 6 + pixel_y = 7 }, /obj/item/bodybag/environmental/nanotrasen{ - pixel_x = 7 + pixel_x = 7; + pixel_y = 1 }, -/turf/open/floor/iron, +/obj/item/storage/medkit/advanced{ + pixel_y = 7; + pixel_x = -12 + }, +/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, +/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/stripes/line{ - dir = 6 - }, +/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/item/cigarette/cigar/cohiba{ - pixel_x = 6 +/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/havana{ - pixel_x = 2 +/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/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/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, +/obj/machinery/door/airlock/centcom{ + name = "Administrative Office" + }, +/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/clipboard{ + pixel_x = -4; + pixel_y = 3 + }, +/obj/item/folder/red{ + pixel_x = -4; + pixel_y = 2 + }, /obj/item/stamp/denied{ - pixel_x = 3; + pixel_x = 9; pixel_y = 3 }, -/obj/item/stamp/granted, +/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 1d4036882789..20f1addfff1f 100644 --- a/_maps/map_files/tramstation/tramstation.dmm +++ b/_maps/map_files/tramstation/tramstation.dmm @@ -1119,7 +1119,7 @@ /turf/open/floor/iron, /area/station/security/courtroom) "adD" = ( -/mob/living/simple_animal/bot/secbot/beepsky/officer, +/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{ @@ -1526,7 +1526,7 @@ /turf/open/misc/asteroid/airless, /area/station/asteroid) "aeX" = ( -/mob/living/simple_animal/bot/secbot/beepsky/armsky, +/mob/living/basic/bot/secbot/beepsky/armsky, /obj/effect/turf_decal/stripes/line, /obj/structure/cable, /turf/open/floor/iron, @@ -2338,7 +2338,9 @@ "ajn" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/decal/cleanable/dirt, -/obj/structure/railing, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/iron, /area/station/cargo/miningfoundry) "ajo" = ( @@ -9859,8 +9861,8 @@ /area/station/hallway/secondary/service) "cqj" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/railing/corner/end{ - dir = 4 +/obj/effect/turf_decal/stripes/line{ + dir = 1 }, /turf/open/floor/iron, /area/station/cargo/miningfoundry) @@ -11986,8 +11988,12 @@ /turf/open/floor/plating, /area/station/engineering/atmos) "cZQ" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/conveyor{ + dir = 8; + id = "mining" + }, +/obj/structure/railing/corner/end/flip{ + dir = 8 }, /turf/open/floor/iron, /area/station/cargo/miningfoundry) @@ -12242,10 +12248,8 @@ /area/station/security/prison/safe) "ddY" = ( /obj/structure/sign/poster/official/jim_nortons/directional/north, -/obj/machinery/conveyor{ - dir = 8; - id = "mining" - }, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/iron, /area/station/cargo/miningfoundry) "dec" = ( @@ -14728,7 +14732,7 @@ /turf/open/floor/iron/white, /area/station/medical/medbay/central) "dWi" = ( -/mob/living/simple_animal/bot/secbot/beepsky, +/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, @@ -22831,7 +22835,7 @@ /turf/open/floor/iron, /area/station/engineering/atmos) "gWx" = ( -/mob/living/simple_animal/bot/secbot/pingsky{ +/mob/living/basic/bot/secbot/pingsky{ dir = 1 }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -28642,6 +28646,14 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/wood, /area/station/commons/vacant_room/office) +"jfP" = ( +/obj/structure/closet/crate, +/obj/item/stack/ducts{ + amount = 5 + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "jfU" = ( /obj/machinery/door/airlock/hatch{ name = "Secure Pen" @@ -29404,11 +29416,9 @@ /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, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/iron, /area/station/cargo/miningfoundry) "jsy" = ( @@ -29703,8 +29713,8 @@ /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 +/obj/effect/turf_decal/stripes/line{ + dir = 1 }, /turf/open/floor/iron, /area/station/cargo/miningfoundry) @@ -32955,9 +32965,10 @@ /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 +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/conveyor{ + dir = 8; + id = "mining" }, /turf/open/floor/iron, /area/station/cargo/miningfoundry) @@ -38049,8 +38060,8 @@ /area/station/security/courtroom) "meg" = ( /obj/machinery/light/small/directional/west, -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/structure/railing/corner/end{ + dir = 4 }, /turf/open/floor/iron, /area/station/cargo/miningfoundry) @@ -38695,10 +38706,9 @@ /turf/open/floor/iron, /area/station/hallway/secondary/entry) "mqT" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /obj/effect/decal/cleanable/dirt, +/obj/machinery/bouldertech/refinery/smelter, +/obj/structure/railing, /turf/open/floor/iron, /area/station/cargo/miningfoundry) "mrf" = ( @@ -40074,7 +40084,6 @@ /area/station/medical/psychology) "mTg" = ( /obj/effect/decal/cleanable/rubble, -/obj/structure/closet/crate, /turf/open/floor/iron, /area/station/cargo/miningfoundry) "mTh" = ( @@ -41705,6 +41714,10 @@ /area/station/hallway/secondary/exit) "nxN" = ( /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) "nxT" = ( @@ -43077,7 +43090,9 @@ "nXb" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/railing, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/iron, /area/station/cargo/miningfoundry) "nXh" = ( @@ -49931,11 +49946,7 @@ /turf/closed/wall, /area/station/command/heads_quarters/qm) "qzh" = ( -/obj/machinery/bouldertech/refinery/smelter, -/obj/machinery/conveyor{ - dir = 8; - id = "mining" - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/iron, /area/station/cargo/miningfoundry) "qzn" = ( @@ -50592,6 +50603,15 @@ /obj/item/paper/monitorkey, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/ce) +"qLx" = ( +/obj/machinery/bouldertech/refinery, +/obj/machinery/conveyor{ + dir = 8; + id = "mining" + }, +/obj/structure/railing, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "qLD" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -50680,10 +50700,8 @@ /area/station/science/ordnance/testlab) "qMI" = ( /obj/machinery/light/warm/directional/north, -/obj/machinery/conveyor{ - dir = 8; - id = "mining" - }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/iron, /area/station/cargo/miningfoundry) "qMQ" = ( @@ -54713,14 +54731,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 @@ -55818,6 +55828,7 @@ /obj/effect/turf_decal/tile/brown/opposingcorners{ dir = 1 }, +/obj/effect/decal/cleanable/greenglow/waste, /turf/open/floor/iron, /area/station/cargo/miningfoundry) "szs" = ( @@ -65105,12 +65116,9 @@ /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" - }, +/obj/effect/mapping_helpers/burnt_floor, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/iron, /area/station/cargo/miningfoundry) "vFh" = ( @@ -69032,11 +69040,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 @@ -69141,6 +69144,16 @@ /obj/structure/cable, /turf/open/floor/iron/dark, /area/station/ai/satellite/maintenance) +"xeV" = ( +/obj/machinery/conveyor{ + dir = 8; + id = "mining" + }, +/obj/structure/railing/corner/end{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/miningfoundry) "xfd" = ( /obj/effect/turf_decal/trimline/red/filled/corner, /obj/effect/turf_decal/trimline/red/filled/corner{ @@ -118588,8 +118601,8 @@ aac aaa xdZ qMI -cZQ -xcU +xeV +cqj sfn njK xiZ @@ -118844,9 +118857,9 @@ aac aaa aaa xdZ -siF -cZQ -xcU +qzh +qLx +cqj goY njK flZ @@ -119102,8 +119115,8 @@ aaa aaa xdZ jsx -mqT -xcU +cZQ +cqj eAV qxG unl @@ -119615,8 +119628,8 @@ aac aaa aaa xdZ +jfP fdc -cZQ jwy sUC pIF diff --git a/_maps/map_files/wawastation/wawastation.dmm b/_maps/map_files/wawastation/wawastation.dmm index 4ee2d9a6ad03..403a0404252c 100644 --- a/_maps/map_files/wawastation/wawastation.dmm +++ b/_maps/map_files/wawastation/wawastation.dmm @@ -491,6 +491,12 @@ /obj/item/radio/intercom/directional/north, /turf/open/floor/iron, /area/station/cargo/storage) +"ahX" = ( +/obj/structure/sign/warning/directional/west, +/turf/closed/mineral/random/stationside/asteroid/porus{ + mineral_chance = 20 + }, +/area/station/asteroid) "aic" = ( /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -810,7 +816,7 @@ dir = 5 }, /obj/machinery/camera/autoname/directional/east, -/mob/living/simple_animal/bot/secbot/pingsky, +/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, @@ -837,6 +843,11 @@ /obj/structure/grille/broken, /turf/open/floor/plating/reinforced/airless, /area/station/asteroid) +"anz" = ( +/turf/closed/mineral/random/stationside/asteroid/porus{ + mineral_chance = 20 + }, +/area/station/maintenance/department/science) "anJ" = ( /obj/effect/landmark/event_spawn, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, @@ -946,11 +957,6 @@ }, /turf/open/floor/iron/dark/textured, /area/station/medical/morgue) -"apr" = ( -/turf/closed/mineral/random/stationside/asteroid/porus{ - mineral_chance = 20 - }, -/area/station/maintenance/department/medical) "apt" = ( /obj/structure/rack, /obj/item/stack/sheet/glass{ @@ -4788,12 +4794,6 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos/upper) -"bGz" = ( -/obj/item/reagent_containers/cup/bottle/fake_gbs, -/turf/closed/mineral/random/stationside/asteroid/porus{ - mineral_chance = 20 - }, -/area/station/asteroid) "bGD" = ( /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -4957,6 +4957,11 @@ /obj/machinery/door/window/right/directional/west, /turf/open/floor/grass, /area/station/service/hydroponics/garden) +"bIS" = ( +/turf/closed/mineral/random/stationside/asteroid/porus{ + mineral_chance = 20 + }, +/area/station/maintenance/port/greater) "bJo" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/kitchen, @@ -5017,6 +5022,11 @@ /obj/effect/turf_decal/tile/neutral/opposingcorners, /turf/open/floor/iron/dark, /area/station/security/courtroom) +"bLu" = ( +/obj/effect/turf_decal/sand/plating, +/obj/machinery/light/small/directional/north, +/turf/open/misc/asteroid, +/area/station/cargo/miningoffice) "bLI" = ( /obj/effect/turf_decal/bot_red, /obj/effect/turf_decal/stripes/line, @@ -5752,7 +5762,7 @@ /area/station/service/lawoffice) "bZI" = ( /obj/effect/turf_decal/bot, -/mob/living/simple_animal/bot/secbot/beepsky/armsky, +/mob/living/basic/bot/secbot/beepsky/armsky, /obj/effect/landmark/event_spawn, /turf/open/floor/iron/dark/textured_large, /area/station/security/armory) @@ -5824,15 +5834,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 @@ -10991,11 +10992,6 @@ /obj/structure/barricade/wooden, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) -"dQq" = ( -/turf/closed/mineral/random/stationside/asteroid/porus{ - mineral_chance = 20 - }, -/area/station/hallway/secondary/entry) "dQr" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/iron/dark/textured, @@ -15876,20 +15872,6 @@ /obj/structure/disposalpipe/trunk/multiz, /turf/open/floor/iron, /area/station/security) -"fCU" = ( -/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) "fCY" = ( /obj/effect/turf_decal/tile/dark_blue/anticorner/contrasted{ dir = 8 @@ -16096,10 +16078,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, @@ -22057,12 +22035,6 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/commons/dorms) -"hFT" = ( -/obj/structure/sign/warning/directional/east, -/turf/closed/mineral/random/stationside/asteroid/porus{ - mineral_chance = 20 - }, -/area/station/asteroid) "hFY" = ( /obj/effect/turf_decal/tile/purple{ dir = 8 @@ -22475,6 +22447,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, @@ -23100,6 +23088,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/construction/mining/aux_base) +"hXH" = ( +/obj/effect/decal/cleanable/rubble, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating, +/area/station/cargo/miningoffice) "hXK" = ( /obj/structure/closet/cardboard, /obj/effect/turf_decal/stripes/line, @@ -23271,12 +23264,6 @@ }, /turf/open/floor/iron/freezer, /area/station/security/prison/shower) -"ibw" = ( -/obj/structure/sign/warning/directional/south, -/turf/closed/mineral/random/stationside/asteroid/porus{ - mineral_chance = 20 - }, -/area/station/asteroid) "ibx" = ( /obj/effect/turf_decal/sand/plating, /turf/open/floor/plating, @@ -23788,13 +23775,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, @@ -24382,6 +24362,11 @@ dir = 1 }, /area/station/engineering/atmos) +"iwP" = ( +/turf/closed/mineral/random/stationside/asteroid/porus{ + mineral_chance = 20 + }, +/area/station/hallway/secondary/entry) "iwQ" = ( /obj/effect/turf_decal/tile/dark_red/opposingcorners, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -24554,6 +24539,10 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/hallway/primary/central) +"izF" = ( +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating, +/area/station/cargo/miningoffice) "izP" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable, @@ -26222,11 +26211,6 @@ }, /turf/open/floor/iron, /area/station/security/execution/transfer) -"jfO" = ( -/turf/closed/mineral/random/stationside/asteroid/porus{ - mineral_chance = 20 - }, -/area/station/maintenance/port/greater) "jge" = ( /obj/effect/spawner/random/structure/crate, /obj/item/clothing/glasses/meson, @@ -27029,11 +27013,6 @@ /obj/effect/landmark/start/assistant, /turf/open/floor/iron, /area/station/commons/fitness/recreation) -"jsy" = ( -/turf/closed/mineral/random/stationside/asteroid/porus{ - mineral_chance = 20 - }, -/area/station/maintenance/central/greater) "jsC" = ( /turf/closed/wall/r_wall, /area/station/maintenance/department/medical/central) @@ -27045,6 +27024,11 @@ /obj/machinery/firealarm/directional/north, /turf/open/floor/iron/dark, /area/station/engineering/supermatter/room) +"jsO" = ( +/turf/closed/mineral/random/stationside/asteroid/porus{ + mineral_chance = 20 + }, +/area/station/maintenance/department/medical) "jsU" = ( /obj/effect/turf_decal/trimline/dark_blue/filled/corner{ dir = 1 @@ -31921,6 +31905,17 @@ /obj/machinery/door/firedoor/heavy, /turf/open/floor/plating, /area/station/science/breakroom) +"kVS" = ( +/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) "kVX" = ( /obj/structure/closet/secure_closet/miner, /obj/effect/turf_decal/tile/brown/anticorner/contrasted{ @@ -33488,11 +33483,6 @@ "lyN" = ( /turf/open/openspace, /area/station/engineering/lobby) -"lyP" = ( -/turf/closed/mineral/random/stationside/asteroid/porus{ - mineral_chance = 20 - }, -/area/station/asteroid) "lyQ" = ( /obj/effect/turf_decal/stripes/corner{ dir = 1 @@ -33837,6 +33827,11 @@ }, /turf/open/floor/iron/dark/smooth_large, /area/station/ai/satellite/interior) +"lEj" = ( +/turf/closed/mineral/random/stationside/asteroid/porus{ + mineral_chance = 20 + }, +/area/station/asteroid) "lEu" = ( /obj/structure/railing/corner{ dir = 4 @@ -34832,11 +34827,6 @@ dir = 1 }, /area/station/engineering/atmos/mix) -"lWq" = ( -/turf/closed/mineral/random/stationside/asteroid/porus{ - mineral_chance = 20 - }, -/area/station/maintenance/department/cargo) "lWF" = ( /obj/structure/table/wood, /obj/item/paper_bin, @@ -36223,6 +36213,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, @@ -36404,6 +36408,12 @@ /obj/machinery/door/firedoor, /turf/open/floor/iron/showroomfloor, /area/station/engineering/main) +"mxf" = ( +/obj/structure/sign/warning/directional/east, +/turf/closed/mineral/random/stationside/asteroid/porus{ + mineral_chance = 20 + }, +/area/station/asteroid) "mxh" = ( /obj/item/radio/intercom/directional/east, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ @@ -37487,6 +37497,11 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/wood, /area/station/commons/lounge) +"mRE" = ( +/obj/effect/turf_decal/sand/plating, +/obj/machinery/light/small/directional/north, +/turf/open/floor/plating, +/area/station/cargo/miningoffice) "mRI" = ( /obj/effect/mob_spawn/corpse/human/clown, /turf/open/misc/asteroid, @@ -37644,6 +37659,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 @@ -38487,6 +38518,12 @@ }, /turf/open/floor/engine, /area/station/hallway/secondary/entry) +"nho" = ( +/obj/structure/sign/warning/directional/south, +/turf/closed/mineral/random/stationside/asteroid/porus{ + mineral_chance = 20 + }, +/area/station/asteroid) "nhC" = ( /obj/effect/turf_decal/tile/neutral, /obj/structure/cable, @@ -39217,15 +39254,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 @@ -39642,11 +39670,6 @@ /obj/machinery/firealarm/directional/east, /turf/open/floor/iron, /area/station/security/office) -"nGi" = ( -/turf/closed/mineral/random/stationside/asteroid/porus{ - mineral_chance = 20 - }, -/area/station/maintenance/disposal/incinerator) "nGp" = ( /obj/machinery/camera/directional/west{ c_tag = "Atmospherics Tank - Carbon Dioxide" @@ -40365,6 +40388,12 @@ /obj/item/radio/intercom/directional/south, /turf/open/floor/iron/kitchen_coldroom, /area/station/medical/coldroom) +"nTN" = ( +/obj/item/reagent_containers/cup/bottle/fake_gbs, +/turf/closed/mineral/random/stationside/asteroid/porus{ + mineral_chance = 20 + }, +/area/station/asteroid) "nTQ" = ( /obj/effect/turf_decal/trimline/yellow/filled/corner{ dir = 1 @@ -40632,22 +40661,6 @@ /obj/structure/reagent_dispensers/watertank, /turf/open/floor/plating, /area/station/maintenance/central/lesser) -"oab" = ( -/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) "oac" = ( /obj/machinery/mecha_part_fabricator{ drop_direction = 1 @@ -40687,6 +40700,11 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos/upper) +"oaD" = ( +/turf/closed/mineral/random/stationside/asteroid/porus{ + mineral_chance = 20 + }, +/area/station/maintenance/department/cargo) "oaF" = ( /obj/effect/spawner/structure/window/hollow/reinforced/middle{ dir = 4 @@ -43682,6 +43700,22 @@ }, /turf/open/floor/iron/large, /area/station/hallway/secondary/exit/departure_lounge) +"pdj" = ( +/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) "pdo" = ( /obj/structure/cable/multilayer/multiz, /turf/open/floor/glass, @@ -43690,22 +43724,6 @@ /obj/effect/turf_decal/siding/wood, /turf/open/floor/wood/tile, /area/station/service/bar) -"pdt" = ( -/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) "pdx" = ( /obj/effect/turf_decal/trimline/blue/filled/line, /obj/item/radio/intercom/directional/south, @@ -44263,6 +44281,11 @@ "pog" = ( /turf/open/floor/iron/dark, /area/station/ai/satellite/teleporter) +"poh" = ( +/turf/closed/mineral/random/stationside/asteroid/porus{ + mineral_chance = 20 + }, +/area/station/maintenance/disposal/incinerator) "poi" = ( /turf/closed/wall, /area/station/maintenance/department/cargo) @@ -44980,12 +45003,6 @@ dir = 1 }, /area/station/medical/exam_room) -"pzu" = ( -/obj/structure/sign/warning/directional/west, -/turf/closed/mineral/random/stationside/asteroid/porus{ - mineral_chance = 20 - }, -/area/station/asteroid) "pzw" = ( /obj/machinery/door/airlock/maintenance/external, /obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance, @@ -47584,6 +47601,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 @@ -48939,12 +48970,6 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating/airless, /area/station/solars/starboard/fore) -"qSf" = ( -/obj/structure/sign/warning/directional/north, -/turf/closed/mineral/random/stationside/asteroid/porus{ - mineral_chance = 20 - }, -/area/station/asteroid) "qSg" = ( /obj/machinery/newscaster/directional/north, /obj/structure/disposalpipe/segment{ @@ -51406,7 +51431,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 1 }, -/mob/living/simple_animal/bot/secbot/beepsky/officer, +/mob/living/basic/bot/secbot/beepsky/officer, /turf/open/floor/iron, /area/station/hallway/primary/central) "rFX" = ( @@ -55107,6 +55132,11 @@ /obj/item/stamp/head/hop, /turf/open/floor/carpet/green, /area/station/command/heads_quarters/hop) +"sPy" = ( +/turf/closed/mineral/random/stationside/asteroid/porus{ + mineral_chance = 20 + }, +/area/station/maintenance/central/greater) "sPC" = ( /obj/effect/turf_decal/trimline/blue/filled/line, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ @@ -57681,6 +57711,12 @@ /obj/machinery/digital_clock/directional/south, /turf/open/floor/iron, /area/station/hallway/primary/central) +"tJk" = ( +/obj/structure/sign/warning/directional/north, +/turf/closed/mineral/random/stationside/asteroid/porus{ + mineral_chance = 20 + }, +/area/station/asteroid) "tJx" = ( /obj/structure/chair/plastic{ dir = 4 @@ -60721,6 +60757,11 @@ "uKm" = ( /turf/closed/wall, /area/station/asteroid) +"uKu" = ( +/turf/closed/mineral/random/stationside/asteroid/porus{ + mineral_chance = 20 + }, +/area/station/cargo/miningoffice) "uKv" = ( /obj/machinery/requests_console/directional/east{ department = "Chief Medical Officer's Desk"; @@ -61058,11 +61099,6 @@ /obj/effect/turf_decal/trimline/blue/filled/mid_joiner, /turf/open/floor/iron/white/smooth_large, /area/station/medical/medbay/central) -"uPO" = ( -/turf/closed/mineral/random/stationside/asteroid/porus{ - mineral_chance = 20 - }, -/area/station/maintenance/department/science) "uQl" = ( /obj/item/flashlight/flare/candle/infinite{ pixel_x = 16; @@ -61753,6 +61789,16 @@ /obj/structure/extinguisher_cabinet/directional/north, /turf/closed/wall, /area/station/hallway/primary/central) +"vfg" = ( +/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) "vfq" = ( /obj/structure/railing{ dir = 9 @@ -64183,20 +64229,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, /area/station/science/lobby) -"vXz" = ( -/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) "vXS" = ( /obj/structure/broken_flooring/side, /obj/effect/decal/cleanable/dirt/dust, @@ -66668,11 +66700,6 @@ "wOU" = ( /turf/closed/wall/r_wall, /area/station/command/heads_quarters/qm) -"wPb" = ( -/turf/closed/mineral/random/stationside/asteroid/porus{ - mineral_chance = 20 - }, -/area/station/cargo/miningoffice) "wPd" = ( /obj/effect/turf_decal/stripes/line, /turf/open/floor/iron, @@ -67888,7 +67915,7 @@ /area/station/maintenance/port/lesser) "xkc" = ( /obj/structure/cable/layer3, -/mob/living/simple_animal/bot/secbot/pingsky, +/mob/living/basic/bot/secbot/pingsky, /turf/open/floor/iron/dark, /area/station/ai/satellite/foyer) "xkx" = ( @@ -69758,6 +69785,13 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central) +"xSi" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating, +/area/station/cargo/miningoffice) "xSN" = ( /obj/machinery/airalarm/directional/north, /obj/machinery/hydroponics/soil/rich, @@ -81097,9 +81131,9 @@ cLf cLf cLf cLf -lyP -lyP -lyP +lEj +lEj +lEj rnk rnk auE @@ -81121,10 +81155,10 @@ rYJ fjg gzL jsC -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj cLf dUc cLf @@ -81353,9 +81387,9 @@ dUc cLf cLf cLf -lyP -lyP -lyP +lEj +lEj +lEj rnk rnk tdh @@ -81378,10 +81412,10 @@ oFu hrk oFu jsC -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj rnk loh loh @@ -81608,9 +81642,9 @@ cLf cLf dUc cLf -lyP -lyP -lyP +lEj +lEj +lEj rnk rnk rnk @@ -81864,10 +81898,10 @@ cLf cLf cLf dUc -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj rnk ryV rnk @@ -82100,10 +82134,10 @@ cLf cLf cLf cLf -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj cLf dUc dUc @@ -82124,7 +82158,7 @@ hCS hCS hCS hCS -lyP +lEj rnk bCv tDg @@ -83118,7 +83152,7 @@ poi fgP poi cax -lWq +oaD aCx mxq mxq @@ -83374,7 +83408,7 @@ dqW vTd csl dfW -lWq +oaD dDZ mMS nIJ @@ -83628,13 +83662,13 @@ cro cro cro poi -lWq +oaD ngd lKZ ngd mMS mMS -lWq +oaD mxq pRM mxq @@ -83890,8 +83924,8 @@ eSS dGR syR aVY -lWq -lWq +oaD +oaD mxq iPw tBe @@ -84148,7 +84182,7 @@ sIV syR sVn sIV -lWq +oaD mxq uiy qWu @@ -84405,7 +84439,7 @@ mJL hHJ hHJ qHv -lWq +oaD mxq mxq xlB @@ -84662,8 +84696,8 @@ abw eSS esl ggY -lWq -lWq +oaD +oaD mxq fGr ugu @@ -84917,10 +84951,10 @@ cDM lDP fBK eSS -lWq +oaD ggY -lWq -lWq +oaD +oaD mxq mxq sGj @@ -86431,7 +86465,7 @@ cLf cLf cLf dUc -lyP +lEj ubm ubm hME @@ -86528,8 +86562,8 @@ rnk gtK oqj rnk -lyP -lyP +lEj +lEj dUc cLf cLf @@ -86688,8 +86722,8 @@ cLf cLf cLf unk -lyP -lyP +lEj +lEj ubm fae eyv @@ -86767,7 +86801,7 @@ wJy qof hHj lUk -oab +mUB asr lyr tYs @@ -86786,7 +86820,7 @@ gtK rnk rnk rnk -lyP +lEj unk cLf cLf @@ -86944,9 +86978,9 @@ cLf cLf cLf cLf -lyP -lyP -lyP +lEj +lEj +lEj ubm eYT ohZ @@ -87043,7 +87077,7 @@ gtK rnk gaE rnk -lyP +lEj cLf cLf cLf @@ -87201,9 +87235,9 @@ cLf cLf cLf cLf -lyP -lyP -lyP +lEj +lEj +lEj ubm dMF rrF @@ -87300,8 +87334,8 @@ gtK rZz beO rnk -lyP -lyP +lEj +lEj cLf cLf cLf @@ -87458,9 +87492,9 @@ cLf cLf cLf cLf -lyP -lyP -lyP +lEj +lEj +lEj ubm hME hME @@ -87557,7 +87591,7 @@ paa rnk qvN rnk -lyP +lEj cLf cLf cLf @@ -87715,9 +87749,9 @@ cLf cLf cLf cLf -lyP -lyP -lyP +lEj +lEj +lEj hHw oRD pbB @@ -87814,7 +87848,7 @@ paa rnk rnk rnk -lyP +lEj cLf cLf cLf @@ -87972,9 +88006,9 @@ cLf cLf cLf cLf -lyP -lyP -lyP +lEj +lEj +lEj hHw mut eQY @@ -88070,7 +88104,7 @@ rnk rms loR rnk -lyP +lEj cLf cLf cLf @@ -88229,9 +88263,9 @@ cLf cLf cLf cLf -lyP -lyP -lyP +lEj +lEj +lEj hHw xjQ oMk @@ -88487,8 +88521,8 @@ cLf cLf cLf cLf -lyP -lyP +lEj +lEj hHw xjQ qEm @@ -88745,7 +88779,7 @@ cLf cLf cLf cLf -lyP +lEj hHw okV mks @@ -92943,9 +92977,9 @@ rnk paa lqf rnk -lyP -lyP -lyP +lEj +lEj +lEj cLf cLf dUc @@ -93137,8 +93171,8 @@ oZz oZz pHy oZz -lyP -lyP +lEj +lEj ygw lTJ qZh @@ -93200,8 +93234,8 @@ rnk paa pDQ rnk -lyP -lyP +lEj +lEj rnk rnk rnk @@ -93393,9 +93427,9 @@ fYe fYe fYe fYe -lyP -lyP -lyP +lEj +lEj +lEj ygw pgC sxC @@ -93636,10 +93670,10 @@ cLf cLf cLf cLf -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj wBC pOg cYP @@ -93652,7 +93686,7 @@ cLf fYe fYe fYe -lyP +lEj ygw ygw ygw @@ -93894,9 +93928,9 @@ cLf cLf cLf cLf -lyP -lyP -lyP +lEj +lEj +lEj wBC rKi kIK @@ -93910,10 +93944,10 @@ cLf uuN fYe fYe -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj iol iol iol @@ -94151,9 +94185,9 @@ cLf cLf cLf cLf -lyP +lEj unk -lyP +lEj wBC dQr dNn @@ -94169,8 +94203,8 @@ uuN fYe fYe fYe -lyP -lyP +lEj +lEj fri sZy otH @@ -94427,7 +94461,7 @@ cLf cLf fYe fYe -lyP +lEj fri taD nIb @@ -103653,7 +103687,7 @@ iUF cLf cLf cLf -lyP +lEj srs eEx vDK @@ -103910,7 +103944,7 @@ iUF dUc dUc unk -lyP +lEj srs srs cgK @@ -104166,8 +104200,8 @@ cLf iUF cLf cLf -lyP -lyP +lEj +lEj srs lPj cqm @@ -104424,7 +104458,7 @@ iUF cLf cLf cLf -lyP +lEj eOn fxo vDK @@ -104703,10 +104737,10 @@ dUc cLf cLf cLf -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj gvF uLz grl @@ -104959,11 +104993,11 @@ dUc dUc dUc dUc -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj gvF dnW rvg @@ -105216,7 +105250,7 @@ cLf cLf cLf cLf -lyP +lEj vfJ uJt uJt @@ -105473,7 +105507,7 @@ cLf cLf cLf cLf -lyP +lEj uJt eJr wWY @@ -105708,7 +105742,7 @@ cLf iUF cLf cLf -lyP +lEj dZy fhG lQe @@ -105730,7 +105764,7 @@ cLf cLf cLf cLf -lyP +lEj uJt eJr hgX @@ -105964,8 +105998,8 @@ cLf cLf cLf cLf -lyP -lyP +lEj +lEj dZy dZy xZX @@ -105986,8 +106020,8 @@ kYu cLf cLf cLf -lyP -lyP +lEj +lEj uJt nXF tLH @@ -106221,9 +106255,9 @@ cLf cLf cLf cLf -lyP -lyP -lyP +lEj +lEj +lEj dZy tgw nes @@ -106239,12 +106273,12 @@ kYu aUD kYu kYu -lyP +lEj cLf cLf cLf -lyP -lyP +lEj +lEj uJt eJr wWY @@ -106479,8 +106513,8 @@ cLf cLf cLf cLf -lyP -lyP +lEj +lEj dZy prz idU @@ -106496,12 +106530,12 @@ lYN iPQ noc kYu -lyP -lyP +lEj +lEj cLf cLf -lyP -lyP +lEj +lEj vfJ vfJ xbu @@ -106737,7 +106771,7 @@ cLf cLf cLf cLf -lyP +lEj wfl dZy dZy @@ -106753,13 +106787,13 @@ kYu kYu kYu pIN -lyP -lyP +lEj +lEj cLf cLf -lyP -lyP -lyP +lEj +lEj +lEj vfJ eIV gMK @@ -106994,8 +107028,8 @@ cLf cLf cLf cLf -lyP -lyP +lEj +lEj wZz wZz wZz @@ -107009,14 +107043,14 @@ wZz wZz wZz fBc -lyP -lyP -lyP +lEj +lEj +lEj fYe fYe -lyP -lyP -lyP +lEj +lEj +lEj vfJ gLw jmY @@ -107251,8 +107285,8 @@ cLf cLf cLf cLf -lyP -lyP +lEj +lEj wZz wZz dxA @@ -107266,14 +107300,14 @@ dPf uCS wZz wZz -lyP -lyP +lEj +lEj uif fYe fYe fYe -lyP -lyP +lEj +lEj vfJ rXG raz @@ -107508,8 +107542,8 @@ cLf cLf cLf cLf -lyP -lyP +lEj +lEj wZz wZz tOs @@ -107523,14 +107557,14 @@ hwP wmd wZz wZz -lyP -lyP +lEj +lEj fYe fYe fYe fYe -lyP -lyP +lEj +lEj vfJ oBP raz @@ -107765,8 +107799,8 @@ cLf cLf cLf cLf -lyP -lyP +lEj +lEj wZz wZz rdK @@ -107780,13 +107814,13 @@ hwP iYC wZz wZz -lyP -lyP +lEj +lEj fYe fYe fYe uif -lyP +lEj vfJ vfJ oBP @@ -108021,9 +108055,9 @@ cLf cLf cLf cLf -lyP -lyP -lyP +lEj +lEj +lEj wZz wZz mYK @@ -108037,13 +108071,13 @@ cHP taK wZz wZz -lyP -lyP -lyP +lEj +lEj +lEj fYe fYe -lyP -lyP +lEj +lEj vfJ gZF oBP @@ -108123,9 +108157,9 @@ ykG fdj dUc mPv -lyP -lyP -lyP +lEj +lEj +lEj cLf cLf cLf @@ -108278,9 +108312,9 @@ cLf cLf cLf cLf -lyP -lyP -lyP +lEj +lEj +lEj wZz wZz fOM @@ -108294,13 +108328,13 @@ hwP tOp wZz wZz -lyP -lyP -lyP +lEj +lEj +lEj cLf cLf -lyP -lyP +lEj +lEj vfJ xAd iXp @@ -108383,8 +108417,8 @@ ykG ykG ykG ykG -lyP -lyP +lEj +lEj cLf cLf cLf @@ -108535,9 +108569,9 @@ cLf cLf cLf cLf -lyP -lyP -lyP +lEj +lEj +lEj wZz wZz toT @@ -108551,13 +108585,13 @@ hwP emn wZz wZz -lyP -lyP +lEj +lEj cLf cLf cLf -lyP -lyP +lEj +lEj dpu aku uOo @@ -108640,8 +108674,8 @@ pRG arr aRs ykG -lyP -lyP +lEj +lEj cLf cLf cLf @@ -108793,8 +108827,8 @@ cLf cLf cLf cLf -lyP -lyP +lEj +lEj wZz wZz biC @@ -108808,17 +108842,17 @@ xZL jPg wZz wZz -lyP -lyP +lEj +lEj cLf cLf cLf -lyP -lyP -uPO +lEj +lEj +anz aku uOo -uPO +anz obA lXz oAX @@ -108897,8 +108931,8 @@ ptc saJ arr ykG -lyP -lyP +lEj +lEj cLf cLf cLf @@ -109050,8 +109084,8 @@ cLf cLf cLf cLf -lyP -lyP +lEj +lEj wZz wZz wZz @@ -109065,17 +109099,17 @@ wZz wZz wZz wZz -lyP +lEj cLf cLf cLf cLf -lyP -lyP +lEj +lEj vfR aku uOo -uPO +anz obA mxs qQr @@ -109101,7 +109135,7 @@ vKd niB hjI crU -lyP +lEj dUc dUc nbu @@ -109154,8 +109188,8 @@ rrz wOy voY ykG -lyP -lyP +lEj +lEj cLf cLf cLf @@ -109308,7 +109342,7 @@ cLf cLf cLf cLf -lyP +lEj wNk wZz wZz @@ -109322,17 +109356,17 @@ wZz wZz wZz wNk -lyP +lEj cLf cLf cLf cLf -lyP -lyP -uPO +lEj +lEj +anz aku uOo -uPO +anz obA xPZ gzr @@ -109358,7 +109392,7 @@ aoA pXS hjI crU -lyP +lEj dUc dUc nbu @@ -109411,7 +109445,7 @@ ptc dwH arr ykG -lyP +lEj cLf cLf cLf @@ -109584,12 +109618,12 @@ cLf cLf cLf cLf -lyP -lyP -uPO +lEj +lEj +anz aku uOo -uPO +anz obA wzX eFx @@ -109615,7 +109649,7 @@ ise niB qAI crU -lyP +lEj dUc dUc nbu @@ -109668,7 +109702,7 @@ wIN arr arr ykG -lyP +lEj cLf cLf cLf @@ -109841,12 +109875,12 @@ cLf cLf cLf cLf -lyP -lyP -uPO +lEj +lEj +anz aku uOo -uPO +anz obA sOJ uhc @@ -109872,7 +109906,7 @@ aoA qOs bpy crU -lyP +lEj dUc dUc nbu @@ -109925,7 +109959,7 @@ ykG ykG ykG ykG -lyP +lEj cLf cLf cLf @@ -110098,12 +110132,12 @@ cLf cLf cLf cLf -lyP -lyP +lEj +lEj ieo aku uOo -uPO +anz obA obA obA @@ -110129,7 +110163,7 @@ niB niB aoA crU -lyP +lEj dUc dUc nbu @@ -110182,7 +110216,7 @@ fmr dUc cLf cLf -lyP +lEj cLf cLf cLf @@ -110354,18 +110388,18 @@ cLf cLf cLf cLf -lyP -lyP -lyP -uPO +lEj +lEj +lEj +anz aku uOo -uPO -uPO +anz +anz ieo lKk iSU -uPO +anz ixU mLH dfM @@ -110386,7 +110420,7 @@ niB ers dsL crU -lyP +lEj dUc dUc dUc @@ -110612,9 +110646,9 @@ cLf cLf cLf fYe -lyP -lyP -uPO +lEj +lEj +anz aku uOo aku @@ -110622,7 +110656,7 @@ foX aku ouA jJe -uPO +anz gOY gOY gOY @@ -110643,7 +110677,7 @@ aRf aRf crU crU -lyP +lEj fTX hfp hfp @@ -110693,8 +110727,8 @@ cpG cpG cpG cpG -lyP -lyP +lEj +lEj cLf cLf cLf @@ -110869,17 +110903,17 @@ dUc dUc dUc fYe -lyP -lyP -uPO +lEj +lEj +anz aku uOo aku foX aku aku -uPO -uPO +anz +anz gOY xxN aam @@ -110892,9 +110926,9 @@ uPL sSN nal gOY -lyP +lEj cxg -lyP +lEj dUc dUc dUc @@ -110951,8 +110985,8 @@ rWI hVe cpG cpG -lyP -lyP +lEj +lEj cLf cLf cLf @@ -111126,16 +111160,16 @@ cLf cLf cLf fYe -lyP -lyP -uPO +lEj +lEj +anz aku uOo pwZ rji foX -uPO -uPO +anz +anz jTB jTB jTB @@ -111151,7 +111185,7 @@ cpJ gOY cxg cxg -lyP +lEj nbu nbu nbu @@ -111208,7 +111242,7 @@ lpe xDk mcd cpG -lyP +lEj cLf cLf cLf @@ -111383,15 +111417,15 @@ cLf cLf cLf fYe -lyP -lyP -uPO +lEj +lEj +anz vfR aku uOo aku aku -uPO +anz jTB jTB ief @@ -111408,7 +111442,7 @@ oLj gOY wHl cxg -lyP +lEj nbu aXt rBj @@ -111641,14 +111675,14 @@ cLf cLf cLf uif -lyP -uPO -uPO -uPO +lEj +anz +anz +anz uOo aku -uPO -uPO +anz +anz jTB jGd eBH @@ -111665,7 +111699,7 @@ gOY gOY cxg cxg -lyP +lEj nbu aXt jyO @@ -111889,8 +111923,8 @@ cLf cLf dUc cLf -lyP -lyP +lEj +lEj fYe fYe fYe @@ -111898,14 +111932,14 @@ fYe fYe fYe fYe -lyP -uPO -uPO -uPO +lEj +anz +anz +anz uOo aku -uPO -uPO +anz +anz jTB dkr hbH @@ -111922,7 +111956,7 @@ ofG gOY cxg cxg -lyP +lEj nbu aXt aXt @@ -112144,25 +112178,25 @@ dUc dUc dUc dUc -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj fYe fYe fYe fYe fYe fYe -uPO -uPO +anz +anz ieo iSU uOo uro rji -uPO +anz jTB sqJ wiT @@ -112179,7 +112213,7 @@ rYe gOY gOY cxg -lyP +lEj nbu nbu nbu @@ -112401,9 +112435,9 @@ cLf cLf cLf cLf -lyP -lyP -lyP +lEj +lEj +lEj fYe fYe fYe @@ -112413,13 +112447,13 @@ cLf cLf fYe rji -uPO +anz vfR aku uOo aku -uPO -uPO +anz +anz jTB dEn lIn @@ -112436,7 +112470,7 @@ fDz gqV gOY cxg -lyP +lEj nbu pIV dLf @@ -112659,7 +112693,7 @@ cLf cLf cLf cLf -lyP +lEj cLf cLf dUc @@ -112675,8 +112709,8 @@ aku aku uOo aku -uPO -uPO +anz +anz jTB gbV jqY @@ -112693,7 +112727,7 @@ dyd qDM gOY cxg -lyP +lEj nbu pIV mBg @@ -112750,8 +112784,8 @@ aTv aTv cpG cpG -lyP -lyP +lEj +lEj cLf cLf cLf @@ -112932,8 +112966,8 @@ aku pkw uOo aku -uPO -uPO +anz +anz jTB wKR wKR @@ -112950,7 +112984,7 @@ aWM vzP gOY cxg -lyP +lEj nbu pIV pIV @@ -113007,8 +113041,8 @@ aYf aYf krW cpG -lyP -lyP +lEj +lEj cLf cLf cLf @@ -113182,7 +113216,7 @@ cLf cLf cLf fYe -lyP +lEj rji nLT aku @@ -113190,7 +113224,7 @@ aku uOo aku ieo -uPO +anz jTB jTB qXE @@ -113207,7 +113241,7 @@ lfq mDx gOY cxg -lyP +lEj nbu nbu nbu @@ -113264,8 +113298,8 @@ aYf eRD eRD cpG -lyP -lyP +lEj +lEj cLf cLf cLf @@ -113438,17 +113472,17 @@ cLf cLf cLf cLf -lyP -lyP -uPO +lEj +lEj +anz pkw aku aku uOo aku vfR -uPO -uPO +anz +anz jTB jTB jTB @@ -113464,7 +113498,7 @@ sLr mDx cxg cxg -lyP +lEj nbu msY nGp @@ -113521,8 +113555,8 @@ aYf eRD lPp cpG -lyP -lyP +lEj +lEj cLf cLf cLf @@ -113721,7 +113755,7 @@ lfq nkM cxg cxg -lyP +lEj nbu msY qNM @@ -113778,8 +113812,8 @@ prc prc prc cpG -lyP -lyP +lEj +lEj cLf cLf cLf @@ -113978,7 +114012,7 @@ vib vMR dUc cxg -lyP +lEj nbu msY msY @@ -114035,8 +114069,8 @@ prc prc prc cpG -lyP -lyP +lEj +lEj cLf cLf cLf @@ -114235,7 +114269,7 @@ egV vMR dUc cxg -lyP +lEj nbu nbu nbu @@ -114292,8 +114326,8 @@ cpG cpG cpG cpG -lyP -lyP +lEj +lEj cLf cLf cLf @@ -114492,12 +114526,12 @@ nbS vMR dUc cLf -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj dUc wRN fdC @@ -114524,7 +114558,7 @@ kGZ woo kUX uFC -lyP +lEj uFC cUD nPW @@ -114543,14 +114577,14 @@ xwD cvL psF uFC -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj kxB kxB -lyP -lyP +lEj +lEj cLf cLf cLf @@ -114726,8 +114760,8 @@ pkl pkl pkl pkl -uPO -uPO +anz +anz ieo aku aku @@ -114750,11 +114784,11 @@ nkM dUc cLf dUc -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj dUc fTX rLK @@ -114780,8 +114814,8 @@ edL kGZ wlG kUX -lyP -lyP +lEj +lEj uFC pbD nPW @@ -114806,8 +114840,8 @@ gjZ sqZ uuN kxB -lyP -lyP +lEj +lEj cLf cLf cLf @@ -114980,12 +115014,12 @@ cLf cLf cLf cLf -uPO -uPO -uPO -uPO -uPO -uPO +anz +anz +anz +anz +anz +anz vfR pkw aku @@ -115007,12 +115041,12 @@ moe dUc cLf dUc -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj dUc eTZ dUc @@ -115037,8 +115071,8 @@ cEh kGZ pul kUX -lyP -lyP +lEj +lEj uFC biG nPW @@ -115063,7 +115097,7 @@ mlk dqK sqZ kxB -lyP +lEj cLf cLf cLf @@ -115234,17 +115268,17 @@ fYe fYe wfz dUc -lyP +lEj dUc dUc -uPO -uPO -uPO -uPO -uPO -uPO -uPO -uPO +anz +anz +anz +anz +anz +anz +anz +anz aku aku aku @@ -115268,8 +115302,8 @@ dUc dUc dUc dUc -lyP -lyP +lEj +lEj nbu jWP wVI @@ -115294,8 +115328,8 @@ nPf kGZ qih kUX -lyP -lyP +lEj +lEj uFC lCu pxu @@ -115320,7 +115354,7 @@ mlk mlk wtF kxB -lyP +lEj cLf cLf cLf @@ -115486,21 +115520,21 @@ cLf cLf cLf cLf -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj fYe fYe cLf cLf cLf -uPO -uPO -uPO -uPO +anz +anz +anz +anz cLf -uPO +anz obA lJq tsz @@ -115525,8 +115559,8 @@ cLf cLf cLf dUc -lyP -lyP +lEj +lEj nbu jxx bHa @@ -115577,7 +115611,7 @@ mlk dqK wtF kxB -lyP +lEj cLf cLf cLf @@ -115744,9 +115778,9 @@ cLf cLf cLf uif -lyP -lyP -lyP +lEj +lEj +lEj uif cLf cLf @@ -115782,8 +115816,8 @@ cLf cLf cLf dUc -lyP -lyP +lEj +lEj nbu szc azx @@ -115834,8 +115868,8 @@ mlk dqK wtF kxB -lyP -lyP +lEj +lEj cLf cLf cLf @@ -116000,10 +116034,10 @@ shs shs shs dUc -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj fYe cLf cLf @@ -116012,9 +116046,9 @@ cLf cLf cLf cLf -lyP -lyP -lyP +lEj +lEj +lEj obA lJq jBM @@ -116039,8 +116073,8 @@ cLf cLf cLf dUc -lyP -lyP +lEj +lEj nbu szc szc @@ -116066,7 +116100,7 @@ kUX kUX kUX dUc -lyP +lEj uFC spr xcm @@ -116090,9 +116124,9 @@ mlk mlk mlk wtF -lyP -lyP -lyP +lEj +lEj +lEj cLf cLf cLf @@ -116269,9 +116303,9 @@ cLf cLf cLf cLf -lyP -lyP -lyP +lEj +lEj +lEj obA cLf cPl @@ -116296,8 +116330,8 @@ cLf cLf cLf dUc -lyP -lyP +lEj +lEj nbu nbu nbu @@ -116311,7 +116345,7 @@ nbu nbu nbu nbu -lyP +lEj mUQ cLf dUc @@ -116320,10 +116354,10 @@ cLf cLf dUc cLf -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj uFC uFC jnY @@ -116347,9 +116381,9 @@ dqK mlk dqK wtF -lyP -lyP -lyP +lEj +lEj +lEj cLf cLf cLf @@ -116527,8 +116561,8 @@ cLf cLf cLf cLf -lyP -lyP +lEj +lEj obA cLf cLf @@ -116554,17 +116588,17 @@ cLf cLf dUc cLf -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj fYe fYe fYe @@ -116578,10 +116612,10 @@ cLf dUc cLf cLf -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj dUc cLf mDV @@ -116604,9 +116638,9 @@ dqK dqK dqK wtF -lyP -lyP -lyP +lEj +lEj +lEj cLf cLf cLf @@ -116784,8 +116818,8 @@ tyd cLf cLf cLf -lyP -lyP +lEj +lEj etW cLf cLf @@ -116812,22 +116846,22 @@ cLf dUc cLf cLf -lyP +lEj cLf dUc -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj fYe -lyP +lEj mUQ -lyP +lEj dUc cLf cLf @@ -116836,9 +116870,9 @@ dUc cLf cLf cLf -lyP -lyP -lyP +lEj +lEj +lEj dUc cLf mDV @@ -116861,8 +116895,8 @@ dqK mlk dqK wtF -lyP -lyP +lEj +lEj cLf cLf cLf @@ -117075,16 +117109,16 @@ dUc cLf cLf cLf -lyP -lyP +lEj +lEj cLf cLf cLf -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj dUc cLf cLf @@ -117092,10 +117126,10 @@ cLf dUc cLf cLf -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj dUc dUc mDV @@ -117110,7 +117144,7 @@ adc ncv ncm uFC -lyP +lEj cxg cxg xzT @@ -117118,8 +117152,8 @@ tgj tgj tgj rwE -lyP -lyP +lEj +lEj cLf cLf cLf @@ -117340,18 +117374,18 @@ cLf cLf cLf cLf -lyP -lyP +lEj +lEj dUc iUF iUF iUF dUc -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj cLf cLf cLf @@ -117367,16 +117401,16 @@ uvN wQz kiW uFC -lyP -lyP -lyP +lEj +lEj +lEj cxg cxg cxg cxg -lyP -lyP -lyP +lEj +lEj +lEj cLf cLf cLf @@ -117605,8 +117639,8 @@ cLf cLf cLf cLf -lyP -lyP +lEj +lEj cLf mUQ fYe @@ -117625,15 +117659,15 @@ aQo kEu uFC vaU -lyP -lyP -lyP +lEj +lEj +lEj fYe fYe -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj cLf cLf cLf @@ -117869,7 +117903,7 @@ uVI fYe fYe fYe -lyP +lEj uFC uFC kEu @@ -117881,15 +117915,15 @@ kEu kEu uFC uFC -lyP -lyP -lyP +lEj +lEj +lEj mUQ uVI uVI mUQ -lyP -lyP +lEj +lEj cLf cLf cLf @@ -118126,8 +118160,8 @@ uVI uVI uVI mUQ -lyP -lyP +lEj +lEj uFC uFC uFC @@ -118137,10 +118171,10 @@ uFC uFC uFC uFC -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj fYe fYe fYe @@ -118385,18 +118419,18 @@ cLf cLf cLf cLf -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj cLf cLf fYe @@ -139440,12 +139474,12 @@ hhX hhX hhX hhX -lyP -lyP +lEj +lEj hhX hhX -lyP -lyP +lEj +lEj hhX hhX hhX @@ -139695,15 +139729,15 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj hhX hhX hhX @@ -139950,21 +139984,21 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj mUQ kLL unk -lyP +lEj hhX hhX hhX @@ -140205,24 +140239,24 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj fYe qHE -lyP -lyP -lyP +lEj +lEj +lEj hhX hhX hhX @@ -140462,25 +140496,25 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj vYz aUf vYz vYz vYz -lyP +lEj fYe fYe fYe fYe -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj hhX hhX hhX @@ -140719,8 +140753,8 @@ hhX hhX hhX hhX -lyP -lyP +lEj +lEj vYz aUf vYz @@ -140732,12 +140766,12 @@ vYz aUf aUf aUf -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj fYe -lyP +lEj hhX hhX hhX @@ -140990,9 +141024,9 @@ ory aTE aUf aUf -lyP -lyP -lyP +lEj +lEj +lEj fYe fYe hhX @@ -141247,10 +141281,10 @@ qyq fUv pkA aUf -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj fYe hhX hhX @@ -141506,8 +141540,8 @@ wMe wnw fYe fYe -lyP -lyP +lEj +lEj hhX hhX hhX @@ -143560,7 +143594,7 @@ eZo wCR vYz vYz -lyP +lEj fYe fYe hhX @@ -143816,9 +143850,9 @@ eSs iXA vYz vYz -lyP -lyP -lyP +lEj +lEj +lEj fYe hhX hhX @@ -144075,7 +144109,7 @@ iVG eYP gHN gHN -lyP +lEj hhX hhX hhX @@ -145088,7 +145122,7 @@ hhX hhX hhX hhX -lyP +lEj vYz fJV wdI @@ -145344,8 +145378,8 @@ hhX hhX hhX hhX -lyP -lyP +lEj +lEj vYz vYz rap @@ -145602,8 +145636,8 @@ hhX hhX hhX hhX -lyP -lyP +lEj +lEj vYz aUf aUf @@ -145619,9 +145653,9 @@ hhX hhX jVV hhX -lyP -lyP -lyP +lEj +lEj +lEj hhX hhX fZF @@ -145876,8 +145910,8 @@ hhX fYe fYe fYe -lyP -lyP +lEj +lEj fYe fYe qHE @@ -146110,10 +146144,10 @@ oID jVV hhX hhX -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj hhX hhX hhX @@ -146365,20 +146399,20 @@ hhX hhX hhX jVV -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -hhX -hhX -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +hhX +hhX +lEj +lEj iJm iJm eYP @@ -146389,14 +146423,14 @@ dvC mUQ fYe fYe -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj fYe fYe fYe @@ -146622,19 +146656,19 @@ hhX hhX hhX hhX -lyP -lyP -lyP +lEj +lEj +lEj qAp fYe -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj mUQ kLL cts @@ -146646,14 +146680,14 @@ iJm mUQ mUQ fYe -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj fYe fYe fYe @@ -146879,19 +146913,19 @@ hhX hhX hhX hhX -lyP -lyP -lyP +lEj +lEj +lEj uif uif -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj iJm iJm foL @@ -146900,31 +146934,31 @@ gZt dPG foL iJm -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj fnh fnh fnh fnh fnh fnh -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj fYe fYe fYe fYe -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj hhX hhX hhX @@ -147108,9 +147142,9 @@ hhX hhX hhX hhX -lyP -lyP -lyP +lEj +lEj +lEj hhX hhX hhX @@ -147135,20 +147169,20 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj fYe hSF -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj iJm iJm foL @@ -147158,31 +147192,31 @@ plV foL dcl qHE -lyP -lyP -lyP +lEj +lEj +lEj fnh vTt dBK aQD vTt fnh -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj hhX hhX hhX @@ -147365,10 +147399,10 @@ fYe fYe fYe hhX -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj hhX hhX hhX @@ -147392,8 +147426,8 @@ hhX hhX hhX hhX -lyP -lyP +lEj +lEj gNV gNV gNV @@ -147402,10 +147436,10 @@ gNV gNV gNV uif -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj iJm iJm foL @@ -147424,22 +147458,22 @@ mlK mlK fSp fnh -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -bGz -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +nTN +lEj +lEj hhX hhX hhX @@ -147619,13 +147653,13 @@ fYe fYe fYe fYe -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj hhX hhX hhX @@ -147650,7 +147684,7 @@ aZg aZg aZg aZg -lyP +lEj gNV bMZ tKm @@ -147658,11 +147692,11 @@ lib qmf iSw gNV -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj iJm iJm eYP @@ -147681,22 +147715,22 @@ mlK mlK dBK fnh -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj hhX hhX hhX @@ -147873,28 +147907,28 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj lLo sMT lLo @@ -147907,7 +147941,7 @@ umg umg umg umg -lyP +lEj gNV rwu eiI @@ -147915,11 +147949,11 @@ hvV kkK pha gNV -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj iJm iJm iJm @@ -147928,7 +147962,7 @@ wku plV gHN fYe -apr +jsO fnh diz jMW @@ -147938,8 +147972,8 @@ aQD dBK vTt fnh -lyP -lyP +lEj +lEj fnh fnh fnh @@ -147947,12 +147981,12 @@ fnh fnh fnh fnh -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj hhX hhX hhX @@ -148130,27 +148164,27 @@ fNW hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +pEH pEH pEH pEH -lyP +lEj iaN iaN aJP @@ -148172,12 +148206,12 @@ tXr qia qtT gNV -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj iJm uKm eYP @@ -148185,7 +148219,7 @@ pmp ldf eYP fnh -apr +jsO fnh fnh jMW @@ -148204,10 +148238,10 @@ fnh wXY whx fnh -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj hhX hhX hhX @@ -148387,26 +148421,26 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +uKu pEH -pEH -wPb -wPb +uKu +uKu +uKu iaN iaN iig @@ -148430,19 +148464,19 @@ gNV gNV gNV dLR -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj fnh mUA iLo lYg oHC fnh -apr +jsO fnh lTj jMW @@ -148461,10 +148495,10 @@ mkc kzS uym fnh -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj hhX hhX hhX @@ -148646,24 +148680,24 @@ fYe fYe fYe fYe -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -pEH +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +uKu +uKu ixo dcg -nxd +pdj iaN kVX bUJ @@ -148691,8 +148725,8 @@ vLs aCv vLs aCv -apr -apr +jsO +jsO kGS rPT atT @@ -148718,10 +148752,10 @@ fnh qlO guP fnh -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj hhX hhX hhX @@ -148903,24 +148937,24 @@ hhX hhX fYe fYe -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj pEH +bLu xok -ljG -fFE +vfg +hXH iaN mPH dhv @@ -148975,10 +149009,10 @@ fnh fnh fnh fnh -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj hhX hhX hhX @@ -149160,23 +149194,23 @@ jVV jVV jVV fYe -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -pEH -cbn -ljG +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +uKu +xSi +efm +qXY qXY iaN gEQ @@ -149232,10 +149266,10 @@ nFS fnh dxD aRn -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj hhX hhX hhX @@ -149415,25 +149449,25 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj pEH +izF nuu -ilO +kVS qXY wds uRO @@ -149458,12 +149492,12 @@ fLe xRj xXY kYT -apr -apr -apr +jsO +jsO +jsO aCv wWJ -apr +jsO aCv ygt dXH @@ -149490,10 +149524,10 @@ fnh ibx ibx rFK -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj fYe fYe fYe @@ -149686,9 +149720,9 @@ dOG dOG dOG dOG -lyP -lyP -wPb +lEj +uKu +izF efm ljG qXY @@ -149718,9 +149752,9 @@ wOU wOU wOU kYT -apr +jsO wWJ -apr +jsO bGk bGk tuL @@ -149747,12 +149781,12 @@ fnh fnh uXS fnh -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj fYe fYe hhX @@ -149943,12 +149977,12 @@ qog gcQ bEn dOG -lyP -lyP -wPb +lEj +pEH +mRE iee bPu -wPb +uKu iaN fON jds @@ -149975,9 +150009,9 @@ dCv fxF fxF kYT -apr +jsO taj -apr +jsO bGk mqc mfw @@ -150004,14 +150038,14 @@ qrg eQI iMT fnh -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj hhX hhX hhX @@ -150200,12 +150234,12 @@ dOG dOG mkN dOG -lyP -lyP -lyP -wPb -wPb -wPb +lEj +lEj +uKu +uKu +uKu +uKu iaN iaN dlY @@ -150234,7 +150268,7 @@ fxF kYT wWJ wWJ -apr +jsO bGk sHo mJD @@ -150262,13 +150296,13 @@ eAq lGe fnh fnh -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj fYe -lyP -lyP +lEj +lEj hhX hhX hhX @@ -150457,12 +150491,12 @@ ouF ouF lbr dOG -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +pEH +uKu +pEH iaN qIa fBm @@ -150490,8 +150524,8 @@ mYd uUP kYT wWJ -apr -apr +jsO +jsO bGk jfq dhj @@ -150519,9 +150553,9 @@ rcy cIi siK fnh -lyP -lyP -lyP +lEj +lEj +lEj fYe fYe fYe @@ -150714,12 +150748,12 @@ gAQ eBa eWJ dOG -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj iaN iaN poi @@ -150776,9 +150810,9 @@ qpR lGe oJJ fnh -lyP -lyP -lyP +lEj +lEj +lEj fYe hhX hhX @@ -150971,14 +151005,14 @@ jqd jmU mKW dOG -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj poi xeh jir @@ -151033,9 +151067,9 @@ fnh fnh fnh fnh -lyP -lyP -lyP +lEj +lEj +lEj fYe hhX hhX @@ -151228,14 +151262,14 @@ dOG dOG dOG dOG -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj poi rEK poi @@ -151257,9 +151291,9 @@ wOU wAm lzu wOU -lyP -lyP -apr +lEj +lEj +jsO wWJ kYT auB @@ -151290,9 +151324,9 @@ vYQ ezM qMn iMq -lyP -lyP -lyP +lEj +lEj +lEj hhX hhX hhX @@ -151484,15 +151518,15 @@ xey egY rai uZc -lyP -lyP +lEj +lEj fYe fYe fYe -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj poi tdq xTb @@ -151514,9 +151548,9 @@ wOU cNr ugI wOU -lyP -lyP -apr +lEj +lEj +jsO wWJ kYT xtb @@ -151547,9 +151581,9 @@ spA spA gBY iMq -lyP -lyP -lyP +lEj +lEj +lEj fYe hhX hhX @@ -151741,8 +151775,8 @@ cJZ rai rai uZc -lyP -lyP +lEj +lEj wkX fYe fYe @@ -151771,9 +151805,9 @@ wOU ntd pZj wOU -lyP -lyP -apr +lEj +lEj +jsO wWJ kYT auB @@ -151804,9 +151838,9 @@ iom tjn aRZ iMq -lyP -lyP -lyP +lEj +lEj +lEj hhX hhX hhX @@ -151998,7 +152032,7 @@ uZc uZc uZc uZc -lyP +lEj hen hen hen @@ -152009,7 +152043,7 @@ fYe fYe fYe fYe -lyP +lEj sdc oZQ oZQ @@ -152029,8 +152063,8 @@ epK epK epK fnh -apr -apr +jsO +jsO taj kYT jEu @@ -152061,9 +152095,9 @@ dpj cUm tve iMq -lyP -lyP -lyP +lEj +lEj +lEj fYe fYe hhX @@ -152225,10 +152259,10 @@ hhX hhX fYe fYe -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj jOV skb wSc @@ -152252,10 +152286,10 @@ xtp oPN bWJ uZc -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj hen hen hen @@ -152266,7 +152300,7 @@ hen fYe fYe fYe -lyP +lEj sdc oZQ oZQ @@ -152286,7 +152320,7 @@ pkt xMY aDW fnh -apr +jsO rNJ rNJ kYT @@ -152318,9 +152352,9 @@ niI mnA jKj iMq -lyP -lyP -lyP +lEj +lEj +lEj fYe fYe fYe @@ -152482,10 +152516,10 @@ hhX hhX fYe fYe -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj jOV skb wSc @@ -152509,8 +152543,8 @@ crb iqE mMp hED -lyP -lyP +lEj +lEj fYe fYe hen @@ -152523,7 +152557,7 @@ hen fYe fYe fYe -lyP +lEj sdc oZQ oZQ @@ -152547,7 +152581,7 @@ bgY bgY bgY dog -apr +jsO fnh wnL oFa @@ -152575,9 +152609,9 @@ iMq beR iMq iMq -lyP -lyP -lyP +lEj +lEj +lEj fYe fYe hhX @@ -152739,10 +152773,10 @@ hhX hhX fYe fYe -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj jOV kDb ctL @@ -152752,10 +152786,10 @@ nvR fDi uEX jOV -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj mIW sUM rhc @@ -152767,7 +152801,7 @@ ylZ buu hED hED -lyP +lEj wkX fYe hen @@ -152780,7 +152814,7 @@ hen fYe fYe fYe -lyP +lEj sdc sdc sdc @@ -152800,11 +152834,11 @@ mlh jpx aLE fnh -apr +jsO rNJ koX dog -apr +jsO fnh igq igq @@ -152832,9 +152866,9 @@ iMq avC oEC iMq -lyP -lyP -lyP +lEj +lEj +lEj fYe fYe fYe @@ -152996,7 +153030,7 @@ hhX hhX fYe fYe -lyP +lEj hHw hHw hHw @@ -153009,10 +153043,10 @@ jOV jOV jOV jOV -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj mIW thT thT @@ -153024,7 +153058,7 @@ ccI cPP tTz hED -lyP +lEj fYe fYe hen @@ -153036,9 +153070,9 @@ hen hen fYe fYe -lyP -lyP -lyP +lEj +lEj +lEj bNL xsj lFN @@ -153061,7 +153095,7 @@ aCv cGs vFq dog -apr +jsO fnh evQ evQ @@ -153089,9 +153123,9 @@ iMq lsq iBP iMq -lyP -lyP -lyP +lEj +lEj +lEj fYe fYe hhX @@ -153262,14 +153296,14 @@ wSc rwW wSc jOV -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj mIW sTS thT @@ -153281,7 +153315,7 @@ bZI ipc tME hED -lyP +lEj fYe hen hen @@ -153293,9 +153327,9 @@ hen hen fYe fYe -lyP -lyP -lyP +lEj +lEj +lEj bNL xWQ cVb @@ -153314,11 +153348,11 @@ gnE xeA otY fnh -apr +jsO rNJ blM dog -apr +jsO fnh evQ evQ @@ -153346,9 +153380,9 @@ iMq frv cxP iMq -lyP -lyP -lyP +lEj +lEj +lEj fYe fYe hhX @@ -153519,14 +153553,14 @@ xbr qFS wSc jOV -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj mIW thT thT @@ -153538,21 +153572,21 @@ tGw ipc eQJ hED -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj hen hen fYe fYe -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj bNL exg bcj @@ -153571,11 +153605,11 @@ qBu fIm otY fnh -apr -apr +jsO +jsO rNJ kpx -apr +jsO fnh gWX bAV @@ -153603,9 +153637,9 @@ aOm aOm aOm aOm -lyP -lyP -lyP +lEj +lEj +lEj fYe hhX hhX @@ -153776,14 +153810,14 @@ hHw dAq jOV jOV -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj mIW thT thT @@ -153795,21 +153829,21 @@ rAq xNy iUV hED -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj fYe fYe fYe fYe -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj bNL xgQ oRE @@ -153828,8 +153862,8 @@ vOu vOu vOu fnh -apr -apr +jsO +jsO rNJ kpx qcU @@ -153860,9 +153894,9 @@ fnU udG xzP oZt -lyP -lyP -lyP +lEj +lEj +lEj fYe hhX hhX @@ -154034,13 +154068,13 @@ aCb aCb hHw hHw -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj mIW mIW mIW @@ -154052,21 +154086,21 @@ hED hED hED hED -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj fYe fYe fYe -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj bNL hxg bcj @@ -154079,13 +154113,13 @@ tFD wjC rPt sdc -lyP -lyP -lyP -lyP -lyP -lyP -apr +lEj +lEj +lEj +lEj +lEj +lEj +jsO rNJ rNJ kpx @@ -154105,7 +154139,7 @@ wYo cLD nzb xnq -fCU +muE xhJ oZt fQG @@ -154117,10 +154151,10 @@ aRN nqD hZN oZt -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj hhX hhX hhX @@ -154291,39 +154325,39 @@ uRG uRG uRG hHw -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj hED npn okF aum hED -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -fYe -fYe -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +fYe +fYe +lEj +lEj +lEj +lEj +lEj +lEj bNL pNs dpH @@ -154336,8 +154370,8 @@ sdc sdc sdc sdc -lyP -lyP +lEj +lEj fnh fnh fnh @@ -154346,7 +154380,7 @@ fnh qcU kpx kpx -apr +jsO fnh sxa mpp @@ -154374,10 +154408,10 @@ fnU xzP nrW oZt -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj hhX hhX hhX @@ -154548,53 +154582,53 @@ uRG uRG uRG hHw -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj hED ocl kkC phJ hED -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -fYe -fYe -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +fYe +fYe +lEj +lEj +lEj +lEj +lEj +lEj bNL bNL bNL bNL bNL bNL -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj fnh bmu tMP @@ -154603,7 +154637,7 @@ pSV kpx bzu qcU -apr +jsO fnh igq igq @@ -154631,9 +154665,9 @@ gcy aRN aRN oZt -lyP +lEj fYe -lyP +lEj mUQ jOM hhX @@ -154805,66 +154839,66 @@ hHw hHw hHw hHw -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj hED hED hED hED hED -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -fYe -fYe -fYe -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +fYe +fYe +fYe +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj gYW gYW gYW gYW -lyP -lyP -lyP +lEj +lEj +lEj fnh bmu bMl uJA fnh -apr +jsO rNJ doZ -apr -lyP -lyP -lyP -lyP +jsO +lEj +lEj +lEj +lEj igq igq igq @@ -154884,11 +154918,11 @@ teV oZt rix ixR -vXz -pdt +qro +hOh vau oZt -lyP +lEj kqj xcq gVN @@ -155061,41 +155095,41 @@ hhX hhX hhX okm -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -fYe -fYe -fYe -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +fYe +fYe +fYe +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj gYW gYW gYW @@ -155106,25 +155140,25 @@ gYW jbP gLD gYW -lyP -lyP -lyP +lEj +lEj +lEj fnh fnh fnh fnh fnh -apr +jsO aCv tBL aCv -dQq -dQq -dQq -dQq -lyP -lyP -lyP +iwP +iwP +iwP +iwP +lEj +lEj +lEj gvw gvw gvw @@ -155318,41 +155352,41 @@ hhX hhX hhX okm -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj fYe fYe mEN -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj gYW dTy vsD @@ -155366,25 +155400,25 @@ gYW gYW gYW gYW -dQq -dQq -dQq -dQq +iwP +iwP +iwP +iwP nev dtt dtt dtt dtt dtt -dQq -dQq -dQq -lyP -lyP -lyP -lyP -lyP -lyP +iwP +iwP +iwP +lEj +lEj +lEj +lEj +lEj +lEj gvw gjt jEf @@ -155392,9 +155426,9 @@ kQV uKv evg gvw -lyP -lyP -lyP +lEj +lEj +lEj oZt jCU tkh @@ -155402,10 +155436,10 @@ cgw fMY uHE oZt -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj jVV hhX hhX @@ -155575,41 +155609,41 @@ fYe hhX hhX okm -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj fYe fYe unk -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj gYW fdQ oMn @@ -155631,17 +155665,17 @@ dtt dtt dtt nev -dQq +iwP dtt -dQq -dQq -dQq -lyP -lyP -lyP -lyP -lyP -lyP +iwP +iwP +iwP +lEj +lEj +lEj +lEj +lEj +lEj gvw gvw gvw @@ -155649,7 +155683,7 @@ gvw gvw gvw gvw -lyP +lEj unk unk oZt @@ -155659,10 +155693,10 @@ oZt oZt oZt oZt -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj hhX hhX hhX @@ -155832,37 +155866,37 @@ pnS hhX hhX okm -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj fYe fYe iRm fYe -lyP -lyP -lyP +lEj +lEj +lEj gYW gYW gYW @@ -155887,26 +155921,26 @@ dtt dtt dtt dtt -dQq -dQq +iwP +iwP dtt dtt nev mGn -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -ibw +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +nho unk hhX hhX @@ -155914,10 +155948,10 @@ hhX hhX hhX unk -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj hhX hhX hhX @@ -156089,36 +156123,36 @@ fYe hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -fYe -fYe -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +fYe +fYe +lEj unk fYe fYe -lyP +lEj fYe oSk esQ @@ -156137,15 +156171,15 @@ wjI wjI wjI gYW -dQq -dQq -dQq +iwP +iwP +iwP dtt dtt -dQq +iwP dtt uXD -dQq +iwP dtt dtt dtt @@ -156157,24 +156191,24 @@ azk azk azk azk -lyP -lyP +lEj +lEj gMk -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj hhX hhX hhX hhX hhX unk -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj hhX hhX hhX @@ -156346,32 +156380,32 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj fYe -lyP -lyP +lEj +lEj fYe fYe fYe @@ -156396,7 +156430,7 @@ dSl gYW uXD uXD -dQq +iwP ldo ldo ldo @@ -156412,26 +156446,26 @@ cHs uXD uXD uXD -lyP +lEj azk azk azk azk azk -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj fYe hhX hhX hhX hhX unk -qSf -lyP -lyP -lyP +tJk +lEj +lEj +lEj hhX hhX hhX @@ -156603,37 +156637,37 @@ hhX hhX hhX okm -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -fYe -lyP -lyP -fYe -fYe -fYe -fYe -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +fYe +lEj +lEj +fYe +fYe +fYe +fYe +lEj oSk wAv wAv @@ -156669,26 +156703,26 @@ qIf vwL pbn uXD -lyP -lyP +lEj +lEj uet gMk -lyP +lEj azk azk -lyP -lyP -lyP +lEj +lEj +lEj fYe hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj hhX hhX hhX @@ -156860,33 +156894,33 @@ hhX fNW hhX okm -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -fYe -fYe -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +fYe +fYe +lEj +lEj fYe gYW gYW @@ -156928,24 +156962,24 @@ dFc uXD uXD uXD -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj azk -lyP -lyP -lyP +lEj +lEj +lEj fYe hhX hhX hhX hhX unk -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj hhX hhX hhX @@ -157117,34 +157151,34 @@ hhX hhX hhX okm -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -fYe -fYe -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +fYe +fYe +lEj +lEj gYW dum hdN @@ -157185,24 +157219,24 @@ sZF pLP kEs uXD -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj azk -lyP -lyP +lEj +lEj unk unk unk -lyP +lEj unk unk unk -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj hhX hhX hhX @@ -157374,34 +157408,34 @@ hhX hhX hhX okm -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -fYe -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +fYe +lEj +lEj +lEj gYW kwW tQy @@ -157442,23 +157476,23 @@ sZF pLP pLP uXD -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj azk azk azk azk unk dra -lyP -pzu -lyP -lyP -lyP -hFT -lyP +lEj +ahX +lEj +lEj +lEj +mxf +lEj hhX hhX hhX @@ -157631,34 +157665,34 @@ hhX hhX hhX okm -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -fYe -fYe -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +fYe +fYe +lEj +lEj gYW hbQ saY @@ -157701,17 +157735,17 @@ uXD uXD uKm uKm -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj azk iEl gMk uet uet -lyP +lEj gMk mGM unk @@ -157888,34 +157922,34 @@ hhX hhX okm okm -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -fYe -fYe -fYe -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +fYe +fYe +fYe +lEj +lEj gYW gYW gYW @@ -157958,14 +157992,14 @@ gMk dij atB uKm -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj azk azk unk -lyP +lEj gMk gMk gMk @@ -158145,35 +158179,35 @@ hhX hhX okm okm -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj unk unk gbv any unk unk -lyP -lyP +lEj +lEj gYW kGy mMN @@ -158214,18 +158248,18 @@ uXD uet gMk mZs -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj azk -lyP -lyP -lyP +lEj +lEj +lEj gMk -lyP -lyP +lEj +lEj ent bCg unk @@ -158402,26 +158436,26 @@ hhX hhX okm okm -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj unk unk fYe @@ -158430,7 +158464,7 @@ fYe fYe unk unk -lyP +lEj gYW kGy mMN @@ -158471,22 +158505,22 @@ rzJ gMk gMk gMk -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj azk gMk -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj hhX hhX hhX @@ -158659,26 +158693,26 @@ hhX hhX okm okm -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj fYe dsG fYe fYe fYe -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj unk fYe fYe @@ -158728,22 +158762,22 @@ uXD uXD uXD gMk -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj azk -lyP -lyP -lyP +lEj +lEj +lEj rnk rnk rnk rnk rnk rnk -lyP +lEj hhX hhX hhX @@ -158916,13 +158950,13 @@ hhX hhX okm okm -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj fYe fYe hen @@ -158934,8 +158968,8 @@ fYe fYe dsG dsG -lyP -lyP +lEj +lEj unk fYe ivx @@ -158985,15 +159019,15 @@ pLP kEs uXD gMk -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj gMk azk -lyP -lyP -lyP +lEj +lEj +lEj rnk vGs dwI @@ -159173,13 +159207,13 @@ hhX hhX hhX fYe -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj fYe fYe hen @@ -159243,14 +159277,14 @@ pLP uXD gMk gMk -lyP -lyP -lyP +lEj +lEj +lEj azk azk gMk uet -lyP +lEj rnk iQt noh @@ -159430,13 +159464,13 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj fYe fYe hen @@ -159498,13 +159532,13 @@ wLu uXD uXD uXD -lyP +lEj gMk uet uet -lyP +lEj azk -lyP +lEj gMk gMk gMk @@ -159687,13 +159721,13 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj fYe fYe hen @@ -159715,8 +159749,8 @@ fYe fYe unk unk -lyP -lyP +lEj +lEj jCD jCD jCD @@ -159754,17 +159788,17 @@ lvw xGo oEp ibx -lyP -lyP +lEj +lEj azk azk azk azk azk -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj rnk bzj eMq @@ -159944,13 +159978,13 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj fYe fYe fYe @@ -159964,19 +159998,19 @@ hen hen hen fYe -lyP +lEj unk unk unk unk unk unk -lyP -lyP -lyP -lyP -lyP -jsy +lEj +lEj +lEj +lEj +lEj +sPy gYW gYW gYW @@ -160014,13 +160048,13 @@ ibx uet azk azk -lyP -lyP +lEj +lEj pfg -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj hhX rnk rnk @@ -160201,13 +160235,13 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj fYe fYe fYe @@ -160221,21 +160255,21 @@ hen hen hen fYe -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj hwW dTe -jsy +sPy gYW gYW gYW @@ -160270,14 +160304,14 @@ ibx ibx ibx azk -lyP -lyP -lyP +lEj +lEj +lEj iDq -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj hhX hhX hhX @@ -160458,15 +160492,15 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj fYe hen hen @@ -160478,23 +160512,23 @@ hen hen hen hen -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj oSk qGN dTe -jsy -jsy -jsy +sPy +sPy +sPy gYW gYW wjI @@ -160715,15 +160749,15 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj fYe fYe hen @@ -160735,24 +160769,24 @@ hen hen hen hen -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj fAV aIB dTe eyf eyf -jsy -jsy +sPy +sPy gYW wjI wjI @@ -160779,9 +160813,9 @@ qaE klJ lSD jGB -lyP +lEj pfg -lyP +lEj ibx ftX piS @@ -160972,15 +161006,15 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj fYe fYe hen @@ -160991,15 +161025,15 @@ hen hen hen hen -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj gYW gYW gYW @@ -161009,7 +161043,7 @@ pjn aWJ aWJ hwW -jsy +sPy gYW tXp gYW @@ -161038,7 +161072,7 @@ jGB jGB cOD uet -lyP +lEj ibx lgp hzF @@ -161229,15 +161263,15 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj fYe fYe hen @@ -161248,15 +161282,15 @@ hen hen hen hen -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj gYW gnx dTe @@ -161487,14 +161521,14 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj fYe fYe hen @@ -161505,15 +161539,15 @@ hen hen hen hen -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj gYW rLJ srv @@ -161523,7 +161557,7 @@ pLE tXp aWJ aIB -jsy +sPy gYW tXp gYW @@ -161744,14 +161778,14 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj fYe fYe fYe @@ -161762,15 +161796,15 @@ dsG fYe fYe fYe -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj gYW gYW hCT @@ -162002,33 +162036,33 @@ oID jVV jVV jVV -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj dsG -lyP -lyP -lyP -fYe -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +fYe +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj gYW gYW gYW @@ -162274,20 +162308,20 @@ ttt oaF ttt ttt -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj nzw aih fne @@ -162535,16 +162569,16 @@ ttt ttt ttt ttt -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj nzw pqB fne @@ -162792,23 +162826,23 @@ bjn bjn rRY ttt -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj nzw aih qCf ycw ksf hmF -jsy +sPy gYW wAv gYW @@ -163049,23 +163083,23 @@ tMp bjn nen ttt -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj fne dTe dTe nMj nfj -jsy +sPy gYW wAv wAv @@ -163306,23 +163340,23 @@ wcH fib fDf ttt -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj lIZ dTe fne dTe -jsy +sPy gYW kIB gYW @@ -163579,7 +163613,7 @@ ycN wbT wub uMY -jsy +sPy gYW gYW gYW @@ -163836,9 +163870,9 @@ ycN unk unk unk -lyP -lyP -lyP +lEj +lEj +lEj gYW uSe cjp @@ -164090,12 +164124,12 @@ cHh kNJ vaC ycN -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj gYW uSe cjp @@ -164347,12 +164381,12 @@ hqg ukY vaC ycN -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj gYW gYW gYW @@ -164604,14 +164638,14 @@ kqS rtN jlI ycN -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj gYW wyK tuR @@ -164651,7 +164685,7 @@ hzF hzF hzF hzF -lyP +lEj jVV jVV jVV @@ -164861,14 +164895,14 @@ brV hQA yhW ycN -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj gYW kdc jYp @@ -164891,24 +164925,24 @@ mBw qxU fAT apQ -lyP -lyP +lEj +lEj gMk gMk -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj hhX hhX hhX @@ -165118,14 +165152,14 @@ daK wad vaC ycN -lyP -lyP -lyP +lEj +lEj +lEj gMk gMk -lyP -lyP -lyP +lEj +lEj +lEj gYW imU mhD @@ -165148,26 +165182,26 @@ hPP rhW kNO apQ -lyP +lEj gMk gMk gMk -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj hhX hhX hhX @@ -165375,14 +165409,14 @@ hqg ukY vaC ycN -lyP +lEj gMk gMk gMk gMk uet -lyP -lyP +lEj +lEj gYW gYW gYW @@ -165405,13 +165439,13 @@ apQ kOE rMQ apQ -lyP -lyP +lEj +lEj gMk gMk -lyP -lyP -lyP +lEj +lEj +lEj lAj lAj lAj @@ -165425,7 +165459,7 @@ lAj lAj lAj lAj -lyP +lEj fYe hhX hhX @@ -165639,9 +165673,9 @@ gMk gMk gMk gMk -lyP -lyP -jsy +lEj +lEj +sPy aWJ dTe dTe @@ -165662,13 +165696,13 @@ apQ kOE uDd apQ -lyP -lyP +lEj +lEj gMk gMk gMk -lyP -lyP +lEj +lEj lAj pBg xJT @@ -165682,7 +165716,7 @@ vmB ctv rPC lAj -lyP +lEj fYe hhX hhX @@ -165889,15 +165923,15 @@ vaC vaC vaC ycN -lyP -lyP +lEj +lEj gMk gMk gMk gMk gMk -lyP -lyP +lEj +lEj oSk nlZ dTe @@ -165919,13 +165953,13 @@ apQ kOE rMQ apQ -lyP -lyP +lEj +lEj gMk gMk gMk -lyP -lyP +lEj +lEj lAj ebz sbo @@ -165939,7 +165973,7 @@ uBn rts gdZ lAj -lyP +lEj fYe hhX hhX @@ -166115,7 +166149,7 @@ hhX hhX hhX hhX -lyP +lEj juw prr juw @@ -166146,16 +166180,16 @@ ycN ycN ycN ycN -lyP -lyP -lyP +lEj +lEj +lEj gMk gMk gMk gMk -lyP -lyP -jsy +lEj +lEj +sPy aWJ hUN dTe @@ -166176,9 +166210,9 @@ apQ kOE rMQ apQ -lyP -lyP -lyP +lEj +lEj +lEj gMk gMk lAj @@ -166196,7 +166230,7 @@ ajS ajS gdZ lAj -lyP +lEj fYe hhX hhX @@ -166372,51 +166406,51 @@ hhX hhX hhX hhX -lyP -lyP +lEj +lEj dsG -lyP -lyP +lEj +lEj dsG dsG -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj gMk gMk -lyP -lyP -lyP -lyP -jsy +lEj +lEj +lEj +lEj +sPy aWJ fAJ qaS -jsy +sPy apQ hCb rwX @@ -166433,9 +166467,9 @@ oNo vRt pXB apQ -lyP -lyP -lyP +lEj +lEj +lEj gMk rcP lAj @@ -166453,7 +166487,7 @@ ajS ajS gdZ lAj -lyP +lEj fYe hhX hhX @@ -166637,43 +166671,43 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj uet xUx -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj oSk lhO oSk oSk -jsy +sPy apQ dzQ vjT @@ -166690,8 +166724,8 @@ anZ jIf eaS apQ -lyP -lyP +lEj +lEj uet gMk obD @@ -166710,8 +166744,8 @@ ajS ajS bag lAj -lyP -lyP +lEj +lEj hhX hhX hhX @@ -166896,41 +166930,41 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj xUx uet -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj gMk gMk gMk gMk -lyP -lyP +lEj +lEj apQ qEn tRl @@ -166947,8 +166981,8 @@ rwU sTl apQ apQ -lyP -lyP +lEj +lEj gMk alx obD @@ -166967,8 +167001,8 @@ ajS ajS gdZ lAj -lyP -lyP +lEj +lEj hhX hhX hhX @@ -167153,41 +167187,41 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj unk -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj gMk gMk -lyP -lyP +lEj +lEj gMk gMk gMk gMk uet -lyP -lyP +lEj +lEj apQ apQ apQ @@ -167204,8 +167238,8 @@ apQ apQ apQ apQ -lyP -lyP +lEj +lEj gMk gMk sDP @@ -167224,7 +167258,7 @@ ajS ajS gdZ lAj -lyP +lEj fYe hhX hhX @@ -167412,58 +167446,58 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj gMk his gMk -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj gMk gMk -lyP +lEj gMk gMk gMk gMk gMk -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj gMk vDa rBU @@ -167481,7 +167515,7 @@ ajS ajS gdZ lAj -lyP +lEj fYe hhX hhX @@ -167669,57 +167703,57 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj voq jmp gMk xkI cGl -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj gMk gMk gMk gMk gMk gMk -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj vDa vDa vDa @@ -167738,7 +167772,7 @@ ajS ajS gdZ lAj -lyP +lEj hhX hhX hhX @@ -167926,56 +167960,56 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj syX cGl gMk syX gMk cGl -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj gMk gMk gMk -lyP +lEj gMk gMk gMk -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj gMk vDa gMk @@ -167995,7 +168029,7 @@ ajS ajS gdZ lAj -lyP +lEj hhX hhX hhX @@ -168183,11 +168217,11 @@ hhX umg asZ umg -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj ura syX qIA @@ -168195,22 +168229,22 @@ cGl gMk syX qIA -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj gMk gMk -lyP -lyP +lEj +lEj gMk gMk gMk @@ -168218,25 +168252,25 @@ gMk gMk gMk gMk -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj mUQ gMk gMk -lyP +lEj gMk vDa gMk -lyP +lEj lAj lAj lAj @@ -168252,7 +168286,7 @@ ajS ajS lxR lAj -lyP +lEj hhX hhX hhX @@ -168440,11 +168474,11 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj aHe gMk xkI @@ -168452,39 +168486,39 @@ syX jmp gMk cGl -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj gMk gMk gMk gMk gMk gMk -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj gMk iEl gMk @@ -168492,10 +168526,10 @@ gMk vDa vDa vDa -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj lAj fiI rts @@ -168509,10 +168543,10 @@ mRd sbo gdZ lAj -lyP +lEj fYe fYe -lyP +lEj hhX hhX hhX @@ -168697,50 +168731,50 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj syX cGl gMk gMk gMk -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj gMk gMk gMk -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj uet gMk iEl @@ -168748,11 +168782,11 @@ gMk gMk vDa gMk -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj lAj hXu xQe @@ -168769,7 +168803,7 @@ lAj fYe fYe fYe -lyP +lEj hhX hhX hhX @@ -168954,62 +168988,62 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj pfg pfg pfg -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj gMk gMk -lyP +lEj gMk uet -lyP -lyP +lEj +lEj gMk gMk -lyP +lEj gMk gMk mUQ -lyP -lyP +lEj +lEj vDa uet -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj lAj lAj lAj @@ -169026,7 +169060,7 @@ lAj fYe fYe fYe -lyP +lEj hhX hhX hhX @@ -169211,40 +169245,40 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj gMk gMk gMk -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj gMk gMk gMk @@ -169257,33 +169291,33 @@ gMk gMk gMk gMk -lyP -lyP -lyP +lEj +lEj +lEj vDa -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj gMk gMk gMk -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj fYe fYe fYe -lyP +lEj hhX hhX hhX @@ -169468,38 +169502,38 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj gMk gMk gMk -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj uet gMk gMk gMk -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj gMk gMk gMk @@ -169514,32 +169548,32 @@ gMk gMk gMk gMk -lyP -lyP -lyP +lEj +lEj +lEj vDa vDa -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj fYe fYe -lyP +lEj hhX hhX hhX @@ -169723,11 +169757,11 @@ mxt hhX hhX hhX -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj gvF gvF gvF @@ -169737,25 +169771,25 @@ gvF gvF gvF gvF -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj xUx uet -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj gMk nyq gMk uQl gMk gMk -lyP -lyP +lEj +lEj uet gMk gMk @@ -169763,37 +169797,37 @@ gMk gMk gMk gMk -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj gMk gMk gMk -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj vDa -lyP -lyP +lEj +lEj mUQ -lyP +lEj gMk gMk gMk gMk gMk -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj hhX hhX hhX @@ -169980,9 +170014,9 @@ mxt hhX hhX hhX -lyP -lyP -lyP +lEj +lEj +lEj gvF gvF gvF @@ -169994,42 +170028,42 @@ tqD mMO fhP gvF -lyP +lEj bKL gMk gMk rZg gMk gMk -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj gMk gMk gqm gMk gMk gMk -lyP -lyP +lEj +lEj gMk gMk gMk -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj gMk gMk -lyP -lyP +lEj +lEj woL woL cMJ @@ -170038,19 +170072,19 @@ stz stz gMk gMk -lyP +lEj gMk gMk gMk gMk -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj hhX hhX hhX @@ -170259,55 +170293,55 @@ gMk gMk gMk fVf -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj rBv gMk tbp gMk gMk -lyP +lEj gMk gMk gMk gMk -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj uet -lyP -lyP +lEj +lEj gMk -lyP -lyP +lEj +lEj woL eAk cMJ stz jPq woL -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj uet gMk -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj hhX hhX hhX @@ -170508,7 +170542,7 @@ gOc gOc gOc gvF -lyP +lEj xUx gMk gMk @@ -170516,27 +170550,27 @@ gMk gMk gMk gMk -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj gMk gMk -lyP +lEj uet -lyP +lEj mNZ gMk gMk gMk gMk -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj ent gMk gMk @@ -170555,16 +170589,16 @@ ltS ltS ltS ltS -lyP +lEj gMk gMk -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj hhX hhX hhX @@ -170765,8 +170799,8 @@ gOc gOc gOc gvF -lyP -lyP +lEj +lEj uet gMk tui @@ -170774,15 +170808,15 @@ gMk gMk gMk gMk -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj mNZ mNZ gMk @@ -170790,17 +170824,17 @@ gMk gMk gMk mNZ -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj gMk gMk gMk gMk gMk -lyP +lEj woL sVT cMJ @@ -170813,15 +170847,15 @@ lQL aoy ltS mpc -lyP +lEj gMk -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj hhX hhX hhX @@ -171005,7 +171039,7 @@ mwe dUl bGg sJT -lyP +lEj hhX hhX hhX @@ -171022,8 +171056,8 @@ gOc gOc gOc gvF -lyP -lyP +lEj +lEj hyM gMk cgu @@ -171032,14 +171066,14 @@ gMk gMk gMk gMk -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj mNZ mNZ mNZ @@ -171047,8 +171081,8 @@ gMk gMk gMk gMk -lyP -lyP +lEj +lEj kxB kxB kxB @@ -171059,7 +171093,7 @@ eOx kxB kxB bkk -jfO +bIS cMJ msi ppD @@ -171072,13 +171106,13 @@ lls mpc gMk gMk -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj hhX hhX hhX @@ -171262,7 +171296,7 @@ rBZ lPi meH sJT -lyP +lEj hhX hhX hhX @@ -171279,24 +171313,24 @@ gOc gOc gOc gvF -lyP -lyP -lyP +lEj +lEj +lEj gMk cgu yjm -lyP -lyP +lEj +lEj gMk gMk gMk -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj mNZ mNZ mNZ @@ -171304,8 +171338,8 @@ mNZ gMk gMk gMk -lyP -lyP +lEj +lEj kxB hhX hhX @@ -171328,17 +171362,17 @@ pVB pHr cXo tOw -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj hhX hhX hhX @@ -171502,7 +171536,7 @@ hhX hhX cxg cxg -lyP +lEj imZ mQE fTj @@ -171519,13 +171553,13 @@ tww jlL sJT ogb -lyP -lyP +lEj +lEj hhX fYe mNZ mNZ -lyP +lEj vfJ fhN obA @@ -171538,22 +171572,22 @@ cMZ cMZ cMZ cMZ -lyP +lEj uet cgu -lyP -lyP +lEj +lEj uet gMk qIA gMk -lyP -lyP -lyP +lEj +lEj +lEj uKm -lyP -lyP -lyP +lEj +lEj +lEj mNZ mNZ gMk @@ -171561,8 +171595,8 @@ mNZ mNZ gMk gMk -lyP -lyP +lEj +lEj kxB hhX xAy @@ -171586,16 +171620,16 @@ mry mpc gMk yeS -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj hhX hhX hhX @@ -171759,8 +171793,8 @@ hhX hhX cxg pvT -lyP -lyP +lEj +lEj mQE vNg kWb @@ -171775,9 +171809,9 @@ kWb sae sJT sJT -lyP -lyP -lyP +lEj +lEj +lEj hhX fYe mNZ @@ -171799,18 +171833,18 @@ ipx dVt cdl ipx -lyP -lyP +lEj +lEj gMk gMk gMk gMk -lyP -lyP +lEj +lEj kTV gMk -lyP -lyP +lEj +lEj fJz gMk gMk @@ -171843,16 +171877,16 @@ cuW cuW cuW cuW -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj hhX hhX hhX @@ -172015,9 +172049,9 @@ hhX hhX hhX hhX -lyP -lyP -lyP +lEj +lEj +lEj mQE lJv kWb @@ -172032,7 +172066,7 @@ kWb wYj pdo sJT -lyP +lEj uif hhX hhX @@ -172057,22 +172091,22 @@ dOg kqf ipx ipx -lyP +lEj gMk -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj xUx gMk gMk -lyP -lyP -lyP +lEj +lEj +lEj gMk gMk -lyP -lyP +lEj +lEj gMk gMk dtQ @@ -172102,14 +172136,14 @@ gun cuW cuW cuW -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj hhX hhX hhX @@ -172272,9 +172306,9 @@ hhX hhX hhX hhX -lyP -lyP -lyP +lEj +lEj +lEj kWb kWb kWb @@ -172289,8 +172323,8 @@ kWb kWb kWb kWb -lyP -lyP +lEj +lEj hhX hhX fYe @@ -172318,19 +172352,19 @@ xCX gMk xUx uet -lyP -lyP +lEj +lEj gMk ceN gMk gMk gMk -lyP +lEj xKx -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj gMk dtQ gMk @@ -172359,14 +172393,14 @@ yhy dlX iUq cuW -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj hhX hhX hhX @@ -172529,9 +172563,9 @@ hhX hhX hhX hhX -lyP -lyP -lyP +lEj +lEj +lEj kWb kWb kWb @@ -172545,9 +172579,9 @@ lRk kWb kWb kWb -lyP -lyP -lyP +lEj +lEj +lEj hhX hhX fYe @@ -172575,22 +172609,22 @@ xCX gMk gMk gMk -lyP -lyP -lyP +lEj +lEj +lEj lmn gMk -lyP +lEj gMk -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj gMk -lyP -lyP +lEj +lEj dtQ -lyP +lEj kxB hhX xAy @@ -172616,17 +172650,17 @@ pMw nME iJb cuW -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj hhX hhX hhX @@ -172786,8 +172820,8 @@ hhX hhX hhX hhX -lyP -lyP +lEj +lEj kWb kWb kWb @@ -172803,8 +172837,8 @@ qWB kWb kWb kWb -lyP -lyP +lEj +lEj hhX hhX hhX @@ -172828,26 +172862,26 @@ dRh xBU xje ipx -lyP +lEj gMk gMk -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj xIP xIP uKm elE -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj gMk vkv -lyP +lEj dtQ -lyP +lEj kxB hhX cLf @@ -172873,18 +172907,18 @@ jGP cYe qbZ cuW -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj hhX hhX hhX @@ -173043,8 +173077,8 @@ hhX hhX hhX hhX -lyP -lyP +lEj +lEj kWb kWb kWb @@ -173060,8 +173094,8 @@ vAB kWb kWb kWb -lyP -lyP +lEj +lEj hhX hhX hhX @@ -173089,15 +173123,15 @@ uKm mWS gMk ent -lyP +lEj gMk gMk gMk uet cPE gMk -lyP -lyP +lEj +lEj gMk gMk gMk @@ -173136,10 +173170,10 @@ aWD uYG uYG uYG -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj uYG uYG uYG @@ -173301,7 +173335,7 @@ hhX hhX hhX unk -lyP +lEj kWb kWb kWb @@ -173317,8 +173351,8 @@ vAB kWb kWb kWb -lyP -lyP +lEj +lEj hhX hhX hhX @@ -173342,20 +173376,20 @@ fFg fFg dhR ipx -lyP +lEj uet gMk -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj gMk xUx -lyP +lEj dsF gMk -lyP -lyP +lEj +lEj gMk gMk gMk @@ -173574,8 +173608,8 @@ qDl aKU kWb kWb -lyP -lyP +lEj +lEj hhX hhX fYe @@ -173599,22 +173633,22 @@ dVt dVt ipx ipx -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj gMk gMk xUx -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj gMk gMk dtQ @@ -173661,8 +173695,8 @@ tNE cEG cEG uYG -lyP -lyP +lEj +lEj jVV jVV jGa @@ -173815,7 +173849,7 @@ hhX hhX hhX unk -lyP +lEj kWb kWb kWb @@ -173831,8 +173865,8 @@ vAB kWb kWb kWb -lyP -lyP +lEj +lEj hhX hhX fYe @@ -173855,22 +173889,22 @@ vRA vRA vRA ixU -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj uet -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj xKo xKo xKo @@ -173918,8 +173952,8 @@ tNE tNE dYZ uYG -lyP -lyP +lEj +lEj jVV hhX hhX @@ -174071,8 +174105,8 @@ hhX hhX hhX hhX -lyP -lyP +lEj +lEj kWb kWb kWb @@ -174088,7 +174122,7 @@ vAB kWb kWb kWb -lyP +lEj hhX hhX hhX @@ -174112,9 +174146,9 @@ vRA vRA vRA ixU -lyP -lyP -lyP +lEj +lEj +lEj kxB uKm uKm @@ -174122,12 +174156,12 @@ uKm uKm uKm uKm -lyP +lEj gMk -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj xKo rhn lWF @@ -174328,8 +174362,8 @@ hhX hhX hhX hhX -lyP -lyP +lEj +lEj kWb kWb kWb @@ -174377,14 +174411,14 @@ iHO iHO jZY ouE -lyP +lEj lzE -lyP +lEj gMk gMk uet -lyP -lyP +lEj +lEj xKo ljN eqC @@ -174586,7 +174620,7 @@ hhX hhX hhX hhX -lyP +lEj kWb kWb kWb @@ -174636,12 +174670,12 @@ uKm uKm uKm uKm -lyP -lyP +lEj +lEj gMk gMk -lyP -lyP +lEj +lEj xKo fEQ eeB @@ -174844,7 +174878,7 @@ hhX hhX hhX hhX -lyP +lEj kWb kWb kWb @@ -174893,12 +174927,12 @@ twx twx twx twx -lyP -lyP +lEj +lEj gMk gMk -lyP -lyP +lEj +lEj xKo xKo xKo @@ -175101,8 +175135,8 @@ hhX hhX hhX hhX -lyP -lyP +lEj +lEj kWb kWb kWb @@ -175150,12 +175184,12 @@ twx twx twx twx -lyP -lyP +lEj +lEj gMk gMk -lyP -lyP +lEj +lEj xKo tmR xKo @@ -175359,16 +175393,16 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj kWb kWb kWb kWb kWb -lyP +lEj hhX hhX hhX @@ -175407,12 +175441,12 @@ twx twx twx twx -lyP +lEj uKm aXH gMk xUx -lyP +lEj xKo nqu ikD @@ -175458,11 +175492,11 @@ nUy uYG uYG uYG -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj jVV pnS hhX @@ -175617,8 +175651,8 @@ hhX hhX hhX hhX -lyP -lyP +lEj +lEj hhX hhX jVV @@ -175665,11 +175699,11 @@ twx twx twx uKm -lyP +lEj gMk -lyP -lyP -lyP +lEj +lEj +lEj xKo xKo xKo @@ -175716,10 +175750,10 @@ uYG hhX hhX hhX -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj jVV hhX vUj @@ -175924,9 +175958,9 @@ twx uKm xwA gMk -lyP -lyP -lyP +lEj +lEj +lEj xKo dor lVx @@ -175974,8 +176008,8 @@ hhX hhX hhX hhX -lyP -lyP +lEj +lEj hhX jVV hhX @@ -176181,9 +176215,9 @@ mxq uKm gMk uet -lyP -lyP -lyP +lEj +lEj +lEj xKo lVx bkk @@ -176224,14 +176258,14 @@ vzC aWD wlV aWD -lyP -lyP +lEj +lEj mUQ rGg rGg mUQ -lyP -lyP +lEj +lEj hhX hhX jVV @@ -176431,15 +176465,15 @@ ixU dtQ dtQ gMk -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj xUx -lyP -lyP -lyP +lEj +lEj +lEj ent cIN lVx @@ -176481,13 +176515,13 @@ xwm sCp sCp aWD -lyP -lyP -lyP +lEj +lEj +lEj tOG ufA -lyP -lyP +lEj +lEj uif hhX hhX @@ -176689,14 +176723,14 @@ dtQ gMk gMk gMk -lyP +lEj gMk -lyP +lEj uKm aXH lgL rQP -lyP +lEj gMk vWx dor @@ -176738,13 +176772,13 @@ xwm mog mog aWD -lyP -lyP -lyP +lEj +lEj +lEj uif fYe -lyP -lyP +lEj +lEj hhX hhX hhX @@ -176995,12 +177029,12 @@ muB mog mog aWD -lyP -lyP -lyP +lEj +lEj +lEj fYe fYe -lyP +lEj mUQ jVV hhX @@ -177252,8 +177286,8 @@ mog mog cYw aWD -lyP -lyP +lEj +lEj fYe fYe fYe @@ -177464,9 +177498,9 @@ sqL rlw khP rlw -lyP -lyP -lyP +lEj +lEj +lEj xKo wlR lNe @@ -177509,12 +177543,12 @@ mog mog mog aWD -lyP -lyP -lyP +lEj +lEj +lEj fYe -lyP -lyP +lEj +lEj mUQ eCF hhX @@ -177716,14 +177750,14 @@ ixU gMk gMk gMk -lyP -lyP +lEj +lEj sqL uoY sqL -lyP -lyP -lyP +lEj +lEj +lEj xKo jBG oEN @@ -177766,14 +177800,14 @@ mog mog mog aWD -lyP -lyP -lyP +lEj +lEj +lEj fYe -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj hhX hhX hhX @@ -177971,16 +178005,16 @@ xbC cIE ixU gMk -lyP +lEj gMk -lyP -lyP +lEj +lEj sqL uoY sqL gMk -lyP -nGi +lEj +poh woL iNv xKo @@ -178023,14 +178057,14 @@ bkW bkW bkW aWD -lyP -lyP +lEj +lEj fYe fYe fYe -lyP -lyP -lyP +lEj +lEj +lEj hhX hhX hhX @@ -178227,17 +178261,17 @@ lsx idr lsx hEi -lyP -lyP +lEj +lEj iOE -lyP -lyP +lEj +lEj sqL uoY gbP fWJ -nGi -nGi +poh +poh wPU uab qhG @@ -178280,13 +178314,13 @@ tel tel lhg uFC -lyP -lyP +lEj +lEj fYe -lyP +lEj fYe -lyP -lyP +lEj +lEj fYe hhX hhX @@ -178485,10 +178519,10 @@ cHn sAN hEi hEi -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj sqL uoY sqL @@ -178537,13 +178571,13 @@ tGb tGb xlG uFC -lyP -lyP +lEj +lEj fYe -lyP +lEj fYe -lyP -lyP +lEj +lEj fYe hhX hhX @@ -178744,8 +178778,8 @@ uaY iFN iFN iFN -lyP -lyP +lEj +lEj sqL uoY sqL @@ -178775,7 +178809,7 @@ pMG lXi ldl iZa -lyP +lEj uFC xlG tGb @@ -178794,13 +178828,13 @@ tGb tGb xlG uFC -lyP -lyP +lEj +lEj fYe -lyP +lEj fYe -lyP -lyP +lEj +lEj fYe hhX hhX @@ -179002,11 +179036,11 @@ iFN ekR iFN iFN -lyP +lEj rlw eGM rlw -lyP +lEj dsP nQs ohk @@ -179032,7 +179066,7 @@ lRU wZb vxp iZa -lyP +lEj uFC xlG tGb @@ -179051,13 +179085,13 @@ tGb tGb xlG uFC -lyP -lyP +lEj +lEj fYe tOG fYe -lyP -lyP +lEj +lEj uif hhX hhX @@ -179259,12 +179293,12 @@ qJN uHQ szk iFN -lyP +lEj sqL uoY sqL -lyP -nGi +lEj +poh alu ohk jMN @@ -179289,7 +179323,7 @@ qWT grz grz grz -lyP +lEj uFC xlG tGb @@ -179308,13 +179342,13 @@ tGb tGb xlG uFC -lyP +lEj uKm uKm iDu uKm uKm -lyP +lEj fYe hhX hhX @@ -179516,13 +179550,13 @@ kHf xkL uSX iFN -lyP +lEj sqL uoY sqL -lyP -nGi -nGi +lEj +poh +poh hFa tUc qhG @@ -179545,8 +179579,8 @@ uLS uyZ esc grz -lyP -lyP +lEj +lEj uFC xlG tGb @@ -179565,13 +179599,13 @@ tGb tGb xlG uFC -lyP -lyP +lEj +lEj iJm iJm iJm uKm -lyP +lEj fYe hhX hhX @@ -179773,16 +179807,16 @@ aXl fyJ aXl iFN -lyP +lEj sqL uoY sqL -lyP -lyP -lyP +lEj +lEj +lEj dsP -nGi -nGi +poh +poh stP tNK vkp @@ -179802,8 +179836,8 @@ urI kdE xjL grz -lyP -lyP +lEj +lEj uFC xlG tGb @@ -179822,7 +179856,7 @@ tGb tGb xlG uFC -lyP +lEj fYe fYe iJm @@ -180030,16 +180064,16 @@ mZn oND iem iFN -lyP +lEj sqL uoY sqL gMk -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj qhG pql qhG @@ -180059,8 +180093,8 @@ rAP odk jDl grz -lyP -lyP +lEj +lEj uFC pFg gsg @@ -180079,13 +180113,13 @@ tGb tGb xlG uFC -lyP +lEj fYe fYe fYe iJm uKm -lyP +lEj fYe hhX hhX @@ -180287,15 +180321,15 @@ rEv vjQ evN iFN -lyP +lEj sqL uoY sqL gMk -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj fYe vnb jCm @@ -180317,7 +180351,7 @@ odk kOU grz fYe -lyP +lEj uFC bMb xlG @@ -180336,13 +180370,13 @@ tGb tGb xgN uFC -lyP -lyP +lEj +lEj fYe -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj fYe hhX hhX @@ -180544,7 +180578,7 @@ iFN iFN iFN iFN -lyP +lEj eIO ehY rlw @@ -180593,13 +180627,13 @@ tGb tGb xlG uFC -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj hen -lyP -lyP +lEj +lEj hhX hhX hhX @@ -180797,11 +180831,11 @@ wkG wkG rzI moe -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj rlw wvS uCp @@ -180850,13 +180884,13 @@ tGb tGb xlG uFC -lyP +lEj hen hen hen hen -lyP -lyP +lEj +lEj hhX hhX hhX @@ -181054,10 +181088,10 @@ jYT jYT rIJ moe -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj hhX rlw sqL @@ -181112,8 +181146,8 @@ hen hen hen hen -lyP -lyP +lEj +lEj hhX hhX hhX @@ -181311,9 +181345,9 @@ wkG wkG wkG moe -lyP -lyP -lyP +lEj +lEj +lEj hhX hhX jVV @@ -181370,7 +181404,7 @@ hen hen hen kxB -lyP +lEj fYe hhX hhX @@ -181567,9 +181601,9 @@ jYT wkG ivx ivx -lyP -lyP -lyP +lEj +lEj +lEj hhX hhX hhX @@ -181626,8 +181660,8 @@ hen hen hen hen -lyP -lyP +lEj +lEj fYe hhX hhX @@ -181825,8 +181859,8 @@ moe rGg rGg fqD -lyP -lyP +lEj +lEj hhX hhX hhX @@ -181848,18 +181882,18 @@ tAo vbd vbd fYe -lyP -lyP +lEj +lEj hhX nbk smD pBC hhX -lyP -lyP -lyP +lEj +lEj +lEj fYe -lyP +lEj uFC uFC uFC @@ -181883,8 +181917,8 @@ hen hen hen hen -lyP -lyP +lEj +lEj fYe hhX hhX @@ -182105,42 +182139,42 @@ uLR avQ uLR tAo -lyP -lyP +lEj +lEj hhX hHZ mxt eRO hhX -lyP -lyP -lyP -fYe -lyP -lyP -hhX -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +fYe +lEj +lEj +hhX +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj hen hen hen hen hen -lyP +lEj fYe uif hhX @@ -182363,41 +182397,41 @@ fYe uLR fYe fYe -lyP -lyP +lEj +lEj hhX mxt hhX hhX -lyP -lyP -lyP -fYe -lyP -lyP -hhX -hhX -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +fYe +lEj +lEj +hhX +hhX +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj hen hen hen hen hen -lyP +lEj fYe hhX hhX @@ -182612,11 +182646,11 @@ rlw uVI uVI mUQ -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj mUQ uVI uVI @@ -182626,35 +182660,35 @@ hhX mxt hhX hhX -lyP -lyP +lEj +lEj fYe fYe -lyP -lyP +lEj +lEj hhX hhX hhX -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj gMk -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj hen hen hen hen hen hen -lyP +lEj fYe hhX hhX @@ -182868,13 +182902,13 @@ uoY sqL fYe fYe -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj fYe fYe fYe @@ -182887,31 +182921,31 @@ fYe fYe fYe fYe -lyP +lEj hhX hhX hhX hhX -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj gMk gMk -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj hen hen hen hen -lyP -lyP +lEj +lEj fYe hhX hhX @@ -183128,9 +183162,9 @@ hhX jVV hhX hhX -lyP +lEj hhX -lyP +lEj hhX hhX hhX @@ -183149,25 +183183,25 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj gMk xKx -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj hen hen -lyP -lyP +lEj +lEj uif fYe hhX @@ -183405,21 +183439,21 @@ rjp hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj bZr rjp rjp @@ -183662,21 +183696,21 @@ rjp rjp rjp bZr -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj hhX hhX hhX @@ -183920,20 +183954,20 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj +lEj hhX hhX hhX @@ -184178,18 +184212,18 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj +lEj +lEj hhX hhX -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj hhX hhX hhX @@ -184436,10 +184470,10 @@ hhX hhX hhX hhX -lyP -lyP -lyP -lyP +lEj +lEj +lEj +lEj hhX hhX hhX diff --git a/_maps/shuttles/emergency_casino.dmm b/_maps/shuttles/emergency_casino.dmm index e4521dc80b6c..1f28d476bf9f 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, /turf/open/floor/sepia, /area/shuttle/escape) "NN" = ( diff --git a/_maps/shuttles/emergency_shadow.dmm b/_maps/shuttles/emergency_shadow.dmm index ac2807c70f3e..b1b61cc376a8 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 b1b00f10d57f..61f8ea231df2 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 bb32515c5a1f..24c52bda672d 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/lazy_templates/nukie_base.dmm b/_maps/templates/lazy_templates/nukie_base.dmm index 537fe8fda84f..d025553bd8da 100644 --- a/_maps/templates/lazy_templates/nukie_base.dmm +++ b/_maps/templates/lazy_templates/nukie_base.dmm @@ -1181,11 +1181,11 @@ /obj/effect/turf_decal/siding/thinplating_new/dark{ dir = 1 }, -/obj/machinery/door/poddoor/shutters{ +/obj/structure/fans/tiny, +/obj/machinery/door/poddoor/shutters/syndicate{ id = "FBBZ1"; name = "Security Shutters" }, -/obj/structure/fans/tiny, /turf/open/floor/mineral/titanium, /area/centcom/syndicate_mothership/control) "nk" = ( @@ -1627,7 +1627,7 @@ dir = 1 }, /obj/effect/turf_decal/siding/wideplating, -/obj/machinery/door/poddoor/shutters/indestructible{ +/obj/machinery/door/poddoor/shutters/syndicate/indestructible{ name = "Subterrainian Cargo Lift" }, /turf/open/floor/iron/dark/textured_half, @@ -2390,12 +2390,9 @@ /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, /turf/open/floor/iron, /area/centcom/syndicate_mothership/control) "AO" = ( @@ -3672,10 +3669,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 +3810,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" = ( @@ -4354,11 +4351,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" = ( diff --git a/_maps/virtual_domains/fredingtonfastingbear.dmm b/_maps/virtual_domains/fredingtonfastingbear.dmm index 24174de946be..c792d2443fa8 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 417aad431b54..0019fbd857fa 100644 --- a/code/__DEFINES/DNA.dm +++ b/code/__DEFINES/DNA.dm @@ -31,7 +31,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" diff --git a/code/__DEFINES/access.dm b/code/__DEFINES/access.dm index b139ef6713b2..7f5487651f92 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/bot_keys.dm b/code/__DEFINES/ai/bot_keys.dm index c12f48273eec..0c7758f61348 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/basic_mobs.dm b/code/__DEFINES/basic_mobs.dm index 32360a21260f..1a97163a8715 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/cameranets.dm b/code/__DEFINES/cameranets.dm index 20add763b122..1201705d627e 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/construction/material.dm b/code/__DEFINES/construction/material.dm index 7e5c6d6263a4..59a7b1b74ec2 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 8933490dc664..66a4ffc894b6 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_mob/signals_mob_carbon.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm index 3c7e95a5a4b7..993a29274255 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm @@ -63,7 +63,7 @@ /// 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 +205,10 @@ #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" 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 d8815eb694a2..828a2aa73b07 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm @@ -395,3 +395,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 b3b6acefd232..cf26bbbad24b 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_object.dm b/code/__DEFINES/dcs/signals/signals_object.dm index 3081b60449fc..08e024bec8ad 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" diff --git a/code/__DEFINES/inventory.dm b/code/__DEFINES/inventory.dm index a382d3b985a6..b5922c2f5273 100644 --- a/code/__DEFINES/inventory.dm +++ b/code/__DEFINES/inventory.dm @@ -181,6 +181,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 @@ -211,7 +212,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 2f0183f42ec4..c551998af2ac 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/jobs.dm b/code/__DEFINES/jobs.dm index 7e68043000d6..a372cc8e9020 100644 --- a/code/__DEFINES/jobs.dm +++ b/code/__DEFINES/jobs.dm @@ -17,14 +17,16 @@ #define JOB_UNAVAILABLE_SPLAT_SLOTS 9 /// Checks for character whitelist. #define JOB_UNAVAILABLE_WHITELIST 10 -/// Checks for character kindred age. -#define JOB_UNAVAILABLE_KINDRED_AGE 11 +/// Checks for character kindred age. (Minium age) +#define JOB_UNAVAILABLE_KINDRED_AGE_MIN 11 +/// Checks for character kindred age. (Maximum age) +#define JOB_UNAVAILABLE_KINDRED_AGE_MAX 12 /// Checks for character kindred generation. -#define JOB_UNAVAILABLE_KINDRED_GENERATION 12 +#define JOB_UNAVAILABLE_KINDRED_GENERATION 13 /// Checks for character clan. -#define JOB_UNAVAILABLE_KINDRED_CLAN 13 -#define JOB_UNAVAILABLE_FERA_TRIBE 14 -#define JOB_UNAVAILABLE_FERA_AUSPICE 15 +#define JOB_UNAVAILABLE_KINDRED_CLAN 14 +#define JOB_UNAVAILABLE_FERA_TRIBE 15 +#define JOB_UNAVAILABLE_FERA_AUSPICE 16 // DARKPACK EDIT ADD END diff --git a/code/__DEFINES/keybinding.dm b/code/__DEFINES/keybinding.dm index 1e88e16d5d72..73da7d1924c0 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 2115ce4a5dd4..de8e74b79cd7 100644 --- a/code/__DEFINES/lag_switch.dm +++ b/code/__DEFINES/lag_switch.dm @@ -16,5 +16,7 @@ #define DISABLE_PARALLAX 7 /// Disables footsteps, TRAIT_BYPASS_MEASURES exempted #define DISABLE_FOOTSTEPS 8 +/// Disables runechat for ghosts +#define DISABLE_DEAD_RUNECHAT 9 -#define MEASURES_AMOUNT 8 // The total number of switches defined above +#define MEASURES_AMOUNT 9 // The total number of switches defined above diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index 596f8134ebaa..1b64aaeb0d37 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -39,12 +39,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 diff --git a/code/__DEFINES/mining.dm b/code/__DEFINES/mining.dm index 6c660299563d..f71f30a70837 100644 --- a/code/__DEFINES/mining.dm +++ b/code/__DEFINES/mining.dm @@ -44,8 +44,6 @@ /// 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.5 // String defines to use with CaveGenerator presets for what ore breakdown to use. #define OREGEN_PRESET_LAVALAND "lavaland" @@ -63,3 +61,8 @@ /// 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 6eab221d0160..4d0e8fe53635 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -182,6 +182,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" @@ -838,7 +839,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 @@ -855,6 +857,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, @@ -863,7 +866,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) diff --git a/code/__DEFINES/paper.dm b/code/__DEFINES/paper.dm index e77086a40e5e..ff4c4a508563 100644 --- a/code/__DEFINES/paper.dm +++ b/code/__DEFINES/paper.dm @@ -43,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/reagents.dm b/code/__DEFINES/reagents.dm index 8af05df6ca07..0df7396b5447 100644 --- a/code/__DEFINES/reagents.dm +++ b/code/__DEFINES/reagents.dm @@ -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 5b14301927e7..2c76b6f3b91c 100644 --- a/code/__DEFINES/robots.dm +++ b/code/__DEFINES/robots.dm @@ -219,6 +219,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 3f0f09d74f60..5cf51eef8748 100644 --- a/code/__DEFINES/say.dm +++ b/code/__DEFINES/say.dm @@ -146,3 +146,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 ab88e6e2c30b..610a03a9e46f 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/span.dm b/code/__DEFINES/span.dm index fe70a5366b76..4c13ae804fd0 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 1d69909c31c1..ba15414a883e 100644 --- a/code/__DEFINES/speech_channels.dm +++ b/code/__DEFINES/speech_channels.dm @@ -4,5 +4,6 @@ #define ME_CHANNEL "Me" #define OOC_CHANNEL "OOC" #define ADMIN_CHANNEL "Admin" +#define PRAY_CHANNEL "Pray" #define LOOC_CHANNEL "LOOC" // DARKPACK EDIT ADD - LOOC #define DO_CHANNEL "Do" // DARKPACK EDIT ADD - DO_EMOTES diff --git a/code/__DEFINES/time.dm b/code/__DEFINES/time.dm index 210b5fc65b68..ea8a8c0f0e0b 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 -17 // DARKPACK EDIT ///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 -17 // DARKPACK EDIT - #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 9f6b8783e006..1c8db1602259 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 d35653f354bd..4a16d6102313 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 @@ -1222,9 +1220,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" @@ -1429,6 +1424,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" diff --git a/code/__DEFINES/vv.dm b/code/__DEFINES/vv.dm index 3b53072e1960..f6ae682fc9b4 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/~darkpack/fera/fera.dm b/code/__DEFINES/~darkpack/fera/fera.dm index 5eb76a3149ab..6a2f0b7a33f9 100644 --- a/code/__DEFINES/~darkpack/fera/fera.dm +++ b/code/__DEFINES/~darkpack/fera/fera.dm @@ -25,4 +25,5 @@ GLOBAL_LIST_INIT(garou_fur_colors, list( "brown" = "brown" )) +#define STATUS_EFFECT_DELIRIUM /datum/status_effect/delirium #define STATUS_EFFECT_SILVER_BULLET_STACKS /datum/status_effect/stacking/silver_bullets diff --git a/code/__DEFINES/~darkpack/flavor_text.dm b/code/__DEFINES/~darkpack/flavor_text.dm index 6ea5c18d398a..92b8f975df57 100644 --- a/code/__DEFINES/~darkpack/flavor_text.dm +++ b/code/__DEFINES/~darkpack/flavor_text.dm @@ -4,6 +4,8 @@ #define EXAMINE_DNA_HEADSHOT "headshot" /// Examine Panel flavor text #define EXAMINE_DNA_FLAVOR_TEXT "flavor_text" +#define EXAMINE_DNA_WAR_FORM_FLAVOR_TEXT "war_form_flavor_text" +#define EXAMINE_DNA_FERAL_FORM_FLAVOR_TEXT "feral_form_flavor_text" /// Examine Panel flavor text #define EXAMINE_DNA_NSFW_FLAVOR_TEXT "nsfw_flavor_text" /// Examine Panel OOC notes diff --git a/code/__DEFINES/~darkpack/jobs.dm b/code/__DEFINES/~darkpack/jobs.dm index cfe8b58874e8..d234471e43d7 100644 --- a/code/__DEFINES/~darkpack/jobs.dm +++ b/code/__DEFINES/~darkpack/jobs.dm @@ -103,6 +103,12 @@ #define JOB_PENTEX_SEC "Security Agent" #define JOB_PENTEX_EMPLOYEE "Employee" +// Society of Leopold +#define JOB_NOVICE "Novice" +#define JOB_ABBE "Abbe" +#define JOB_CONDOTTIERI "Condottieri" +#define JOB_INQUISITOR "Inquisitor" + ////////////////////////////////////////////////// #define JOB_DISPLAY_ORDER_CITIZEN 1 @@ -172,6 +178,11 @@ #define JOB_DISPLAY_ORDER_PENTEX_SEC 52 #define JOB_DISPLAY_ORDER_EMPLOYEE 53 +#define JOB_DISPLAY_ORDER_ABBE 54 +#define JOB_DISPLAY_ORDER_INQUISITOR 55 +#define JOB_DISPLAY_ORDER_CONDOTTIERI 56 +#define JOB_DISPLAY_ORDER_NOVICE 57 + ////////////////////////////////////////////////// #define DEPARTMENT_BITFLAG_CITIZEN (1<<0) @@ -206,6 +217,8 @@ #define DEPARTMENT_PENTEX "Pentex" #define DEPARTMENT_BITFLAG_GAIA (1<<15) #define DEPARTMENT_GAIA "Garou_Nation" +#define DEPARTMENT_BITFLAG_SOCIETY_OF_LEOPOLD (1<<16) +#define DEPARTMENT_SOCIETY_OF_LEOPOLD "Society_of_Leopold" DEFINE_BITFIELD(departments_bitflags, list( "CITIZEN" = DEPARTMENT_BITFLAG_CITIZEN, @@ -224,6 +237,7 @@ DEFINE_BITFIELD(departments_bitflags, list( "CHANTRY" = DEPARTMENT_BITFLAG_CHANTRY, "MANOR" = DEPARTMENT_BITFLAG_MANOR, "CITY_SERVICES" = DEPARTMENT_BITFLAG_CITY_SERVICES, + "SOCIETY_OF_LEOPOLD" = DEPARTMENT_BITFLAG_SOCIETY_OF_LEOPOLD, )) /// Combination flag for jobs which are considered regular crew members of the station. @@ -244,6 +258,7 @@ DEFINE_BITFIELD(departments_bitflags, list( #define SUPERVISOR_REGENT "the Regent" #define SUPERVISOR_SENESCHAL_PUBLIC "the COO" #define SUPERVISOR_BARON_PUBLIC "the Bar's Owner" +#define SUPERVISOR_SOCIETY_OF_LEOPOLD "the Society of Leopold, the Inquisition, the local Provincial, and God" // Playtime tracking system, see jobs_exp.dm #define EXP_TYPE_KINDRED "Kindred" diff --git a/code/__DEFINES/~darkpack/names.dm b/code/__DEFINES/~darkpack/names.dm index fcf4b82a1120..39632426b3d8 100644 --- a/code/__DEFINES/~darkpack/names.dm +++ b/code/__DEFINES/~darkpack/names.dm @@ -2,3 +2,4 @@ GLOBAL_LIST_INIT(bahari_quotes, world.file2list("strings/quotes/bahari.txt")) GLOBAL_LIST_INIT(noddist_quotes, world.file2list("strings/quotes/noddist.txt")) GLOBAL_LIST_INIT(quran_quotes, world.file2list("strings/quotes/islam.txt")) +GLOBAL_LIST_INIT(bible_quotes, world.file2list("strings/quotes/bible.txt")) diff --git a/code/__DEFINES/~darkpack/spirit_defines.dm b/code/__DEFINES/~darkpack/spirit_defines.dm new file mode 100644 index 000000000000..e440e8468f7f --- /dev/null +++ b/code/__DEFINES/~darkpack/spirit_defines.dm @@ -0,0 +1,45 @@ +#define SPIRIT_ATHERIAL "aetherial" +#define SPIRIT_ANAMAE "anamae" +#define SPIRIT_ANCESTOR "ancestor spirit" +#define SPIRIT_ANIMAL "animal" +#define SPIRIT_AUTOMATA "automata" +#define SPIRIT_CHIMERA "chimera's brood" +#define SPIRIT_COCKROACH "cockroach's brood" +#define SPIRIT_CONSOR "consor" +#define SPIRIT_DARKNESS "darkness" +#define SPIRIT_DEMON "demon" +#define SPIRIT_DJINN "djinn" +#define SPIRIT_DREAM "dream" +#define SPIRIT_ELEMENTAL "elemental" +#define SPIRIT_ELEMENTAL_WYRM "wyrm elemental" +#define SPIRIT_ENIGMATIC "enigmatic" +#define SPIRIT_EPIHLING "epiphling" +#define SPIRIT_FALCON "falcon's brood" +#define SPIRIT_FENRIS "fenris's brood" +#define SPIRIT_GRANDFATHER_THUNDER "grandfather thunder's brood" +#define SPIRIT_GRIFFIN "griffin's brood" +#define SPIRIT_GUARDIAN "guardian" +#define SPIRIT_MIDREALM "midrealm" +#define SPIRIT_MINION "minion" +#define SPIRIT_NATURAE "naturae" +#define SPIRIT_NIGHT "night" +#define SPIRIT_OTHER "other" +#define SPIRIT_OWL "owl's brood" +#define SPIRIT_PARADOX "paradox" +#define SPIRIT_PEGASUS "pegasus's brood" +#define SPIRIT_PRECEPTOR "preceptor" +#define SPIRIT_RAT "rat's brood" +#define SPIRIT_SEA "sea" +#define SPIRIT_STAG "stag's brood" +#define SPIRIT_STORM_BORN "storm-born" +#define SPIRIT_UKTENA "uktena's brood" +#define SPIRIT_UMBROOD_LORD "umbrood lord" +#define SPIRIT_UNICORN "unicorn's brood" +#define SPIRIT_VENGEANCE "vengeance" +#define SPIRIT_VIRTUE "virtue" +#define SPIRIT_WEAVER "weaver" +#define SPIRIT_AMAROK "amarok's brood" +#define SPIRIT_WYLD "wyld" +#define SPIRIT_WYRM "wyrm" +#define SPIRIT_YANG "yang" +#define SPIRIT_YIN "yin" diff --git a/code/__DEFINES/~darkpack/traits/declarations.dm b/code/__DEFINES/~darkpack/traits/declarations.dm index 5fc637e1b77b..15d361e121fa 100644 --- a/code/__DEFINES/~darkpack/traits/declarations.dm +++ b/code/__DEFINES/~darkpack/traits/declarations.dm @@ -124,6 +124,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai // If the vampire can't perform mental abilities that require eye contact, as an example: dominate. #define TRAIT_NO_EYE_CONTACT "no_eye_contact" +// If the splat shifts between diffrent forms as a fera +#define TRAIT_FERA_FORMS "fera_forms" // If the splat uses the WTA renown system described in W20 p. 245 #define TRAIT_FERA_RENOWN "wta_fera_renown" /// If the species has garou breeds to select. diff --git a/code/__HELPERS/logging/mob.dm b/code/__HELPERS/logging/mob.dm index adcc9170d30c..0e0464b60cc2 100644 --- a/code/__HELPERS/logging/mob.dm +++ b/code/__HELPERS/logging/mob.dm @@ -50,7 +50,7 @@ colored_message = "(SUBTLE) [colored_message]" // DARKPACK EDIT ADD END - 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 f352123f9a2a..704e8cb6c45b 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 a138dbdbf0f3..cdb4edb0098f 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -378,9 +378,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) @@ -398,17 +400,17 @@ 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 // DARKPACK EDIT ADD START if(HAS_TRAIT(M, TRAIT_LOCAL_SIXTHSENSE) && (message_type == DEADCHAT_REGULAR) && (source in orange(DEFAULT_MESSAGE_RANGE, M))) - override = TRUE + override = SEE_DEADCHAT_NORMAL // DARKPACK EDIT ADD END if(SSticker.current_state == GAME_STATE_FINISHED) - override = TRUE + override = SEE_DEADCHAT_NORMAL if(isnewplayer(M) && !override) continue if(M.stat != DEAD && !override) @@ -432,6 +434,7 @@ GLOBAL_LIST_INIT(skin_tone_names, list( if(isobserver(M)) var/rendered_message = message + override = SEE_DEADCHAT_NORMAL if(follow_target) var/F @@ -448,6 +451,13 @@ 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/time.dm b/code/__HELPERS/time.dm index 59e95ad8e85f..bee7fc6fe03e 100644 --- a/code/__HELPERS/time.dm +++ b/code/__HELPERS/time.dm @@ -1,30 +1,23 @@ -/// 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) + // DARKPACK EDIT ADD START - CITY_TIME + if(ic_time) + var/time_string = twelve_hour_clock ? time_to_twelve_hour(format, city_time(), NO_TIMEZONE) : time2text(city_time(), format, NO_TIMEZONE) + if(findtext(format, "YYYY")) //if we have a year, replace the year + time_string = replacetext_char(time_string, "[GLOB.year_integer]", CURRENT_STATION_YEAR) + return time_string + // DARKPACK EDIT ADD END + var/time_string = twelve_hour_clock ? time_to_twelve_hour(format, world.timeofday, world.timezone) : time2text(world.timeofday, format, world.timezone) + /* // DARKPACK EDIT REMOVAL - CITY_TIME + 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 +121,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 +130,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/visual_effects.dm b/code/__HELPERS/visual_effects.dm index c8720ba46eea..76bc1c9f0662 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/darkpack/lists/phone_contacts.dm b/code/_globalvars/darkpack/lists/phone_contacts.dm index dbb5cf9bcb8e..d762a4914634 100644 --- a/code/_globalvars/darkpack/lists/phone_contacts.dm +++ b/code/_globalvars/darkpack/lists/phone_contacts.dm @@ -14,6 +14,7 @@ GLOBAL_LIST_EMPTY(anarch_network) GLOBAL_LIST_EMPTY(supply_network) GLOBAL_LIST_EMPTY(vampire_leader_network) GLOBAL_LIST_EMPTY(endron_network) +GLOBAL_LIST_EMPTY(society_network) #define MILLENIUM_TOWER_NETWORK 1 #define LASOMBRA_NETWORK 2 @@ -24,6 +25,7 @@ GLOBAL_LIST_EMPTY(endron_network) #define SUPPLY_NETWORK 7 #define VAMPIRE_LEADER_NETWORK 8 #define ENDRON_NETWORK 9 +#define SOCIETY_OF_LEOPOLD_NETWORK 10 // An indexed list of all the different phone networks that connect the phones that are part of them together. GLOBAL_LIST_INIT(contact_networks, alist( @@ -36,4 +38,5 @@ GLOBAL_LIST_INIT(contact_networks, alist( SUPPLY_NETWORK = GLOB.supply_network, VAMPIRE_LEADER_NETWORK = GLOB.vampire_leader_network, ENDRON_NETWORK = GLOB.endron_network, + SOCIETY_OF_LEOPOLD_NETWORK = GLOB.society_network, )) diff --git a/code/_globalvars/layers.dm b/code/_globalvars/layers.dm new file mode 100644 index 000000000000..e90c38756d54 --- /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 b8ad73d7e584..30e78113294c 100644 --- a/code/_globalvars/lists/maintenance_loot.dm +++ b/code/_globalvars/lists/maintenance_loot.dm @@ -351,11 +351,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/reagents.dm b/code/_globalvars/lists/reagents.dm index d94c62a7a24e..cbed6116d05a 100644 --- a/code/_globalvars/lists/reagents.dm +++ b/code/_globalvars/lists/reagents.dm @@ -134,7 +134,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 8bf5fd8cb257..a13ed9e5c7b7 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/time_vars.dm b/code/_globalvars/time_vars.dm index fd9b925e0d4f..a006a4bc699d 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 ce73e59955f3..34ede6349de4 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -172,6 +172,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, @@ -346,7 +347,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, @@ -448,7 +448,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, @@ -693,6 +692,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_ENHANCED_MELEE_DODGE" = TRAIT_ENHANCED_MELEE_DODGE, // DARKPACK EDIT ADD "TRAIT_FAIR_GLABRO" = TRAIT_FAIR_GLABRO, // DARKPACK EDIT ADD - MERITS_FLAWS "TRAIT_FEEDING_RESTRICTION" = TRAIT_FEEDING_RESTRICTION, // DARKPACK EDIT ADD + "TRAIT_FERA_FORMS" = TRAIT_FERA_FORMS, // DARKPACK EDIT ADD - WEREWOLF "TRAIT_FERA_FUR" = TRAIT_FERA_FUR, // DARKPACK EDIT ADD - WEREWOLF "TRAIT_FERA_RENOWN" = TRAIT_FERA_RENOWN, // DARKPACK EDIT ADD - WEREWOLF "TRAIT_FORCED_EMOTION" = TRAIT_FORCED_EMOTION, // DARKPACK EDIT ADD - Melpominee @@ -742,10 +742,10 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_STAKED" = TRAIT_STAKED, // DARKPACK EDIT ADD "TRAIT_STAKE_IMMUNE" = TRAIT_STAKE_IMMUNE, // DARKPACK EDIT ADD "TRAIT_STAKE_RESISTANT" = TRAIT_STAKE_RESISTANT, // DARKPACK EDIT ADD - "TRAIT_THE_LARGEST_MAW" = TRAIT_THE_LARGEST_MAW, // DARKPACK EDIT ADD - MERITS/FLAWS - "TRAIT_THIRD_EYE" = TRAIT_THIRD_EYE, // DARKPACK EDIT ADD - Tremere & Salubri Quirk "TRAIT_STILLNESS_OF_DEATH" = TRAIT_STILLNESS_OF_DEATH, // DARKPACK EDIT ADD - Gargoyle Quirk "TRAIT_THE_LARGEST_MAW" = TRAIT_THE_LARGEST_MAW, // DARKPACK EDIT ADD - MERITS/FLAWS + "TRAIT_THE_LARGEST_MAW" = TRAIT_THE_LARGEST_MAW, // DARKPACK EDIT ADD - MERITS/FLAWS + "TRAIT_THIRD_EYE" = TRAIT_THIRD_EYE, // DARKPACK EDIT ADD - Tremere & Salubri Quirk "TRAIT_TIMEWARPER" = TRAIT_TIMEWARPER, // DARKPACK EDIT ADD "TRAIT_TIME_SENSE" = TRAIT_TIME_SENSE, // DARKPACK EDIT ADD - MERITS_FLAWS "TRAIT_TORPOR" = TRAIT_TORPOR, // DARKPACK EDIT ADD diff --git a/code/_globalvars/traits/admin_tooling.dm b/code/_globalvars/traits/admin_tooling.dm index 1c3ea433381f..a361a289db94 100644 --- a/code/_globalvars/traits/admin_tooling.dm +++ b/code/_globalvars/traits/admin_tooling.dm @@ -40,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 +148,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, diff --git a/code/_onclick/hud/alien.dm b/code/_onclick/hud/alien.dm index 50121d853a53..72b17e7cecd4 100644 --- a/code/_onclick/hud/alien.dm +++ b/code/_onclick/hud/alien.dm @@ -30,7 +30,7 @@ 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) + add_screen_object(/atom/movable/screen/alien/alien_queen_finder, HUD_ALIEN_QUEEN_FINDER, HUD_GROUP_INFO) /datum/hud/alien/persistent_inventory_update() if(!mymob) 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 36fd9f37d2d6..6cfafcd6797a 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 ad48e91f6f8b..4cf64e24842f 100644 --- a/code/_onclick/hud/rendering/render_plate.dm +++ b/code/_onclick/hud/rendering/render_plate.dm @@ -133,7 +133,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) @@ -156,6 +156,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/screen_objects/new_player.dm b/code/_onclick/hud/screen_objects/new_player.dm index 18440824314c..12600cbc16a6 100644 --- a/code/_onclick/hud/screen_objects/new_player.dm +++ b/code/_onclick/hud/screen_objects/new_player.dm @@ -581,7 +581,8 @@ . = ..() if(!. || !usr.client.is_localhost() || !check_rights_for(usr.client, R_SERVER)) return - SEND_SOUND(hud.mymob, sound('modular_darkpack/master_files/sounds/start_now.ogg', volume = 100)) // DARKPACK EDIT CHANGE + if(SSticker.start_immediately != TRUE) // DARKPACK EDIT ADD + SEND_SOUND(hud.mymob, sound('modular_darkpack/master_files/sounds/start_now.ogg', volume = 50)) // DARKPACK EDIT CHANGE SSticker.start_immediately = TRUE if(SSticker.current_state == GAME_STATE_STARTUP) to_chat(usr, span_admin("The server is still setting up, but the round will be started as soon as possible.")) @@ -695,7 +696,7 @@ 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/other_mobs.dm b/code/_onclick/other_mobs.dm index 9098dfc1a3a1..ecb8f6d7d59e 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -190,7 +190,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 34e3ff0f18a3..cb38d2f9d078 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -396,25 +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 - -// In deciseconds and using station_time_rate_multiplier -/datum/config_entry/number/time_till_day - default = 198000 - protection = CONFIG_ENTRY_LOCKED - -// In deciseconds and using station_time_rate_multiplier -/datum/config_entry/number/time_till_roundend - default = 216000 - protection = CONFIG_ENTRY_LOCKED - /datum/config_entry/number/monkeycap default = 64 min_val = 0 @@ -496,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/economy.dm b/code/controllers/subsystem/economy.dm index 85cc898ad6d1..321567705d4e 100644 --- a/code/controllers/subsystem/economy.dm +++ b/code/controllers/subsystem/economy.dm @@ -219,7 +219,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/events.dm b/code/controllers/subsystem/events.dm index 1aea336e3752..5a9bd31b568c 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -24,8 +24,12 @@ SUBSYSTEM_DEF(events) var/wizardmode = FALSE /datum/controller/subsystem/events/Initialize() - for(var/type in typesof(/datum/round_event_control)) - var/datum/round_event_control/event = new type() + // DARKPACK EDIT CHANGE START - EVENTS + for(var/datum/round_event_control/event_typepath as anything in valid_subtypesof(/datum/round_event_control)) + if(!event_typepath::darkpack_allowed) + continue + var/datum/round_event_control/event = new event_typepath() + // DARKPACK EDIT CHANGE END if(!event.typepath) continue if(!event.valid_for_map()) diff --git a/code/controllers/subsystem/explosions.dm b/code/controllers/subsystem/explosions.dm index f5c733c0fd6a..4e7d0d5fb8ae 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/lag_switch.dm b/code/controllers/subsystem/lag_switch.dm index 70979b40816f..f70b3e70709b 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 diff --git a/code/controllers/subsystem/lighting.dm b/code/controllers/subsystem/lighting.dm index 4717e7dcf8cd..d35a58b6ab68 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 7086ef24206c..ae5e9400696d 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -761,11 +761,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 @@ -802,11 +797,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) @@ -892,11 +882,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/networks/modular_computers.dm b/code/controllers/subsystem/networks/modular_computers.dm index eb25e0c97aee..40ce21c51cd7 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 170f12696147..000000000000 --- 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/persistence/recipes.dm b/code/controllers/subsystem/persistence/recipes.dm index c1d72d8d9088..828f856b76a8 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 45dd31c7f5c9..d4b7ded137a2 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/quirks.dm b/code/controllers/subsystem/processing/quirks.dm index fbbe8a62c997..5015e5ea07ed 100644 --- a/code/controllers/subsystem/processing/quirks.dm +++ b/code/controllers/subsystem/processing/quirks.dm @@ -56,8 +56,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 @@ -118,7 +127,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 @@ -182,9 +190,7 @@ PROCESSING_SUBSYSTEM_DEF(quirks) /datum/controller/subsystem/processing/quirks/proc/filter_invalid_quirks(list/quirks) 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 2e48d593faec..c88237ec7eaa 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/shuttle.dm b/code/controllers/subsystem/shuttle.dm index 415d524b9c5b..0b29ee9f042d 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -187,9 +187,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 6b814820753f..7fea51076dba 100644 --- a/code/controllers/subsystem/statpanel.dm +++ b/code/controllers/subsystem/statpanel.dm @@ -37,9 +37,8 @@ SUBSYSTEM_DEF(statpanels) global_data += list( "Round ID: [GLOB.round_id ? GLOB.round_id : "NULL"]", - "Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss", world.timezone)]", - "Round Time: [ROUND_TIME()]", - // "Station Time: [station_time_timestamp()]", // DARKPACK EDIT REMOVAL - MERITS_FLAWS - (Time sense) + "Server Time: [server_timestamp(format = "YYYY-MM-DD hh:mm:ss")]", // DARKPACK EDIT CHANGE - CITY_TIME + "Round Time: [(SSticker.round_start_time == 0) ? "Pre-Game" : round_timestamp()]", // DARKPACK EDIT CHANGE - CITY_TIME "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)]%)", "\n", // DARKPACK EDIT ADD "Canon: [GLOB.canon_event ? "Yes" : "No"]", // DARKPACK EDIT ADD diff --git a/code/controllers/subsystem/tgui.dm b/code/controllers/subsystem/tgui.dm index 9f5d518b6c2a..df33cf68c8c7 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/ticker.dm b/code/controllers/subsystem/ticker.dm index d0d7ccc37a81..82b0c4d396b4 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -38,8 +38,8 @@ SUBSYSTEM_DEF(ticker) var/timeLeft //pregame timer var/start_at - var/gametime_offset = 21 HOURS //Deciseconds to add to world.time for station time. // DARKPACK EDIT CHANGE - ORIGINAL: var/gametime_offset = 432000 - var/station_time_rate_multiplier = 2 //factor of station time progressal vs real time. // DARKPACK EDIT CHANGE - ORIGINAL: var/station_time_rate_multiplier = 12 + var/gametime_offset = 21 HOURS //Deciseconds to add to world.time for station time. // DARKPACK EDIT ADD - CITY_TIME + var/city_time_rate_multiplier = 2 //factor of station time progressal vs real time. // DARKPACK EDIT CHANGE - CITY_TIME /// Num of players, used for pregame stats on statpanel var/totalPlayers = 0 @@ -132,21 +132,17 @@ SUBSYSTEM_DEF(ticker) GLOB.syndicate_code_response_regex = codeword_match start_at = world.time + (CONFIG_GET(number/lobby_countdown) * (1 SECONDS)) + // DARKPACK EDIT ADD START - CITY_TIME round_start_time = start_at // May be changed later, but prevents the time from jumping back when the round actually starts - 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 - station_time_rate_multiplier = 1 - else - gametime_offset = (CONFIG_GET(number/shift_time_start_hour) * (1 HOURS)) + gametime_offset = (CONFIG_GET(number/shift_time_start_hour) * (1 HOURS)) + // DARKPACK EDIT ADD END 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()]!")) @@ -157,9 +153,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 @@ -192,7 +188,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) diff --git a/code/datums/actions/items/adjust.dm b/code/datums/actions/items/adjust.dm index be04a0f8dbdd..13189c533c07 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/ai/basic_mobs/basic_ai_behaviors/basic_attacking.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/basic_attacking.dm index 2e145c31ec4b..9d9f995e17fd 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,7 +18,7 @@ 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] @@ -57,6 +59,8 @@ /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) diff --git a/code/datums/ai/dog/dog_behaviors.dm b/code/datums/ai/dog/dog_behaviors.dm index 6ae1529d4700..dc031a1d3f11 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/communications.dm b/code/datums/communications.dm index c3dd97c97129..116224d7265a 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/crafting/crafting.dm b/code/datums/components/crafting/crafting.dm index 0033e58669fb..66b867bbdc4b 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 a1d55a785ecc..ec4cd62df1d0 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/robot.dm b/code/datums/components/crafting/robot.dm index 053151673bc4..73a86eaf8a8b 100644 --- a/code/datums/components/crafting/robot.dm +++ b/code/datums/components/crafting/robot.dm @@ -1,6 +1,6 @@ /* /datum/crafting_recipe/ed209 // DARKPACK EDIT REMOVAL 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/manual_blinking.dm b/code/datums/components/manual_blinking.dm index aed2c531e3d9..b02646dc6868 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 289e600c509c..3f3af944f68b 100644 --- a/code/datums/components/plumbing/_plumbing.dm +++ b/code/datums/components/plumbing/_plumbing.dm @@ -20,6 +20,11 @@ /// Ex - if this was set to "3", our component would only request the first 3 reagents found, even if more are available var/distinct_reagent_cap = INFINITY + ///Extra offset on supply pipe. + var/supply_offset = 0 + ///Extra offset on demand pipe. + var/demand_offset = 0 + /datum/component/plumbing/Initialize(ducting_layer) if(!ismovable(parent)) return COMPONENT_INCOMPATIBLE @@ -168,9 +173,7 @@ if(tile_covered) return - //Copied from ducts handle_layer() var/offset - switch(ducting_layer) if(FIRST_DUCT_LAYER) offset = -10 @@ -183,16 +186,36 @@ 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 + if(demand_offset) + switch(parent_movable.dir) + if(NORTH) + duct_y -= demand_offset + if(SOUTH) + duct_y += demand_offset + if(EAST) + duct_x -= demand_offset + if(WEST) + duct_x += demand_offset else if(direction & initial(supply_connects)) color = supply_color + if(supply_offset) + switch(parent_movable.dir) + if(NORTH) + duct_y += supply_offset + if(SOUTH) + duct_y -= supply_offset + if(EAST) + duct_x += supply_offset + if(WEST) + duct_x -= supply_offset else continue @@ -218,6 +241,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 000000000000..56496ea803c4 --- /dev/null +++ b/code/datums/components/plumbing/boulder_reactions.dm @@ -0,0 +1,30 @@ +/** + * The boulder machines take in many types of chems, but should only ever eject "waste" chems, + */ +/datum/component/plumbing/boulder_reactions + demand_connects = NORTH + supply_connects = SOUTH + supply_offset = 4 + demand_offset = 4 + +/datum/component/plumbing/boulder_reactions/Initialize(ducting_layer) + if(!istype(parent, /obj/machinery/bouldertech/refinery)) + return COMPONENT_INCOMPATIBLE + return ..() + +/datum/component/plumbing/boulder_reactions/can_give(amount, reagent, datum/ductnet/net) + if(amount <= 0 || !reagents.total_volume || !reagent) + return FALSE + + var/obj/machinery/bouldertech/refinery/the_refinery = parent + var/list/datum/reagents/boosters = the_refinery.booster_list + + if(istype(amount, the_refinery.waste_chemical)) + return TRUE //Always allow waste chemicals to leave. + + if(!length(boosters)) + return ..() + for(var/datum/chem as anything in boosters) + if(chem.type == reagent) // Need to check strict subtype since most acids are subtypes of eachother. + return FALSE + return ..() diff --git a/code/datums/components/religious_tool.dm b/code/datums/components/religious_tool.dm index 2d51563d7b00..19cf2e079414 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 ab46ec0c3297..9abf3ed6c609 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/riding/riding_mob.dm b/code/datums/components/riding/riding_mob.dm index bc457829b7a9..b75fcac9aacc 100644 --- a/code/datums/components/riding/riding_mob.dm +++ b/code/datums/components/riding/riding_mob.dm @@ -754,3 +754,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/style/style.dm b/code/datums/components/style/style.dm index d4a107e612d0..670ef6894dc1 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 /datum/component/style/RegisterWithParent() RegisterSignal(parent, COMSIG_USER_PRE_ITEM_ATTACK, PROC_REF(hotswap)) @@ -328,6 +327,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 @@ -419,7 +422,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() @@ -447,7 +449,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) @@ -476,6 +477,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 7b399927e33e..535242b8b611 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/dash_weapon.dm b/code/datums/dash_weapon.dm index 8a02894bc1e1..c55ce0be79bf 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 55d8e28b197c..3d7fff257065 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/floor_diseases/gastritium.dm b/code/datums/diseases/floor_diseases/gastritium.dm index 228cfa7496a4..e87555111476 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 c5e0e760e944..2eba4bdb9616 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/dna/dna.dm b/code/datums/dna/dna.dm index bed1baa6f67a..7262271af1b4 100644 --- a/code/datums/dna/dna.dm +++ b/code/datums/dna/dna.dm @@ -622,7 +622,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/elements/cult_eyes.dm b/code/datums/elements/cult_eyes.dm index 68d70a470929..6e95d9b1bcab 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 b93c870f817f..7589e7194158 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 ccd2e827c50c..6ec8854d0f7d 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 ca32bde165b1..f9b790855174 100644 --- a/code/datums/elements/loomable.dm +++ b/code/datums/elements/loomable.dm @@ -101,7 +101,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/tool_blocker.dm b/code/datums/elements/tool_blocker.dm index e7fdefd6c87d..f1ce1f4fa4a2 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/keybinding/communication.dm b/code/datums/keybinding/communication.dm index bc77eee0f93e..a5aa69812433 100644 --- a/code/datums/keybinding/communication.dm +++ b/code/datums/keybinding/communication.dm @@ -11,6 +11,9 @@ . = ..() 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") return TRUE @@ -25,6 +28,9 @@ . = ..() 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") return TRUE @@ -39,6 +45,9 @@ . = ..() 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") return TRUE @@ -53,6 +62,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, "tgui_say.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/lazy_template.dm b/code/datums/lazy_template.dm index 3faefc0cc78b..9fe85cbcbcd2 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) diff --git a/code/datums/looping_sounds/machinery_sounds.dm b/code/datums/looping_sounds/machinery_sounds.dm index cd9d7fd862d1..871a5ca7bf90 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/biomes/_biome.dm b/code/datums/mapgen/biomes/_biome.dm index bb0398259de6..d671f50e1f8e 100644 --- a/code/datums/mapgen/biomes/_biome.dm +++ b/code/datums/mapgen/biomes/_biome.dm @@ -91,49 +91,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. @@ -143,7 +100,11 @@ * 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) @@ -151,17 +112,21 @@ // in this. CHECK_TICK - if(flora_allowed && length(flora_types) && prob(flora_density)) + if(istype(target_turf, closed_turf_type)) + continue + + if(has_flora && prob(flora_density)) var/obj/structure/flora = pick(flora_types) new flora(target_turf) continue - if(features_allowed && prob(feature_density)) + if(has_features && 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)) + var/list/features_in_range = range(7, target_turf) + for(var/obj/structure/existing_feature in features_in_range) if(istype(existing_feature, picked_feature)) can_spawn = FALSE break @@ -170,19 +135,29 @@ new picked_feature(target_turf) continue - if(fauna_allowed && length(fauna_types) && prob(fauna_density)) + if(has_fauna && 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)) + var/blocked = FALSE for(var/obj/structure/spawner/lavaland/spawn_blocker in range(2, target_turf)) + blocked = TRUE + break + + if(blocked) continue // 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) + var/blocked = FALSE for(var/mob/living/mob_blocker in things_in_range) if(ismining(mob_blocker)) - continue + blocked = TRUE + break + + if(blocked) + continue new picked_mob(target_turf) diff --git a/code/datums/materials/_material.dm b/code/datums/materials/_material.dm index 5d34b97c75d8..2c7f8093c74c 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. diff --git a/code/datums/materials/basemats.dm b/code/datums/materials/basemats.dm index 4284503cede4..56c8a4807ba9 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/quirks/positive_quirks/spacer.dm b/code/datums/quirks/positive_quirks/spacer.dm index a1c7f83ab421..24d392985de6 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" @@ -26,7 +27,7 @@ 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 /datum/quirk/spacer_born/add(client/client_source) @@ -38,9 +39,10 @@ // 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 @@ -69,6 +71,7 @@ /datum/quirk/spacer_born/remove() UnregisterSignal(quirk_holder, COMSIG_MOVABLE_Z_CHANGED) + UnregisterSignal(quirk_holder, COMSIG_LIVING_GRAVITY_CHANGED) if(QDELING(quirk_holder)) return @@ -87,7 +90,13 @@ /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. @@ -95,9 +104,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) @@ -168,9 +180,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 @@ -181,7 +194,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) @@ -197,5 +210,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 729b85c56b8e..a403923ab80d 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 16ea2fd2324c..0bf5985a4a84 100644 --- a/code/datums/records/manifest.dm +++ b/code/datums/records/manifest.dm @@ -136,7 +136,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, // DARKPACK EDIT - ALTERNATIVE_JOB_TITLES - ORIGINAL: rank = assignment, diff --git a/code/datums/records/record.dm b/code/datums/records/record.dm index fd2f02ec1aed..3874e483bdc4 100644 --- a/code/datums/records/record.dm +++ b/code/datums/records/record.dm @@ -157,7 +157,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 18feada06cb9..c88433e5ca91 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 dffe313c1200..5e293a70747a 100644 --- a/code/datums/ruins/icemoon.dm +++ b/code/datums/ruins/icemoon.dm @@ -85,6 +85,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/mining_site diff --git a/code/datums/ruins/lavaland.dm b/code/datums/ruins/lavaland.dm index fb2d1d44c0c0..cd3c1065ec4d 100644 --- a/code/datums/ruins/lavaland.dm +++ b/code/datums/ruins/lavaland.dm @@ -330,3 +330,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 fe7cfaeb8c8e..b89da65d5ebf 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. @@ -1288,7 +1289,7 @@ GLOBAL_LIST_EMPTY(blended_hair_icons_cache) 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_to_use, icon, female_sprite_flags_to_use) if(use_digi) @@ -1315,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 @@ -1509,6 +1511,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" @@ -1797,6 +1800,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/debuffs/debuffs.dm b/code/datums/status_effects/debuffs/debuffs.dm index b55a385e2378..08f36ff70363 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/spacer.dm b/code/datums/status_effects/debuffs/spacer.dm index 6f970eafac95..99b724b1d356 100644 --- a/code/datums/status_effects/debuffs/spacer.dm +++ b/code/datums/status_effects/debuffs/spacer.dm @@ -105,6 +105,20 @@ 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" diff --git a/code/datums/status_effects/neutral.dm b/code/datums/status_effects/neutral.dm index d5989f91a7e4..9ccc6e3d3335 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/storage/storage.dm b/code/datums/storage/storage.dm index 7779f559e90b..20cfc49b737f 100644 --- a/code/datums/storage/storage.dm +++ b/code/datums/storage/storage.dm @@ -1068,10 +1068,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/wounds/pierce.dm b/code/datums/wounds/pierce.dm index 2ccf49d293f9..28a9286a7752 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) @@ -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/game/atom/atom_vv.dm b/code/game/atom/atom_vv.dm index 85d7ed011c7d..d5a4b5ccd9dc 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/machinery/computer/accounting.dm b/code/game/machinery/computer/accounting.dm index 05a1d12ed40c..6ccc1d2c7b31 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 6c56f6e2aa60..a7add4639c3e 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/orders/order_items/mining/order_mining.dm b/code/game/machinery/computer/orders/order_items/mining/order_mining.dm index cf33d3bd8e5a..d628e3fc3292 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/records/medical.dm b/code/game/machinery/computer/records/medical.dm index 15cdc19f8979..3511a75f706b 100644 --- a/code/game/machinery/computer/records/medical.dm +++ b/code/game/machinery/computer/records/medical.dm @@ -101,7 +101,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 57c58083aae7..e43ed60c32fb 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 e69a78f132df..83ed8b3a02e8 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 e4d93a587f8f..a00e561d5899 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 83e67734f258..c92f46b37ada 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 8939fb64e0fd..3a9a893d54db 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/rat_organs.dm b/code/game/machinery/dna_infuser/organ_sets/rat_organs.dm index 3b1e1b9f3bb9..d9a0abbe76a5 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 000000000000..623f8607e9a0 --- /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_TALLER, 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 883084e6c9a8..3ff1662d99bb 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1575,7 +1575,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() @@ -1599,7 +1599,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 @@ -1616,7 +1616,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) @@ -2400,6 +2400,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/shutters.dm b/code/game/machinery/doors/shutters.dm index c09dae310ceb..8757837cb14a 100644 --- a/code/game/machinery/doors/shutters.dm +++ b/code/game/machinery/doors/shutters.dm @@ -107,3 +107,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/fat_sucker.dm b/code/game/machinery/fat_sucker.dm index d9806ba6f2bb..a0756ca11db3 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/medipen_refiller.dm b/code/game/machinery/medipen_refiller.dm index bdeb8227cac2..8192cf3c93c7 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 b10f0fd74f64..06d0d0707c0c 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/slotmachine.dm b/code/game/machinery/slotmachine.dm index 8903bacc8f03..5fcb061e0653 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 539d3cc0e8d3..89f8c527e188 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 5b78deb2bc00..838e902f0bc4 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/telecomms/machines/message_server.dm b/code/game/machinery/telecomms/machines/message_server.dm index f9fb183e53ee..eaa27f20794d 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)].") // DARKPACK EDIT CHANGE - CITY_TIME else pda_msgs += new /datum/data_tablet_msg("System Administrator", "system", MESSAGE_SERVER_FUNCTIONING_MESSAGE) diff --git a/code/game/objects/effects/decals/cleanable/mess.dm b/code/game/objects/effects/decals/cleanable/mess.dm index be640e2b5b5b..7667513f00ba 100644 --- a/code/game/objects/effects/decals/cleanable/mess.dm +++ b/code/game/objects/effects/decals/cleanable/mess.dm @@ -22,8 +22,10 @@ pixel_x = base_pixel_x + rand(-5, 5) pixel_y = base_pixel_y + rand(-5, 5) +// DARKPACK EDIT CHANGE START /obj/effect/decal/cleanable/ash/NeverShouldHaveComeHere(turf/here_turf) - return !istype(here_turf, /obj/structure/bodycontainer/crematorium) && ..() + return isclosedturf(here_turf) +// DARKPACK EDIT CHANGE END /obj/effect/decal/cleanable/ash/large name = "large pile of ashes" 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 000000000000..13a3fe57a0f7 --- /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 736be058ee4b..468654f4d5a0 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 @@ -291,10 +291,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 b6d3d892896b..cca69643fb36 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/particles/acid.dm b/code/game/objects/effects/particles/acid.dm index 5ce0984991d8..19683b6ad788 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 9d1da48cd290..c5c82b485e0e 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.assert_gas(/datum/gas/nitrogen) - second_gasmix.assert_gas(/datum/gas/tritium) + first_gasmix.set_temperature(2.7) + second_gasmix.set_temperature(2.7) - 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.assert_gas(/datum/gas/hypernoblium) - second_gasmix.assert_gas(/datum/gas/tritium) + first_gasmix.set_temperature(20000) + second_gasmix.set_temperature(2.7) - 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 901bb06cee78..500d0832e4c1 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/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/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/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/effect/spawner/random/exotic/antag_gear + name = "antag gear" + icon_state = "esword" + loot = list( + /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/items/AI_modules/_AI_modules.dm b/code/game/objects/items/AI_modules/_AI_modules.dm index 3422f57ac3be..69c809c903ee 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/circuitboards/machines/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm index 9fb7633daf4a..1a8695c75d3d 100644 --- a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm @@ -1703,6 +1703,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 @@ -1713,6 +1714,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/devices/scanners/autopsy_scanner.dm b/code/game/objects/items/devices/scanners/autopsy_scanner.dm index c541e513a0d8..5e0376879e77 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 a36848069670..c3ae145b51e7 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 @@ -474,11 +474,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 3184ed43857f..039f6225b21a 100644 --- a/code/game/objects/items/devices/table_clock.dm +++ b/code/game/objects/items/devices/table_clock.dm @@ -31,8 +31,11 @@ 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)].") DARKPACK EDIT REMOVAL + . += span_info("The current CST (local) time is: [server_timestamp(ic_time = TRUE, twelve_hour_clock = user.client?.prefs.read_preference(/datum/preference/toggle/twelve_hour))].") // DARKPACK EDIT CHANGE + /* // DARKPACK EDIT REMOVAL + 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/emags.dm b/code/game/objects/items/emags.dm index 9bce1d09fdd0..96e5ca19d2f7 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/food/packaged.dm b/code/game/objects/items/food/packaged.dm index 95054ec4a1a4..597ec3ce60d4 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/grenades/ghettobomb.dm b/code/game/objects/items/grenades/ghettobomb.dm index 9afe5cd4aa68..5dbf50521688 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/storage/boxes/cargo_boxes.dm b/code/game/objects/items/storage/boxes/cargo_boxes.dm index 749873b50a06..a299ab085090 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/tanks/jetpack.dm b/code/game/objects/items/tanks/jetpack.dm index 3a665d903a66..74557295dac4 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 0d8734a799b5..11ce2b694799 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() @@ -246,21 +238,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/tools/medical/defib.dm b/code/game/objects/items/tools/medical/defib.dm index 73786ed7b858..b257790daa4f 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 27b629f7e356..1a67911a03a1 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/ranged/flamethrower.dm b/code/game/objects/items/weaponry/ranged/flamethrower.dm index 04cf93803c52..3a8a302d858e 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/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm index 3f8387469c60..9c667f89a0ac 100644 --- a/code/game/objects/structures/beds_chairs/chair.dm +++ b/code/game/objects/structures/beds_chairs/chair.dm @@ -623,8 +623,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 28c2b6030b3c..b911705b0102 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/crates/abandoned_crates/abandoned_crates.dm b/code/game/objects/structures/crates_lockers/crates/abandoned_crates/abandoned_crates.dm index 3a17fdc4b8b3..6ab6b9ce437a 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, diff --git a/code/game/objects/structures/guillotine.dm b/code/game/objects/structures/guillotine.dm index 50a9473e19fe..0615ea579da9 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 bbbc8da76e49..5c790457e440 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/ore_vent.dm b/code/game/objects/structures/lavaland/ore_vent.dm index 8a20893d32ba..38e5ac835371 100644 --- a/code/game/objects/structures/lavaland/ore_vent.dm +++ b/code/game/objects/structures/lavaland/ore_vent.dm @@ -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) . = ..() @@ -357,7 +358,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.") @@ -758,6 +759,40 @@ /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") + +/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" diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index dff81692a5f7..718a527a85cf 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -262,7 +262,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) diff --git a/code/game/objects/structures/petrified_statue.dm b/code/game/objects/structures/petrified_statue.dm index e6327a1a8111..1f4f76c67687 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 000000000000..307993a52d85 --- /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 000000000000..2c5c074d1274 --- /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 e8b98ac3473b..2a6cad61fb70 100644 --- a/code/game/objects/structures/signs/signs_interactive.dm +++ b/code/game/objects/structures/signs/signs_interactive.dm @@ -1,14 +1,17 @@ /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)].") DARKPACK EDIT REMOVAL + . += span_info("The current CST (local) time is: [server_timestamp(ic_time = TRUE, twelve_hour_clock = user.client?.prefs.read_preference(/datum/preference/toggle/twelve_hour))].") // DAKRPACK EDIT CHANGE - CITY_TIME + /* //DARKPACK EDIT REMOVAL + 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 72549bdbcc7f..93e54886e6ef 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 fe806662dac4..30ea69ff0d40 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 a6bc8377d39b..3975030ac06f 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 49ebdb577a92..33afb7c7b291 100644 --- a/code/game/turfs/change_turf.dm +++ b/code/game/turfs/change_turf.dm @@ -158,8 +158,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) @@ -281,7 +285,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/open/floor/plating.dm b/code/game/turfs/open/floor/plating.dm index 2a440db7c742..7718f4b143ef 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/turf.dm b/code/game/turfs/turf.dm index c6debdb5ce99..b6a0b8c38678 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 a243dd09e383..6d6ac4cc60f3 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -126,12 +126,14 @@ GLOBAL_VAR(restart_counter) * All atoms in both compiled and uncompiled maps are initialized() */ /world/New() - log_world("World loaded at [time_stamp()]!") + log_world("World loaded at [server_timestamp()]!") + // DARKPACK EDIT ADD START - CITY_TIME // 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 + // DARKPACK EDIT ADD END // First possible sleep() InitTgs() @@ -244,7 +246,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.picture_log_directory += "[timestamp]" GLOB.picture_logging_prefix += "T_[timestamp]_" @@ -373,14 +375,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) @@ -436,7 +438,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 e38401986654..642675dfc372 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 feb595306ab0..161b39ca10d3 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,7 +30,7 @@ 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 @@ -39,24 +42,86 @@ ADMIN_VERB(admin_ghost, R_ADMIN, "AGhost", "Become a ghost without DNR.", ADMIN_ ghost.exit_avatar(force = TRUE) // DARKPACK EDIT END 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 + + // 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_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 - ADD_TRAIT(user.mob, TRAIT_INVISIMIN, 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) + // 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() @@ -146,8 +211,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) @@ -170,7 +233,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 @@ -185,8 +249,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) @@ -809,10 +871,14 @@ ADMIN_VERB(give_ai_speech, R_FUN, "Give Random AI Speech", ADMIN_VERB_NO_DESCRIP our_controller.planning_subtrees = list(GLOB.ai_subtrees[/datum/ai_planning_subtree/random_speech/blackboard]) + our_controller.planning_subtrees 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 @@ -847,5 +913,8 @@ 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/holder2.dm b/code/modules/admin/holder2.dm index 18b96318f067..9db5efee0dbd 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 diff --git a/code/modules/admin/verbs/admin_newscaster.dm b/code/modules/admin/verbs/admin_newscaster.dm index e300150659b1..ec96d8babce8 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 98987899a27d..2052eeeb92bd 100644 --- a/code/modules/admin/verbs/admingame.dm +++ b/code/modules/admin/verbs/admingame.dm @@ -289,7 +289,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) @@ -488,6 +488,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 622194bc759f..1e3711bc8495 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -278,7 +278,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, ) @@ -356,9 +356,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() @@ -566,9 +566,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)]
" @@ -666,9 +666,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 000000000000..32c29a9e5407 --- /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/pray.dm b/code/modules/admin/verbs/pray.dm index 4277cae7d81f..aefd988aa74d 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 c2a3f1f864dc..84ccaf2935ba 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 64022618c286..e1ffc660706c 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 d92efcb7b2a9..9f8010669989 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/reference_tracking.dm b/code/modules/admin/view_variables/reference_tracking.dm index 5f3afd380f73..cccb97f6c9bb 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/blob/overmind.dm b/code/modules/antagonists/blob/overmind.dm index e6f8ad51e22f..dcfc2a184f43 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) - - // Set status displays to biohazard alert - critical level - send_status_display_biohazard_alert() + begin_victory() - 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)) + 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 +183,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/cult/cult_other.dm b/code/modules/antagonists/cult/cult_other.dm index 0e286d75e811..4f4ddd7aee06 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/heretic/heretic_antag.dm b/code/modules/antagonists/heretic/heretic_antag.dm index bd476de6587c..efddddaa4adb 100644 --- a/code/modules/antagonists/heretic/heretic_antag.dm +++ b/code/modules/antagonists/heretic/heretic_antag.dm @@ -378,6 +378,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) @@ -401,6 +402,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) diff --git a/code/modules/antagonists/heretic/heretic_knowledge.dm b/code/modules/antagonists/heretic/heretic_knowledge.dm index 48aeb721c1aa..0c5efc1a9595 100644 --- a/code/modules/antagonists/heretic/heretic_knowledge.dm +++ b/code/modules/antagonists/heretic/heretic_knowledge.dm @@ -555,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 @@ -586,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)") @@ -636,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/items/corrupted_organs.dm b/code/modules/antagonists/heretic/items/corrupted_organs.dm index a6494591910e..0c96652436c2 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 a5b63179a963..1529284652b5 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 3a5e0e2a1293..4cae667299da 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 61dbef21dc19..21bd99846e5d 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/side_knowledge/tier_one.dm b/code/modules/antagonists/heretic/knowledge/side_knowledge/tier_one.dm index e8a3f9b4d674..3706408b464e 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 6647ee086bcf..4105a4d08c98 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 514236771e24..af2fd7e0ef1a 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/status_effects/dreams.dm b/code/modules/antagonists/heretic/status_effects/dreams.dm new file mode 100644 index 000000000000..1b1db45f7028 --- /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 d88a4d039174..0fdb4251f5f4 100644 --- a/code/modules/antagonists/malf_ai/malf_ai_modules.dm +++ b/code/modules/antagonists/malf_ai/malf_ai_modules.dm @@ -753,7 +753,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/equipment/nuclear_bomb/beer_nuke.dm b/code/modules/antagonists/nukeop/equipment/nuclear_bomb/beer_nuke.dm index 66798ae798c6..73915938adac 100644 --- a/code/modules/antagonists/nukeop/equipment/nuclear_bomb/beer_nuke.dm +++ b/code/modules/antagonists/nukeop/equipment/nuclear_bomb/beer_nuke.dm @@ -17,7 +17,10 @@ overflow_control = locate(/datum/round_event_control/scrubber_overflow/every_vent) in SSevents.control /obj/machinery/nuclearbomb/beer/Destroy() - UnregisterSignal(overflow_control, COMSIG_CREATED_ROUND_EVENT) + // DARKPACK EDIT CHANGE - this was causing runtimes as overflow_control is null if the associated event is not in SSevents + if(!isnull(overflow_control)) + UnregisterSignal(overflow_control, COMSIG_CREATED_ROUND_EVENT) + // DARKPACK EDIT CHANGE END . = ..() /obj/machinery/nuclearbomb/beer/examine(mob/user) diff --git a/code/modules/antagonists/nukeop/outfits.dm b/code/modules/antagonists/nukeop/outfits.dm index ec2b63e7413e..74402a2cd066 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/space_ninja/equipment/ninja_explosive.dm b/code/modules/antagonists/space_ninja/equipment/ninja_explosive.dm index 6e61ad687614..25317f623b72 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 3685800dcf11..224f083029ce 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 a1020c3c93ee..5344f86be2ea 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 447389876ea2..2cd3ff136bbc 100644 --- a/code/modules/antagonists/voidwalker/voidwalker_mob.dm +++ b/code/modules/antagonists/voidwalker/voidwalker_mob.dm @@ -139,7 +139,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 +151,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 +167,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/spellbook_entries/defensive.dm b/code/modules/antagonists/wizard/equipment/spellbook_entries/defensive.dm index 609f626bb05e..382e8963febb 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" diff --git a/code/modules/antagonists/wizard/equipment/spellbook_entries/mobility.dm b/code/modules/antagonists/wizard/equipment/spellbook_entries/mobility.dm index bc09b092f6cd..eb0c841c1054 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 48653ea7cedf..8cd1c5074e73 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/wizard_hammer.dm b/code/modules/antagonists/wizard/equipment/wizard_hammer.dm index 110fcfd214fe..c5877735f314 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/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index b9f59c3208df..2324824426a4 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 d215c1c68030..4f5c643d05c1 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 496a992e50b2..60e355110b79 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 23babb68c963..71eb4e1fb8dc 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 21fd7eb018aa..6ff941771907 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 06fcda77b444..0dbf0cfaa540 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/tank.dm b/code/modules/atmospherics/machinery/components/tank.dm index 1bfb9c1d5b23..8d9381df2732 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/thermomachine.dm b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm index 7fb5364170b6..87d25f25a321 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 0ca5fbff785d..3a76be7b1844 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 60f3ac82bb8f..6ab73e5b2e1d 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 b1b094c9db01..4fd3392c32b5 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/awaymissions/mission_code/murderdome.dm b/code/modules/awaymissions/mission_code/murderdome.dm index 0253ad69f939..87bb666fedb9 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/capture_the_flag/ctf_game.dm b/code/modules/capture_the_flag/ctf_game.dm index b10513eca275..2b164277abaa 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/exports/manifest.dm b/code/modules/cargo/exports/manifest.dm index 861dae87027f..897654d5ccf0 100644 --- a/code/modules/cargo/exports/manifest.dm +++ b/code/modules/cargo/exports/manifest.dm @@ -1,47 +1,49 @@ -#define MAX_MANIFEST_PENALTY CARGO_CRATE_VALUE * 2.5 - -// Approved manifest. -// +80 credits flat. +#define MANIFEST_HANDLING_RATE 0.12 +#define MANIFEST_CORRECT_RATE MANIFEST_HANDLING_RATE * 2 +#define MANIFEST_ERRONEOUS_RATE MANIFEST_HANDLING_RATE * 4 +#define MAX_HANDLING_CHARGE CARGO_CRATE_VALUE * 0.6 +#define MAX_CORRECT_CHARGE MAX_HANDLING_CHARGE * 2 +#define MAX_ERRONEOUS_CHARGE MAX_HANDLING_CHARGE * 4 + +// Approved manifest. 12% handling payment, up to a maximum of the max handling charge /datum/export/manifest_correct - cost = CARGO_CRATE_VALUE * 0.4 k_elasticity = 0 unit_name = "approved manifest" export_types = list(/obj/item/paper/fluff/jobs/cargo/manifest) scannable = FALSE -/datum/export/manifest_correct/applies_to(obj/O) +/datum/export/manifest_correct/applies_to(obj/exported_item) if(!..()) return FALSE - var/obj/item/paper/fluff/jobs/cargo/manifest/M = O - if(M.is_approved() && !M.errors) + var/obj/item/paper/fluff/jobs/cargo/manifest/export_manifest = exported_item + if(export_manifest.is_approved() && !export_manifest.errors) return TRUE return FALSE -// Correctly denied manifest. -// Refunds package cost minus the value of the crate. +/datum/export/manifest_correct/get_base_cost(obj/item/paper/fluff/jobs/cargo/manifest/exported_item) + return min(exported_item.order_cost * MANIFEST_HANDLING_RATE, MAX_HANDLING_CHARGE) + +// Correctly denied manifest. Refunds package cost plus double handling payment, up to a maximum of 2x max handling charge /datum/export/manifest_error_denied - cost = -CARGO_CRATE_VALUE k_elasticity = 0 unit_name = "correctly denied manifest" export_types = list(/obj/item/paper/fluff/jobs/cargo/manifest) scannable = FALSE -/datum/export/manifest_error_denied/applies_to(obj/O) +/datum/export/manifest_error_denied/applies_to(obj/exported_item) if(!..()) return FALSE - var/obj/item/paper/fluff/jobs/cargo/manifest/M = O - if(M.is_denied() && M.errors) + var/obj/item/paper/fluff/jobs/cargo/manifest/export_manifest = exported_item + if(export_manifest.is_denied() && export_manifest.errors) return TRUE return FALSE -/datum/export/manifest_error_denied/get_base_cost(obj/item/paper/fluff/jobs/cargo/manifest/M) - return ..() + M.order_cost +/datum/export/manifest_error_denied/get_base_cost(obj/item/paper/fluff/jobs/cargo/manifest/exported_item) + return exported_item.order_cost + min(exported_item.order_cost * MANIFEST_CORRECT_RATE, MAX_CORRECT_CHARGE) - -// Erroneously approved manifest. -// Subtracts half the package cost. (max -500 credits) +// Erroneously approved manifest. Penalty charged quadruple handling payment, up to a maximum of 4x max handling charge /datum/export/manifest_error unit_name = "erroneously approved manifest" k_elasticity = 0 @@ -49,21 +51,19 @@ allow_negative_cost = TRUE scannable = FALSE -/datum/export/manifest_error/applies_to(obj/O) +/datum/export/manifest_error/applies_to(obj/exported_item) if(!..()) return FALSE - var/obj/item/paper/fluff/jobs/cargo/manifest/M = O - if(M.is_approved() && M.errors) + var/obj/item/paper/fluff/jobs/cargo/manifest/export_manifest = exported_item + if(export_manifest.is_approved() && export_manifest.errors) return TRUE return FALSE -/datum/export/manifest_error/get_base_cost(obj/item/paper/fluff/jobs/cargo/manifest/M) - return -min(M.order_cost * 0.5, MAX_MANIFEST_PENALTY) - +/datum/export/manifest_error/get_base_cost(obj/item/paper/fluff/jobs/cargo/manifest/exported_item) + return -min(exported_item.order_cost * MANIFEST_ERRONEOUS_RATE, MAX_ERRONEOUS_CHARGE) -// Erroneously denied manifest. -// Subtracts half the package cost. (max -500 credits) +// Erroneously denied manifest. Penalty charged quadruple handling payment, up to a maximum of 4x max handling charge /datum/export/manifest_correct_denied k_elasticity = 0 unit_name = "erroneously denied manifest" @@ -71,16 +71,21 @@ allow_negative_cost = TRUE scannable = FALSE -/datum/export/manifest_correct_denied/applies_to(obj/O) +/datum/export/manifest_correct_denied/applies_to(obj/exported_item) if(!..()) return FALSE - var/obj/item/paper/fluff/jobs/cargo/manifest/M = O - if(M.is_denied() && !M.errors) + var/obj/item/paper/fluff/jobs/cargo/manifest/export_manifest = exported_item + if(export_manifest.is_denied() && !export_manifest.errors) return TRUE return FALSE -/datum/export/manifest_correct_denied/get_base_cost(obj/item/paper/fluff/jobs/cargo/manifest/M) - return -min(M.order_cost * 0.5, MAX_MANIFEST_PENALTY) +/datum/export/manifest_correct_denied/get_base_cost(obj/item/paper/fluff/jobs/cargo/manifest/exported_item) + return -min(exported_item.order_cost * MANIFEST_ERRONEOUS_RATE, MAX_ERRONEOUS_CHARGE) -#undef MAX_MANIFEST_PENALTY +#undef MANIFEST_HANDLING_RATE +#undef MANIFEST_CORRECT_RATE +#undef MANIFEST_ERRONEOUS_RATE +#undef MAX_HANDLING_CHARGE +#undef MAX_CORRECT_CHARGE +#undef MAX_ERRONEOUS_CHARGE diff --git a/code/modules/cargo/expressconsole.dm b/code/modules/cargo/expressconsole.dm index c649cda9d562..ec4d782d7421 100644 --- a/code/modules/cargo/expressconsole.dm +++ b/code/modules/cargo/expressconsole.dm @@ -1,6 +1,22 @@ #define EXPRESS_EMAG_DISCOUNT 0.72 #define BEACON_PRINT_COOLDOWN 10 SECONDS +// DARKPACK EDIT ADD START +GLOBAL_LIST_EMPTY(cargo_landing_spots) +/obj/effect/abstract/cargo_landing_spot + icon = 'icons/effects/landmarks_static.dmi' + icon_state = "x2" + invisibility = INVISIBILITY_ABSTRACT + +/obj/effect/abstract/cargo_landing_spot/Initialize(mapload) + . = ..() + GLOB.cargo_landing_spots += src + +/obj/effect/abstract/cargo_landing_spot/Destroy(force) + . = ..() + GLOB.cargo_landing_spots -= src +// DARKPACK EDIT ADD END + /obj/machinery/computer/cargo/express name = "express supply console" desc = "This console allows the user to purchase a package \ @@ -14,7 +30,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 +46,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() @@ -118,23 +128,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() @@ -151,7 +146,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 @@ -162,10 +156,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() @@ -242,14 +232,23 @@ var/list/prefered_turfs = list() // DARKPACK EDIT ADD if (!istype(beacon) || !using_beacon || (obj_flags & EMAGGED)) empty_turfs = list() - for(var/turf/open/open_turf in landingzone.get_turfs_from_all_zlevels()) // DARKPACK EDIT CHANGE - (removes floor so it can include DIRT) + // DARKPACK EDIT ADD START + for(var/obj/effect/abstract/cargo_landing_spot/spot in GLOB.cargo_landing_spots) + var/turf/open/open_turf = get_turf(spot) + if(!astype(open_turf)) + stack_trace("[spot] is not in an open turf. Turf is [open_turf]") if(!open_turf.is_blocked_turf()) - empty_turfs += open_turf - // DARKPACK EDIT ADD START - var/obj/effect/decal/pallet/cool_spot = locate() in open_turf - if(cool_spot) - prefered_turfs += open_turf - // DARKPACK EDIT ADD END + empty_turfs |= open_turf + // DARKPACK EDIT ADD END + // DARKPACK EDIT CHANGE START + if(!length(empty_turfs)) // We ran out of hand-mapped markers, resort to pallets and the ground, but we cannot ensure super sane spawns + for(var/turf/open/open_turf in landingzone.get_turfs_from_all_zlevels()) + if(!open_turf.is_blocked_turf()) + empty_turfs |= open_turf + var/obj/effect/decal/pallet/cool_spot = locate() in open_turf + if(cool_spot) + prefered_turfs += open_turf + // DARKPACK EDIT CHANGE END if (!length(empty_turfs)) return diff --git a/code/modules/cargo/markets/market_items/clothing.dm b/code/modules/cargo/markets/market_items/clothing.dm index bfa34867068b..52b6a18cdc45 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/materials_market.dm b/code/modules/cargo/materials_market.dm index 390ac1d0ee94..207a47ae0c65 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 c6a8166ef69c..0f62be3dbab3 100644 --- a/code/modules/cargo/order.dm +++ b/code/modules/cargo/order.dm @@ -109,7 +109,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]
    " @@ -118,7 +118,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 @@ -221,6 +221,11 @@ /datum/supply_order/disposable/materials/get_final_cost() return (..() + CARGO_CRATE_VALUE) +/// Custom material order to append cargo crate value to the final manifest cost +/datum/supply_order/disposable/materials/generateManifest(obj/container, owner, packname, cost) + cost += CARGO_CRATE_VALUE + return ..() + #undef MANIFEST_ERROR_CHANCE #undef MANIFEST_ERROR_NAME #undef MANIFEST_ERROR_CONTENTS diff --git a/code/modules/cargo/orderconsole.dm b/code/modules/cargo/orderconsole.dm index 8d9671b5eaa6..00db99653a17 100644 --- a/code/modules/cargo/orderconsole.dm +++ b/code/modules/cargo/orderconsole.dm @@ -177,9 +177,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] @@ -189,16 +188,17 @@ 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 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, @@ -406,10 +406,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)]" // DARKPACK EDIT CHANGE - CITY_TIME 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]
    " @@ -424,7 +424,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/_packs.dm b/code/modules/cargo/packs/_packs.dm index dc63b5f43e67..859cb7a99f0b 100644 --- a/code/modules/cargo/packs/_packs.dm +++ b/code/modules/cargo/packs/_packs.dm @@ -139,7 +139,7 @@ name = "materials order" crate_name = "galactic materials market delivery crate" access = FALSE - crate_type = /obj/structure/closet/crate/cardboard + crate_type = /obj/structure/closet/crate/cargo/mining /datum/supply_pack/custom/minerals/New(purchaser, cost, list/contains) . = ..() diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 3096a2dfee31..1a65a4e500a5 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -459,7 +459,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) @@ -490,7 +490,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(LAZYLEN(quirks_removed)) LAZYADD(feedback, "The following quirks are incompatible with your species or splat:") // DARKPACK EDIT CHANGE - SPLATS 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/middleware/quirks.dm b/code/modules/client/preferences/middleware/quirks.dm index 9a2e1f866952..9da41cf22a53 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?" @@ -59,7 +59,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() data["splat_disallowed_quirks"] = get_splat_compatibility() // DARKPACK EDIT ADD - SPLATS data["quirk_balance"] = get_quirk_balance() // DARKPACK EDIT ADD - MERITS_FLAWS @@ -86,7 +86,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] @@ -109,7 +109,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/time.dm b/code/modules/client/preferences/time.dm new file mode 100644 index 000000000000..698618571ec1 --- /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/verbs/ooc.dm b/code/modules/client/verbs/ooc.dm index b1a95e81c2b1..ce33331c6e4d 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.")) @@ -134,7 +133,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" diff --git a/code/modules/client/verbs/typing.dm b/code/modules/client/verbs/typing.dm index b7a736226148..bef6d85a0482 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 91df732e454c..fe5c87fe8987 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/head/hat.dm b/code/modules/clothing/head/hat.dm index 7a307d37b540..5449496e467e 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/masks/gas_filter.dm b/code/modules/clothing/masks/gas_filter.dm index 1399a1a07d45..98abaf220dd2 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 ef976a67c584..36e6a6115cf7 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 7d6df307725e..ab2bb53516c6 100644 --- a/code/modules/clothing/neck/_neck.dm +++ b/code/modules/clothing/neck/_neck.dm @@ -518,6 +518,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 f4535059a050..fa3a77f4365e 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 1a0dcca025db..de7b36804033 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 97eb723c77e9..44324bae47aa 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 72841de62df0..d6cb7bf0c898 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 dc55e3ec0d50..b6627145b8c3 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" @@ -10,7 +10,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 @@ -31,7 +32,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 fb5bc428a5c8..e145e7f3d793 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/under/syndicate.dm b/code/modules/clothing/under/syndicate.dm index 5d2f301484a5..c195718dc3ab 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/detectivework/scanner.dm b/code/modules/detectivework/scanner.dm index a7cebef7bf25..bb1285c11a54 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/error_handler/error_handler.dm b/code/modules/error_handler/error_handler.dm index f8355f530643..57eab84a1f96 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 fa0d1dcc9815..7ffba15b40f5 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 000000000000..3eeacf70e935 --- /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 00267ecba5da..9a507d6dbd80 100644 --- a/code/modules/escape_menu/details.dm +++ b/code/modules/escape_menu/details.dm @@ -1,43 +1,17 @@ -// 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: [server_timestamp(format = "hh:mm:ss", twelve_hour_clock = client_owner.prefs.read_preference(/datum/preference/toggle/twelve_hour))]
    + Round Time: [(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)]%
    - "} + "} // DARKPACK EDIT CHANGE - CITY_TIME maptext = MAPTEXT(new_maptext) diff --git a/code/modules/escape_menu/escape_menu.dm b/code/modules/escape_menu/escape_menu.dm index b1f06df43ba9..55f22fe46901 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 641be0d3a347..aead9cc8d513 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 2a7260785b32..abedf2cba3f6 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 fe08bd021dc6..529bd034c861 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/_event.dm b/code/modules/events/_event.dm index 76fe9d365490..98b7e92c5180 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -38,6 +38,8 @@ /// Flags dictating whether this event should be run on certain kinds of map var/map_flags = NONE + var/darkpack_allowed = FALSE // DARKPACK EDIT ADD - EVENTS + /datum/round_event_control/New() if(!length(admin_setup)) return diff --git a/code/modules/events/ghost_role/sentience.dm b/code/modules/events/ghost_role/sentience.dm index 4fc837169d2b..5d4668f640c9 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/nightshift.dm b/code/modules/events/nightshift.dm new file mode 100644 index 000000000000..785ad8e04ac2 --- /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 5b2b6b71ea1d..fdc37f29715d 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 ab6a3a2d394b..a0308fb317da 100644 --- a/code/modules/events/space_vines/vine_mutations.dm +++ b/code/modules/events/space_vines/vine_mutations.dm @@ -287,7 +287,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/fishing/fish/fish_traits.dm b/code/modules/fishing/fish/fish_traits.dm index 342bfc981fd4..ae97235cfe56 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/flufftext/dreaming.dm b/code/modules/flufftext/dreaming.dm index 9ebb8cd41ade..73520a1625c2 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 3d9578218747..31a6e85075d1 100644 --- a/code/modules/food_and_drinks/machinery/smartfridge.dm +++ b/code/modules/food_and_drinks/machinery/smartfridge.dm @@ -537,6 +537,7 @@ desc = "A wooden contraption, used to dry plant products, food and hide." icon_state = "drying-rack" base_icon_state = "drying-rack" + icon = 'modular_darkpack/master_files/icons/obj/machines/smartfridge.dmi' // DARKPACK EDIT ADD resistance_flags = FLAMMABLE visible_contents = FALSE base_build_path = /obj/machinery/smartfridge/drying/rack @@ -586,7 +587,18 @@ if(drying) . += "[base_icon_state]-drying" if(contents.len) - . += "[base_icon_state]-filled" + // DARKPACK EDIT CHANGE START + var/still_drying = FALSE + for(var/obj/item/item_iterator in src) + if(!accept_check(item_iterator)) + continue + still_drying = TRUE + break + if(still_drying) + . += "[base_icon_state]-filled" + else + . += "[base_icon_state]-filled-dried" + // DARKPACK EDIT CHANGE END // ---------------------------- // Bar drink smartfridge diff --git a/code/modules/food_and_drinks/recipes/food_mixtures.dm b/code/modules/food_and_drinks/recipes/food_mixtures.dm index 15368d2c5431..78dbdb351b0c 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(city_time(), 3 HOURS + 45 MINUTES, 4 HOURS + 15 MINUTES)) // DARKPACK EDIT CHANGE - CITY_TIME return var/lastkey = holder.my_atom?.fingerprintslast if(!lastkey) diff --git a/code/modules/forensics/_forensics.dm b/code/modules/forensics/_forensics.dm index e03790e27b06..af37a9b59589 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/holiday/holidays.dm b/code/modules/holiday/holidays.dm index ddf0b30145f5..26438316b250 100644 --- a/code/modules/holiday/holidays.dm +++ b/code/modules/holiday/holidays.dm @@ -115,6 +115,7 @@ GLOBAL_LIST_INIT(holiday_mail, list()) // JANUARY +/* // DARKPACK EDIT REMOVAL - (TG lore cruft) //Fleet Day is celebrated on Jan 19th, the date on which moths were merged (#34498) /datum/holiday/fleet_day name = "Fleet Day" @@ -127,6 +128,7 @@ GLOBAL_LIST_INIT(holiday_mail, list()) /datum/holiday/fleet_day/getStationPrefix() return pick("Moth", "Fleet", "Nomadic") +*/ // FEBRUARY @@ -354,6 +356,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 @@ -363,6 +380,7 @@ GLOBAL_LIST_INIT(holiday_mail, list()) holiday_hat = /obj/item/clothing/head/utility/hardhat no_mail_holiday = TRUE +/* // DARKPACK EDIT REMOVAL - (TG lore cruft) //Draconic Day is celebrated on May 3rd, the date on which the Draconic language was merged (#26780) /datum/holiday/draconic_day name = "Draconic Language Day" @@ -374,6 +392,7 @@ GLOBAL_LIST_INIT(holiday_mail, list()) /datum/holiday/draconic_day/getStationPrefix() return pick("Draconic", "Literature", "Reading") +*/ /datum/holiday/firefighter name = "Firefighter's Day" @@ -418,6 +437,7 @@ GLOBAL_LIST_INIT(holiday_mail, list()) // JUNE +/* // DARKPACK EDIT REMOVAL - (TG lore cruft) //The Festival of Atrakor's Might (Tizira's Moon) is celebrated on June 15th, the date on which the lizard visual revamp was merged (#9808) /datum/holiday/atrakor_festival name = "Festival of Atrakor's Might" @@ -429,6 +449,7 @@ GLOBAL_LIST_INIT(holiday_mail, list()) /datum/holiday/atrakor_festival/getStationPrefix() return pick("Moon", "Night Sky", "Celebration") +*/ /// Garbage DAYYYYY /// Huh?.... NOOOO @@ -603,6 +624,7 @@ GLOBAL_LIST_INIT(holiday_mail, list()) // SEPTEMBER +/* // DARKPACK EDIT REMOVAL - (TG lore cruft) //Tiziran Unification Day is celebrated on Sept 1st, the day on which lizards were made a roundstart race /datum/holiday/tiziran_unification name = "Tiziran Unification Day" @@ -616,7 +638,9 @@ GLOBAL_LIST_INIT(holiday_mail, list()) /datum/holiday/tiziran_unification/getStationPrefix() return pick("Tizira", "Lizard", "Imperial") +*/ +/* // DARKPACK EDIT REMOVAL - (TG lore cruft) /datum/holiday/ianbirthday name = IAN_HOLIDAY //github.com/tgstation/tgstation/commit/de7e4f0de0d568cd6e1f0d7bcc3fd34700598acb begin_month = SEPTEMBER @@ -638,6 +662,7 @@ GLOBAL_LIST_INIT(holiday_mail, list()) /datum/holiday/ianbirthday/getStationPrefix() return pick("Ian", "Corgi", "Erro") +*/ /datum/holiday/pirate name = "Talk-Like-a-Pirate Day" @@ -793,6 +818,7 @@ GLOBAL_LIST_INIT(holiday_mail, list()) /datum/holiday/hello/greet() return "[pick(list("Aloha", "Bonjour", "Hello", "Hi", "Greetings", "Salutations", "Bienvenidos", "Hola", "Howdy", "Ni hao", "Guten Tag", "Konnichiwa", "G'day cunt"))]! " + ..() +/* // DARKPACK EDIT REMOVAL - (TG lore cruft) //The Festival of Holy Lights is celebrated on Nov 28th, the date on which ethereals were merged (#40995) /datum/holiday/holy_lights name = "Festival of Holy Lights" @@ -809,6 +835,7 @@ GLOBAL_LIST_INIT(holiday_mail, list()) /datum/holiday/holy_lights/getStationPrefix() return pick("Ethereal", "Lantern", "Holy") +*/ // DECEMBER diff --git a/code/modules/holodeck/turfs.dm b/code/modules/holodeck/turfs.dm index 7ef38b1a778b..afc68ef468b2 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 78538b3e8b9e..6e2db6c05bae 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 d2b7ebd59e17..a1c429f6e177 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) AddElement(/datum/element/contextual_screentip_sharpness, rmb_text = "Extract Seed") // DARKPACK EDIT ADD diff --git a/code/modules/hydroponics/growninedible.dm b/code/modules/hydroponics/growninedible.dm index 82c69a8ef09f..0502a500ef28 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/unique_plant_genes.dm b/code/modules/hydroponics/unique_plant_genes.dm index 7b273834a869..ad65e5f3a8e2 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/lighting/lighting_corner.dm b/code/modules/lighting/lighting_corner.dm index 4c35a8f2bb3c..1323f45f1e6a 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 c5ce42e45edd..85bcd6c0c31f 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 949d9b59b8f3..f3feed46bcff 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/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm b/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm index 0674ff97cb83..ffcd8c07a49f 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/museum.dm b/code/modules/mapfluff/ruins/objects_and_mobs/museum.dm index 2917c8b88e73..13963576232a 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/shoe_factory.dm b/code/modules/mapfluff/ruins/shoe_factory.dm new file mode 100644 index 000000000000..db2f8b20d937 --- /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:
    \ +
    \ + 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 0f6ff85eed92..a0a309849dc4 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 d19d5522bb77..ca22627233de 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/boulder_processing/_boulder_processing.dm b/code/modules/mining/boulder_processing/_boulder_processing.dm index 86a8679d0367..6d11c876bf36 100644 --- a/code/modules/mining/boulder_processing/_boulder_processing.dm +++ b/code/modules/mining/boulder_processing/_boulder_processing.dm @@ -23,6 +23,12 @@ ///The action verb to display to players var/action = "processing" + + /// What list of reagents should we look at when we boost the effectiveness of this machinery? Assign a value to a chem as well, eg: /datum/reagent/water = 1 is a 10% boost + var/list/booster_list = list() + /// 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) /// Cooldown associated with taking in boulds. @@ -75,14 +81,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 +104,15 @@ if(panel_open) . += span_notice("The whole machine can be [EXAMINE_HINT("pried")] apart.") +/obj/machinery/bouldertech/examine_more(mob/user) + . = ..() + + 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 = "" @@ -338,7 +357,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 +367,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,7 +378,7 @@ 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. @@ -387,7 +407,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 94435f233d77..96ed8878e71a 100644 --- a/code/modules/mining/boulder_processing/boulder.dm +++ b/code/modules/mining/boulder_processing/boulder.dm @@ -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/refinery.dm b/code/modules/mining/boulder_processing/refinery.dm index 861829219e23..52cf7189062a 100644 --- a/code/modules/mining/boulder_processing/refinery.dm +++ b/code/modules/mining/boulder_processing/refinery.dm @@ -5,12 +5,21 @@ */ /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 + + /// What list of reagents should we look at when we boost the effectiveness of this machinery? + booster_list = list( + /datum/reagent/toxin/acid = 1, + /datum/reagent/toxin/acid/fluacid = 2, + /datum/reagent/toxin/acid/nitracid = 3, + /datum/reagent/teslium = 5, + ) /obj/machinery/bouldertech/refinery/can_process_material(datum/material/possible_mat) var/static/list/processable_materials @@ -37,6 +46,56 @@ 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/Initialize(mapload) + . = ..() + AddComponent(/datum/component/plumbing/boulder_reactions) + AddElement(/datum/element/simple_rotation) + update_appearance(UPDATE_OVERLAYS) + +/obj/machinery/bouldertech/refinery/check_for_boosts() + . = ..() //resets to 1.00 efficiency in the parent + var/highest_boost = 0 + var/datum/reagent/biggest_booster + for(var/datum/reagent/chem in reagents.reagent_list) + if(!booster_list[chem.type]) + continue + if(!reagents.has_reagent(chem.type, booster_list[chem.type])) //check that we have the associated quantity of the chem in order to perform the boost. + continue + if(booster_list[chem.type] > highest_boost) + highest_boost = booster_list[chem.type] + biggest_booster = chem.type + + 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/default_deconstruction_screwdriver(mob/user, icon_state_open, icon_state_closed, obj/item/screwdriver) + . = ..() + set_light_on(TRUE) + +/obj/machinery/bouldertech/refinery/default_unfasten_wrench(mob/user, obj/item/wrench, time) + . = ..() + set_light_on(TRUE) + +/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 +103,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,6 +113,12 @@ circuit = /obj/item/circuitboard/machine/smelter usage_sound = 'sound/machines/mining/smelter.ogg' action = "smelting" + booster_list = list( + /datum/reagent/fuel = 1, + /datum/reagent/thermite = 2, + /datum/reagent/gunpowder = 3, + /datum/reagent/liquid_dark_matter = 5, + ) /obj/machinery/bouldertech/refinery/smelter/Initialize(mapload) . = ..() diff --git a/code/modules/mining/equipment/survival_pod.dm b/code/modules/mining/equipment/survival_pod.dm index 7ba37130ebc7..1f31fbb60536 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/lavaland/ash_flora.dm b/code/modules/mining/lavaland/ash_flora.dm index 9616c6149e56..7f8c16d805e9 100644 --- a/code/modules/mining/lavaland/ash_flora.dm +++ b/code/modules/mining/lavaland/ash_flora.dm @@ -414,12 +414,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/hierophant.dm b/code/modules/mining/lavaland/mining_loot/megafauna/hierophant.dm index 520502aaf305..38f515685440 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/machine_silo.dm b/code/modules/mining/machine_silo.dm index d35002d32f5f..deb61dca16ba 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/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index 832f6e28c3a3..9d8977e9cf9f 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -139,8 +139,10 @@ return "[jobtitle] doesn't have any free splat slots for you. (This can include human)" if(JOB_UNAVAILABLE_WHITELIST) return "You aren't whitelisted for [jobtitle]." - if(JOB_UNAVAILABLE_KINDRED_AGE) + if(JOB_UNAVAILABLE_KINDRED_AGE_MIN) return "Your character is too young for [jobtitle]." + if(JOB_UNAVAILABLE_KINDRED_AGE_MAX) + return "Your character is too old for [jobtitle]." if(JOB_UNAVAILABLE_KINDRED_GENERATION) return "Your character's generation is too high for [jobtitle]." if(JOB_UNAVAILABLE_KINDRED_CLAN) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index cd069dd8ae61..5d38c421e100 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) diff --git a/code/modules/mob/living/basic/alien/maid.dm b/code/modules/mob/living/basic/alien/maid.dm index cf6499884e95..7132f2ef4b08 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 283fa2c4e95b..6378daf25599 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) diff --git a/code/modules/mob/living/basic/basic_defense.dm b/code/modules/mob/living/basic/basic_defense.dm index 6e55dcfff874..fe19aad2b6c5 100644 --- a/code/modules/mob/living/basic/basic_defense.dm +++ b/code/modules/mob/living/basic/basic_defense.dm @@ -136,10 +136,12 @@ else log_combat(user, src, "punched") + /* // DARKPACK EDIT REMOVAL - (A decent amount of combat involves biting here which creates issue from being getting fat from combat) if(biting && (mob_biotypes & MOB_ORGANIC)) //Good for you. You probably just ate someone alive. var/datum/reagents/tasty_meal = new() tasty_meal.add_reagent(/datum/reagent/consumable/nutriment/protein, round(damage/3, 1)) tasty_meal.trans_to(user, tasty_meal.total_volume, transferred_by = user, methods = INGEST) + */ // DARKPACK EDIT CHANGE END updatehealth() return TRUE diff --git a/code/modules/mob/living/basic/boss/boss.dm b/code/modules/mob/living/basic/boss/boss.dm index 9453002a917b..298f1b8ca9a0 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/ed209/ed209.dm b/code/modules/mob/living/basic/bots/ed209/ed209.dm new file mode 100644 index 000000000000..83373e25a82d --- /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 000000000000..57d3143e1331 --- /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 000000000000..d699a153bb25 --- /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 000000000000..24bf9a203670 --- /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 000000000000..95c5b18ea24b --- /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 eb57581ae167..9d7abf3c1f63 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,19 @@ 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 +52,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 +91,33 @@ 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) 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 620a6fc6d97d..3a4d022087d9 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 000000000000..df71f848a941 --- /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 000000000000..23340fe22a0c --- /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 000000000000..6aadd73fd218 --- /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 000000000000..c34dca951560 --- /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 000000000000..1f82db49c7a5 --- /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 000000000000..effd9a98cab6 --- /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/farm_animals/bee/_bee.dm b/code/modules/mob/living/basic/farm_animals/bee/_bee.dm index a90b4e0dd4fd..66cd498ccd60 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/icemoon/ice_whelp/ice_whelp.dm b/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp.dm index 1000c919b11d..7d4c74747a33 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/jungle/seedling/seedling.dm b/code/modules/mob/living/basic/jungle/seedling/seedling.dm index 129e7d7b2f3a..49acc32e5ee0 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/gutlunchers/gutlunchers.dm b/code/modules/mob/living/basic/lavaland/gutlunchers/gutlunchers.dm index 87df7e847b57..9489a119c5c9 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/mook/mook.dm b/code/modules/mob/living/basic/lavaland/mook/mook.dm index a9cd028f4b6a..80d398f23d0c 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 diff --git a/code/modules/mob/living/basic/lavaland/raptor/_raptor.dm b/code/modules/mob/living/basic/lavaland/raptor/_raptor.dm index 82f8c484bcd5..9d8fb37179df 100644 --- a/code/modules/mob/living/basic/lavaland/raptor/_raptor.dm +++ b/code/modules/mob/living/basic/lavaland/raptor/_raptor.dm @@ -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/minebots/minebot.dm b/code/modules/mob/living/basic/minebots/minebot.dm index 0409095f8a87..525f1450141b 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 4d489d3987df..b2b0c12c9c37 100644 --- a/code/modules/mob/living/basic/pets/cat/cat.dm +++ b/code/modules/mob/living/basic/pets/cat/cat.dm @@ -109,21 +109,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 927faa23c963..97a44c433a00 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 /* // DARKPACK EDIT REMOVAL START - NPC - (Moving this into a proc so we can have subtypes with different commands) var/static/list/pet_commands = list( diff --git a/code/modules/mob/living/basic/pets/orbie/orbie.dm b/code/modules/mob/living/basic/pets/orbie/orbie.dm index 40a93f4b8828..fbbdfd89d22d 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 8e338d7bf609..d40a6af9b3dd 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/pet.dm b/code/modules/mob/living/basic/pets/pet.dm index ae32718b6583..d2f3ce283482 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 c6140302bf86..c19af0555295 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) 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 26bb5548e807..7b2846d42729 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/hivebot/_hivebot.dm b/code/modules/mob/living/basic/space_fauna/hivebot/_hivebot.dm index 925b5eb271e8..7b5edab617a0 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/morph.dm b/code/modules/mob/living/basic/space_fauna/morph.dm index 3190f3313e93..a76704e40fe9 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 42e6e831dd5b..f0e370c668e2 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/spider/giant_spider/giant_spiders.dm b/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spiders.dm index d2fbdaf44ffb..10db1405eeac 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 1399e5e1b0a7..ce246e1e0e3e 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 02f11dc94265..44d7585faffe 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 bae229fddd8c..5d370cf7cfbe 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/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index a42799967653..67dc73b3338c 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -130,8 +130,6 @@ 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() @@ -348,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/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index 3038c9b76fb1..0e6efd543571 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -131,3 +131,6 @@ var/obscured_slots = NONE /// Covered hide flags (hideflags that can be seen, BUT can't be interacted with) var/covered_slots = NONE + + /// 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 fb1ceda95585..171e53c65afc 100644 --- a/code/modules/mob/living/carbon/carbon_update_icons.dm +++ b/code/modules/mob/living/carbon/carbon_update_icons.dm @@ -464,10 +464,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 @@ -483,6 +486,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 @@ -498,6 +503,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 @@ -543,6 +552,12 @@ 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) @@ -565,44 +580,6 @@ . += "[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/human/dummy.dm b/code/modules/mob/living/carbon/human/dummy.dm index 1cb072c70805..2d99beba9197 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 7606e409ff56..93ff73faf36e 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1024,12 +1024,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) @@ -1039,9 +1039,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 @@ -1054,7 +1057,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 @@ -1152,8 +1158,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 20a79e802174..5eaf99419f1a 100644 --- a/code/modules/mob/living/carbon/human/human_update_icons.dm +++ b/code/modules/mob/living/carbon/human/human_update_icons.dm @@ -48,27 +48,27 @@ 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 @@ -860,57 +860,78 @@ generate/load female uniform sprites matching all previously decided variables 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() - 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() + . = 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) 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) 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) 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)) - 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) + var/obj/item/bodypart/head/noggin = get_bodypart(BODY_ZONE_HEAD) + if(isnull(noggin) || noggin.is_husked || noggin.is_invisible) return - 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 + if(refresh) + var/obj/item/organ/eyes/eyes = locate() in noggin + eyes?.refresh(src, call_update = FALSE) - eye_organ.refresh(call_update = FALSE) - overlays_standing[EYES_LAYER] = eye_organ.generate_body_overlay(src, noggin) - apply_overlay(EYES_LAYER) + var/list/eye_overlays = noggin.get_eye_overlays() + if(length(eye_overlays)) + overlays_standing[EYES_LAYER] = eye_overlays + 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() @@ -931,8 +952,8 @@ generate/load female uniform sprites matching all previously decided variables 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 @@ -941,11 +962,13 @@ generate/load female uniform sprites matching all previously decided variables if(!istype(my_head)) return - my_head.update_limb(is_creating = update_limb_data) - - add_overlay(my_head.get_limb_icon(dropped = FALSE, update_on = src)) + cut_overlays() + my_head.update_limb() + add_overlay(my_head.get_limb_icon()) update_worn_head() update_worn_mask() + update_eyes() + update_hair() /** * Used to perform regular updates to the limbs of humans with special bodyshapes diff --git a/code/modules/mob/living/carbon/human/init_signals.dm b/code/modules/mob/living/carbon/human/init_signals.dm index 55ab5d6b6b82..9f864884723a 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 10e9edfb715f..cfb9c5d8c163 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -286,18 +286,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/species_types/dullahan.dm b/code/modules/mob/living/carbon/human/species_types/dullahan.dm index 59bd21e22143..62bd2c1ae500 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 bfa1ae5649b9..2de3d7fc7991 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 28f676cb13f9..124196d02af5 100644 --- a/code/modules/mob/living/carbon/human/species_types/felinid.dm +++ b/code/modules/mob/living/carbon/human/species_types/felinid.dm @@ -128,7 +128,7 @@ 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.update_hair() /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/ghost.dm b/code/modules/mob/living/carbon/human/species_types/ghost.dm index 0a53c7b41ba7..d1da78e38700 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) - -/datum/action/innate/toggle_passthrough/proc/on_owner_died(mob/living/owner) - 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() + ), 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) -///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) +///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 - 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/vampire.dm b/code/modules/mob/living/carbon/human/species_types/vampire.dm index 6013c6d2b924..fb891df0f26f 100644 --- a/code/modules/mob/living/carbon/human/species_types/vampire.dm +++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm @@ -31,7 +31,6 @@ . = ..() 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)) if(new_vampire.hud_used) diff --git a/code/modules/mob/living/carbon/inventory.dm b/code/modules/mob/living/carbon/inventory.dm index 34c6e104e297..b8dfca193ba6 100644 --- a/code/modules/mob/living/carbon/inventory.dm +++ b/code/modules/mob/living/carbon/inventory.dm @@ -172,7 +172,8 @@ 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() add_item_coverage(item) /mob/living/carbon/has_unequipped(obj/item/item) @@ -182,7 +183,8 @@ hud_used?.update_locked_slots() if(item.hair_mask) - update_body() + LAZYREMOVE(hair_masks, item.hair_mask) + update_hair() remove_item_coverage(item) /mob/living/carbon/doUnEquip(obj/item/item_dropping, force, newloc, no_move, invdrop = TRUE, silent = FALSE) @@ -444,6 +446,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/death.dm b/code/modules/mob/living/death.dm index 324215167130..a7de4804b76c 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/living.dm b/code/modules/mob/living/living.dm index 02cd45cdae9c..c7b6ab02cbbd 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1485,7 +1485,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" @@ -1570,7 +1570,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, @@ -2447,7 +2447,7 @@ GLOBAL_LIST_EMPTY(fire_appearances) return if(. <= UNCONSCIOUS || new_stat >= UNCONSCIOUS) - update_body() // to update eyes + update_eyes() switch(.) //Previous stat. if(CONSCIOUS) diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index cfc7924aa3c9..69edd7a3728b 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 5e334f3ac751..8ff67ffb6d93 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 f8a998adb744..c983020026e2 100644 --- a/code/modules/mob/living/living_say.dm +++ b/code/modules/mob/living/living_say.dm @@ -306,13 +306,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/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 240ddabf39df..1ae21953f234 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -487,7 +487,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 ee7e53b7141b..000000000000 --- 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 15173c282c1a..7934d9ab858a 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 @@ -343,7 +343,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) @@ -433,10 +433,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 @@ -478,9 +478,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 @@ -513,9 +513,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 945d0c2eba9a..000000000000 --- 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 bd6024c74ad4..000000000000 --- a/code/modules/mob/living/simple_animal/bot/secbot.dm +++ /dev/null @@ -1,588 +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(100) - var/mob/living/carbon/human/human_target = current_target - threat = human_target.assess_threat(judgement_criteria) - else - 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 - - 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/status_procs.dm b/code/modules/mob/living/status_procs.dm index 4fbd0bf66a2b..1f20223787d7 100644 --- a/code/modules/mob/living/status_procs.dm +++ b/code/modules/mob/living/status_procs.dm @@ -513,19 +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)) + 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() @@ -541,8 +539,8 @@ /mob/living/proc/fakedeath(source, silent = FALSE) if(stat != DEAD) if(!silent) - INVOKE_ASYNC(src, TYPE_PROC_REF(/mob, emote), "deathgasp") - station_timestamp_timeofdeath = station_time_timestamp() + INVOKE_ASYNC(src, TYPE_PROC_REF(/mob, emote), "deathgasp") // DARKPACK EDIT CHANGE - (Made aysnc) + station_timestamp_timeofdeath = round_timestamp() if(!HAS_TRAIT(src, TRAIT_FAKEDEATH) && !silent) send_death_moodlets() diff --git a/code/modules/mob/mob_say.dm b/code/modules/mob/mob_say.dm index 568df514fdf4..901fd8fd1322 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.")) @@ -165,12 +159,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 210c041408c2..bbd617f97f7e 100644 --- a/code/modules/mob/mob_update_icons.dm +++ b/code/modules/mob/mob_update_icons.dm @@ -95,9 +95,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 fccd64ab7054..1f190d6cdb43 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/mod/modules/modules_general.dm b/code/modules/mod/modules/modules_general.dm index cf88eeffb1fd..9cc733599ba6 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_timeline.dm b/code/modules/mod/modules/modules_timeline.dm index a544e0963e01..0573d23e7b1d 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 cced073163e4..1225479d73bf 100644 --- a/code/modules/modular_computers/computers/item/computer.dm +++ b/code/modules/modular_computers/computers/item/computer.dm @@ -687,7 +687,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/file_system/programs/chatroom/conversation.dm b/code/modules/modular_computers/file_system/programs/chatroom/conversation.dm index 969e56195edb..0e65dfedd2a8 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/crewmanifest.dm b/code/modules/modular_computers/file_system/programs/crewmanifest.dm index d0dcf0ae873f..eccb78a58ff0 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/messenger/messenger_program.dm b/code/modules/modular_computers/file_system/programs/messenger/messenger_program.dm index dc83a7a76aee..e393ff2a60fb 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 @@ -544,7 +544,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) + 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 @@ -675,7 +675,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"]) + 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/paperwork/fax.dm b/code/modules/paperwork/fax.dm index b2d72873c5fb..deb2adc4e11f 100644 --- a/code/modules/paperwork/fax.dm +++ b/code/modules/paperwork/fax.dm @@ -479,7 +479,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 78f591b3ec36..5b2459d3caf2 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 diff --git a/code/modules/photography/_pictures.dm b/code/modules/photography/_pictures.dm index a59435f55491..76a0cf74bc22 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 3423abfb7b83..cb9d1ca3089d 100644 --- a/code/modules/photography/camera/camera.dm +++ b/code/modules/photography/camera/camera.dm @@ -32,6 +32,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. @@ -79,6 +81,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" @@ -98,6 +101,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)) @@ -211,7 +215,6 @@ */ /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 @@ -289,7 +292,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_Y, 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 @@ -305,7 +320,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) @@ -432,3 +449,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 7a4cc5857a0c..c2e516b6cfce 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 cb976a8cf319..8598302c8401 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 a6009b63528e..1d98d728b298 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/plumbers/synthesizer.dm b/code/modules/plumbing/plumbers/synthesizer.dm index f7adedddd03d..941837c8b6c4 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 e07086c87530..00b2e995f244 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 2f53861f4061..4af0bb0496b5 100644 --- a/code/modules/power/apc/apc_main.dm +++ b/code/modules/power/apc/apc_main.dm @@ -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/cable.dm b/code/modules/power/cable.dm index dc8da05dfebd..5b75b3d7567c 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -685,11 +685,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 @@ -697,31 +697,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/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index c7d79f1a5513..af4e7fa98acb 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/supermatter/supermatter_gas.dm b/code/modules/power/supermatter/supermatter_gas.dm index b6eb2804c28a..01eb977325ea 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 9d5fd1d38501..2717cdafa568 100644 --- a/code/modules/power/thermoelectric_generator.dm +++ b/code/modules/power/thermoelectric_generator.dm @@ -87,8 +87,7 @@ 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/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index 3ebfa61db277..8fc3bff10088 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -132,7 +132,7 @@ return ITEM_INTERACT_BLOCKING var/obj/item/stack/sheet = tool - if (sheet.use(1)) + if (!sheet.use(1)) return ITEM_INTERACT_BLOCKING cell.give(0.2 * STANDARD_CELL_CHARGE * charge_multiplier) diff --git a/code/modules/reagents/chemistry/machinery/chem_synthesizer.dm b/code/modules/reagents/chemistry/machinery/chem_synthesizer.dm index ddff805f45f0..6b9950ebd4bb 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/drinks/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm index fa1d9e4af984..29291d4f1d28 100644 --- a/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm @@ -3451,7 +3451,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" diff --git a/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/code/modules/reagents/chemistry/reagents/drug_reagents.dm index 5b1cced95ad3..2e776ebfb06b 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 62a10ff5ecee..dabf218bc2b6 100644 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -908,7 +908,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) diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 021c7d9b70bc..59edbd997d06 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -874,10 +874,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 @@ -2995,14 +2995,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) . = ..() @@ -3022,6 +3018,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 @@ -3036,12 +3036,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) @@ -3516,7 +3516,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" @@ -3549,3 +3549,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 9b059a93ea4d..ab6c99782870 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -1569,3 +1569,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/special.dm b/code/modules/reagents/chemistry/recipes/special.dm index 1dfd281c5ffc..7a26d8b7a1a7 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 12bd5470bea6..4323f78efd46 100644 --- a/code/modules/reagents/reagent_containers/blood_pack.dm +++ b/code/modules/reagents/reagent_containers/blood_pack.dm @@ -15,8 +15,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, start_blood_amount, list("blood_type" = bloodtype, "blood_DNA" = bloodtype.dna_string, BLOOD_DATA_SYNTH_CONTENT = 0.5), creation_callback = CALLBACK(src, PROC_REF(on_blood_created))) // DARKPACK EDIT CHANGE + reagents.add_reagent(bloodtype.reagent_type, start_blood_amount, list("blood_type" = bloodtype, "blood_DNA" = bloodtype.dna_string, BLOOD_DATA_SYNTH_CONTENT = 1), creation_callback = CALLBACK(src, PROC_REF(on_blood_created))) // DARKPACK EDIT CHANGE - (start_blood_volume) /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 9c6b9c4fe7df..d2983989813a 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/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index 53bbb8901799..09aedfb8460f 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -28,6 +28,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 ea20e85054ac..0466b026caa1 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 000000000000..9883c8253150 --- /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 000000000000..a6232b10d6cd --- /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 000000000000..51324bfc3815 --- /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 000000000000..c1c131978a4a --- /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 000000000000..f69777b6be38 --- /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 000000000000..96b61dd37daa --- /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 d375a1c38824..4a534c99a0fc 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 c57269fa0619..15973442a416 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 dd1e71b2cca0..e6d7369ee629 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 d2257515f8f1..77051641e50e 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/destructive_analyzer.dm b/code/modules/research/destructive_analyzer.dm index 0c958e557be7..4c08911af2e4 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/ordnance/_scipaper.dm b/code/modules/research/ordnance/_scipaper.dm index 0b5efc03e10f..e103416fd179 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)]" // DARKPACK EDIT CHANGE - CITY_TIME /datum/scientific_paper/explosive /** diff --git a/code/modules/research/ordnance/doppler_array.dm b/code/modules/research/ordnance/doppler_array.dm index b39758918ea4..3143ac15a120 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)]" // DARKPACK EDIT CHANGE - CITY_TIME 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 4887b41849b3..3662df233da7 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)]" // DARKPACK EDIT CHANGE - CITY_TIME 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/reta/reta_system.dm b/code/modules/reta/reta_system.dm index ebcfe06d8964..51591a20590b 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 f8cb0efd1166..e1bd0f77b774 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 2eee98a0d6f0..245d1cb3485d 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 dc1500437a3f..07115b52636e 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 3341f3a6aace..0370bc97099d 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/self/ghostliness.dm b/code/modules/spells/spell_types/self/ghostliness.dm new file mode 100644 index 000000000000..878114fa23f6 --- /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 dd2597d00970..aabec75e3db1 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 2b54350f8043..2836c854df9e 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -282,6 +282,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() @@ -660,8 +661,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 @@ -1202,7 +1202,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. diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index d0a3d18cfa2f..2ae41bd5eaea 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -328,7 +328,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() @@ -372,7 +372,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 034c1f8e7524..3a2f4ef01fa8 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) . = ..() @@ -188,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 - - 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(dropped) // These overlays are applied as standing overlays so we only need them if dropped + . += get_hair_overlays(dropped) + . += get_eye_overlays(dropped) - 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 f2af67ebac7f..43689b1852b4 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,110 +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/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 . + +/// 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) + + if(!facial_hair_hidden && (head_flags & HEAD_FACIAL_HAIR)) + . += get_base_facial_hair_overlays(dropped) + + 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 . + +/// 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 = null - if (dropped) - image_dir = SOUTH - - 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 - - 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 + 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) + // 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() - 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 - //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 - . += 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 + // 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_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) + PRIVATE_PROC(TRUE) 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) + 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) + 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 + hair_overlay.color = hair_color - return . +/// 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 . -#undef SET_OVERLAY_VALUE + 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) @@ -251,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. @@ -279,7 +268,7 @@ my_head?.hairstyle = new_style if(update) - update_body_parts() + update_hair() /** * Set the hair color of a human. @@ -300,7 +289,7 @@ my_head?.hair_color = hex_string if(update) - update_body_parts() + update_hair() /** * Get the hair gradient style of a human. @@ -352,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. @@ -406,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. @@ -422,7 +411,7 @@ my_head?.facial_hairstyle = new_style if(update) - update_body_parts() + update_hair() /** * Set the facial hair color of a human. @@ -443,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. @@ -462,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. @@ -481,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/species_parts/ghost_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/ghost_bodyparts.dm index f3247ab84dcf..8fd9913f6d30 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/organs/internal/ears/_ears.dm b/code/modules/surgery/organs/internal/ears/_ears.dm index ff8699165f77..a4d534b0d6df 100644 --- a/code/modules/surgery/organs/internal/ears/_ears.dm +++ b/code/modules/surgery/organs/internal/ears/_ears.dm @@ -253,10 +253,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 64285ea5afc1..a23b7ed06833 100644 --- a/code/modules/surgery/organs/internal/eyes/_eyes.dm +++ b/code/modules/surgery/organs/internal/eyes/_eyes.dm @@ -112,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 @@ -131,7 +134,7 @@ affected_human.add_fov_trait(type, native_fov) if(call_update) - affected_human.update_body() + affected_human.update_eyes() /obj/item/organ/eyes/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) . = ..() @@ -144,7 +147,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) @@ -173,6 +176,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 @@ -182,7 +199,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() @@ -285,47 +302,42 @@ // 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(!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.owner && !(my_head.owner.obscured_slots & HIDEEYES)) + overlays += get_emissive_overlays(eye_left, eye_right, my_head) + + 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 - if(head?.worn_face_offset) + if(my_head.worn_face_offset) for (var/mutable_appearance/overlay as anything in overlays) - head.worn_face_offset.apply_offset(overlay) + my_head.worn_face_offset.apply_offset(overlay) return overlays @@ -392,7 +404,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)) @@ -404,7 +416,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 @@ -448,10 +460,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) diff --git a/code/modules/surgery/organs/internal/eyes/eyes_augments.dm b/code/modules/surgery/organs/internal/eyes/eyes_augments.dm index 276b8437b887..0cce64e4c0ca 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/lungs/_lungs.dm b/code/modules/surgery/organs/internal/lungs/_lungs.dm index 38364f303918..6ccd4a85a8d4 100644 --- a/code/modules/surgery/organs/internal/lungs/_lungs.dm +++ b/code/modules/surgery/organs/internal/lungs/_lungs.dm @@ -1133,10 +1133,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/tgui_input/say_modal/modal.dm b/code/modules/tgui_input/say_modal/modal.dm index 2f4fb23f1f82..331f00b1518b 100644 --- a/code/modules/tgui_input/say_modal/modal.dm +++ b/code/modules/tgui_input/say_modal/modal.dm @@ -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) // DARKPACK EDIT CHANGE - ORIGINAL: if(payload["channel"] != OOC_CHANNEL && payload["channel"] != ADMIN_CHANNEL) + if(payload["channel"] != OOC_CHANNEL && payload["channel"] != LOOC_CHANNEL && payload["channel"] != ADMIN_CHANNEL && payload["channel"] != PRAY_CHANNEL) // DARKPACK EDIT CHANGE - LOOC 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 318f9cc002be..50c37ed3f4cc 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) // DARKPACK EDIT CHANGE - ORIGINAL: if(!entry || payload["channel"] == OOC_CHANNEL || payload["channel"] == ME_CHANNEL) + if(!entry || payload["channel"] == OOC_CHANNEL || payload["channel"] == LOOC_CHANNEL || payload["channel"] == ME_CHANNEL || payload["channel"] == PRAY_CHANNEL) // DARKPACK EDIT CHANGE - LOOC return pick(phrases) /// Random trimming for larger sentences if(length(entry) > 50) @@ -50,16 +50,19 @@ if(ADMIN_CHANNEL) INVOKE_ASYNC(SSadmin_verbs, TYPE_PROC_REF(/datum/controller/subsystem/admin_verbs, dynamic_invoke_verb), client, /datum/admin_verb/cmd_admin_say, entry) return TRUE - // DARKPACK EDIT START + if(PRAY_CHANNEL) + client.mob.pray(entry) + return TRUE + // DARKPACK EDIT ADD START - LOOC if(LOOC_CHANNEL) client.looc(entry) return TRUE -// DARKPACK EDIT END -// DARKPACK EDIT ADD START - DO_EMOTES + // DARKPACK EDIT ADD END + // DARKPACK EDIT ADD START - DO_EMOTES if(DO_CHANNEL) client.mob.do_verb(entry) return TRUE -// DARKPACK EDIT ADD END + // DARKPACK EDIT ADD END return FALSE /** @@ -139,7 +142,7 @@ return TRUE if(type == "force") var/target_channel = payload["channel"] - if(target_channel == ME_CHANNEL || target_channel == OOC_CHANNEL || target_channel == LOOC_CHANNEL) // DARKPACK EDIT CHANGE - ORIGINAL: if(target_channel == ME_CHANNEL || target_channel == OOC_CHANNEL) + if(target_channel == ME_CHANNEL || target_channel == OOC_CHANNEL || target_channel == LOOC_CHANNEL || target_channel == PRAY_CHANNEL) // DARKPACK EDIT CHANGE - LOOC target_channel = SAY_CHANNEL // No ooc leaks delegate_speech(alter_entry(payload), target_channel) return TRUE diff --git a/code/modules/transport/tram/tram_controller.dm b/code/modules/transport/tram/tram_controller.dm index 4194493f27d9..fef1bbdcbf3d 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 abc4c37e8bf2..5800b131c589 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" diff --git a/code/modules/unit_tests/dna_infusion.dm b/code/modules/unit_tests/dna_infusion.dm index 4abe0e16e547..a8d8b2ea4ec7 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/plane_double_transform.dm b/code/modules/unit_tests/plane_double_transform.dm index 3379f751e117..fc0245d0c548 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] - - 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.") + 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.") - // 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/screenshot_debrain.dm b/code/modules/unit_tests/screenshot_debrain.dm new file mode 100644 index 000000000000..2eca2abd9161 --- /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 000000000000..94574f559957 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_silverscale.png b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_lizard_silverscale.png index 61c3aa6ec7b2..42a7025f0078 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 000000000000..5b08e042a023 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/screenshots/screenshot_humanoids__datum_species_tzimisce_blood_form.png b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_tzimisce_blood_form.png index b5d9f07b41bb..23d046199449 100644 Binary files a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_tzimisce_blood_form.png and b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_tzimisce_blood_form.png differ diff --git a/code/modules/unit_tests/simple_animal_freeze.dm b/code/modules/unit_tests/simple_animal_freeze.dm index 2f6f301a8e50..1c6dc15cdae2 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/surgeries.dm b/code/modules/unit_tests/surgeries.dm index 661e48aee572..2cf9f9bdb00e 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/unit_test.dm b/code/modules/unit_tests/unit_test.dm index 3814df5ef38c..74f41bf10884 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/nukeops.dm b/code/modules/uplink/uplink_items/nukeops.dm index bf7c5ffa14fd..265c43dce651 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/vehicles/mecha/equipment/tools/air_tank.dm b/code/modules/vehicles/mecha/equipment/tools/air_tank.dm index 6d9765e6b058..eae27f5a183a 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/wiremod/components/usb/emitter.dm b/code/modules/wiremod/components/usb/emitter.dm new file mode 100644 index 000000000000..a817a3d8cf55 --- /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 000000000000..abd199701d17 --- /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 000000000000..49929e2da83e --- /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 fa675bfa1b9d..e40e4d1f09cd 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/darkpack/city_time.txt b/config/darkpack/city_time.txt new file mode 100644 index 000000000000..0b6162bfda75 --- /dev/null +++ b/config/darkpack/city_time.txt @@ -0,0 +1,6 @@ +## The shift start hour in 24-hour (0-23) notation +SHIFT_TIME_START_HOUR 19 + +## In deciseconds +#TIME_UNTILL_DAY 198000 +#TIME_UNTILL_ROUNDEND 216000 diff --git a/config/game_options.txt b/config/game_options.txt index 3b66a0668bee..9916cb44c4fe 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -157,7 +157,7 @@ DYNAMIC_CONFIG_ENABLED ## RANDOM EVENTS ### ## Comment this out to disable random events during the round. -#ALLOW_RANDOM_EVENTS +ALLOW_RANDOM_EVENTS ## Uncomment this to disable station traits. #FORBID_STATION_TRAITS @@ -492,19 +492,6 @@ DISABLE_HUMAN_MOOD ## Enable night shifts #ENABLE_NIGHT_SHIFTS -## The shift start hour in 24-hour (0-23) notation -SHIFT_TIME_START_HOUR 19 - -## 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 - -## In deciseconds -#TIME_UNTILL_DAY 198000 -#TIME_UNTILL_ROUNDEND 216000 - ## 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 d6a945ff38a1..1f3236c753c8 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 diff --git a/config/lavaruinblacklist.txt b/config/lavaruinblacklist.txt index aaa507374cb6..16382c128b78 100644 --- a/config/lavaruinblacklist.txt +++ b/config/lavaruinblacklist.txt @@ -14,6 +14,7 @@ #_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm #_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm #_maps/RandomRuins/AnywhereRuins/golem_ship.dmm +#_maps/RandomRuins/AnywhereRuins/shoe_factory.dmm ##SIN #_maps/RandomRuins/LavaRuins/lavaland_surface_envy.dmm diff --git a/html/changelogs/AutoChangeLog-pr-1002.yml b/html/changelogs/AutoChangeLog-pr-1002.yml new file mode 100644 index 000000000000..bb261d1c62df --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-1002.yml @@ -0,0 +1,4 @@ +author: "Magisterium2022" +delete-after: True +changes: + - balance: "Made Lupus and Hispo unable to be handcuffed." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-1004.yml b/html/changelogs/AutoChangeLog-pr-1004.yml new file mode 100644 index 000000000000..a72a0c9cf539 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-1004.yml @@ -0,0 +1,5 @@ +author: "FalloutFalcon" +delete-after: True +changes: + - balance: "number of successes required for Fera shifting is based on how many forms your swapping between" + - bugfix: "Feras's shift difficulty is based on the form your currently in rather then the one your turning into" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-1007.yml b/html/changelogs/AutoChangeLog-pr-1007.yml new file mode 100644 index 000000000000..6f48ff462819 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-1007.yml @@ -0,0 +1,8 @@ +author: "FalloutFalcon" +delete-after: True +changes: + - rscadd: "Adds support for automatic successes based on the TTRPG" + - code_imp: "Cleans up some of the code surrounding potance" + - balance: "Kills some of the snowflaky effect of potance in favor of it granting automatic successes (TTRPG accuracy)" + - qol: "Makes the dice unicode characters to show individual dice results a little larger" + - bugfix: "Potance 1-2 no longer cripples melee damage and it now scales correctly with all dots." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-1008.yml b/html/changelogs/AutoChangeLog-pr-1008.yml new file mode 100644 index 000000000000..bd3046f7a227 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-1008.yml @@ -0,0 +1,4 @@ +author: "FalloutFalcon" +delete-after: True +changes: + - bugfix: "Doors can no longer be repunched for infinite door items" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-1013.yml b/html/changelogs/AutoChangeLog-pr-1013.yml new file mode 100644 index 000000000000..a7526bbc63d3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-1013.yml @@ -0,0 +1,4 @@ +author: "FalloutFalcon" +delete-after: True +changes: + - rscdel: "Removed some TG holidays from appearing" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-1018.yml b/html/changelogs/AutoChangeLog-pr-1018.yml new file mode 100644 index 000000000000..7016ff57dc76 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-1018.yml @@ -0,0 +1,4 @@ +author: "chazzyjazzy" +delete-after: True +changes: + - balance: "animalism mobs now have bloodpool = 2" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-1019.yml b/html/changelogs/AutoChangeLog-pr-1019.yml new file mode 100644 index 000000000000..8a1e87dbcf52 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-1019.yml @@ -0,0 +1,6 @@ +author: "chazzyjazzy" +delete-after: True +changes: + - bugfix: "fixes Thaumaturgy 4 not incrementing the target's bloodpool" + - bugfix: "Thaumaturgy 4 Theft of Vitae now costs 1 bloodpoint" + - balance: "lowers Lure of Flames and Levinbolt 'palm of flame'-type ability's damage from 25 burn (50 against kindred) per click to 15 burn (30 against kindred), 20 for 'candle' and 'illuminate'" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-980.yml b/html/changelogs/AutoChangeLog-pr-1020.yml similarity index 55% rename from html/changelogs/AutoChangeLog-pr-980.yml rename to html/changelogs/AutoChangeLog-pr-1020.yml index a32be687a82f..301c9752c83b 100644 --- a/html/changelogs/AutoChangeLog-pr-980.yml +++ b/html/changelogs/AutoChangeLog-pr-1020.yml @@ -1,4 +1,4 @@ author: "FalloutFalcon" delete-after: True changes: - - image: "hair dye spray has an onfloor" \ No newline at end of file + - rscadd: "Delirium status effect" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-1021.yml b/html/changelogs/AutoChangeLog-pr-1021.yml new file mode 100644 index 000000000000..5de36deac2f2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-1021.yml @@ -0,0 +1,4 @@ +author: "FalloutFalcon" +delete-after: True +changes: + - qol: "Makes the local host start now sound quieter and only play once" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-1022.yml b/html/changelogs/AutoChangeLog-pr-1022.yml new file mode 100644 index 000000000000..97bd1e842731 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-1022.yml @@ -0,0 +1,4 @@ +author: "FalloutFalcon" +delete-after: True +changes: + - balance: "Fera transformations damage worn clothing" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-1023.yml b/html/changelogs/AutoChangeLog-pr-1023.yml new file mode 100644 index 000000000000..0c76ebc0bffb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-1023.yml @@ -0,0 +1,4 @@ +author: "Stutternov" +delete-after: True +changes: + - rscadd: "Adds maximum immortal age variable for jobs." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-862.yml b/html/changelogs/AutoChangeLog-pr-1025.yml similarity index 58% rename from html/changelogs/AutoChangeLog-pr-862.yml rename to html/changelogs/AutoChangeLog-pr-1025.yml index 94b77600ca91..68fd006e4c9e 100644 --- a/html/changelogs/AutoChangeLog-pr-862.yml +++ b/html/changelogs/AutoChangeLog-pr-1025.yml @@ -1,4 +1,4 @@ author: "chazzyjazzy" delete-after: True changes: - - rscadd: "fixes serpentis 1" \ No newline at end of file + - bugfix: "adds hunter landmarks" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-979.yml b/html/changelogs/AutoChangeLog-pr-1026.yml similarity index 50% rename from html/changelogs/AutoChangeLog-pr-979.yml rename to html/changelogs/AutoChangeLog-pr-1026.yml index 8a05e1fa8447..20b1e0f135c4 100644 --- a/html/changelogs/AutoChangeLog-pr-979.yml +++ b/html/changelogs/AutoChangeLog-pr-1026.yml @@ -1,4 +1,4 @@ author: "FalloutFalcon" delete-after: True changes: - - balance: "reduces the rate at which cats breed" \ No newline at end of file + - balance: "Removes nutriment gain from biting" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-1028.yml b/html/changelogs/AutoChangeLog-pr-1028.yml new file mode 100644 index 000000000000..377d115d68c3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-1028.yml @@ -0,0 +1,4 @@ +author: "FalloutFalcon, Major00" +delete-after: True +changes: + - image: "Resprites wooden drying racks" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-1029.yml b/html/changelogs/AutoChangeLog-pr-1029.yml new file mode 100644 index 000000000000..f20e1cf797b9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-1029.yml @@ -0,0 +1,4 @@ +author: "FalloutFalcon" +delete-after: True +changes: + - rscadd: "landmark for cargo crate delivery locations" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-1030.yml b/html/changelogs/AutoChangeLog-pr-1030.yml new file mode 100644 index 000000000000..eda8cac2747a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-1030.yml @@ -0,0 +1,4 @@ +author: "Beautiful TG coders" +delete-after: True +changes: + - code_imp: "TG Pull. Thank you TG." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-1032.yml b/html/changelogs/AutoChangeLog-pr-1032.yml new file mode 100644 index 000000000000..d21efc1391c9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-1032.yml @@ -0,0 +1,4 @@ +author: "buffyuwu" +delete-after: True +changes: + - bugfix: "fera no longer feel terribly bloated all the time" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-1037.yml b/html/changelogs/AutoChangeLog-pr-1037.yml new file mode 100644 index 000000000000..c3c50cb5c355 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-1037.yml @@ -0,0 +1,4 @@ +author: "Biplume" +delete-after: True +changes: + - bugfix: "Rolls to not step on sticks are now private." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-1039.yml b/html/changelogs/AutoChangeLog-pr-1039.yml new file mode 100644 index 000000000000..8393aa56a074 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-1039.yml @@ -0,0 +1,4 @@ +author: "FalloutFalcon" +delete-after: True +changes: + - rscadd: "Two separate fields for flavor text that overwrite existing one when your in crinos or hispo/lupus respectivly" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-1041.yml b/html/changelogs/AutoChangeLog-pr-1041.yml new file mode 100644 index 000000000000..34dc990b92e4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-1041.yml @@ -0,0 +1,4 @@ +author: "buffyuwu" +delete-after: True +changes: + - bugfix: "Ghoul auras are no longer fully opaque" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-1045.yml b/html/changelogs/AutoChangeLog-pr-1045.yml new file mode 100644 index 000000000000..b1de8eb39d77 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-1045.yml @@ -0,0 +1,4 @@ +author: "lobotomypilled" +delete-after: True +changes: + - bugfix: "fixed transformers being unrepairable upon failing the roll\n:cl:" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-491.yml b/html/changelogs/AutoChangeLog-pr-491.yml deleted file mode 100644 index 55a2e2f9d0cc..000000000000 --- a/html/changelogs/AutoChangeLog-pr-491.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "dwinters99" -delete-after: True -changes: - - rscadd: "company logo element" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-683.yml b/html/changelogs/AutoChangeLog-pr-683.yml deleted file mode 100644 index 750ed61a21c9..000000000000 --- a/html/changelogs/AutoChangeLog-pr-683.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "FalloutFalcon" -delete-after: True -changes: - - rscadd: "reworks frenzying to be a role-play/fluff effect rather then stealing control of your character." - - bugfix: "color effect from Kiss status effect should properly clear" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-835.yml b/html/changelogs/AutoChangeLog-pr-835.yml deleted file mode 100644 index b59e87124485..000000000000 --- a/html/changelogs/AutoChangeLog-pr-835.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "theselfish" -delete-after: True -changes: - - rscadd: "Tremere may have a Third Eye." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-850.yml b/html/changelogs/AutoChangeLog-pr-850.yml new file mode 100644 index 000000000000..e92eca185a0c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-850.yml @@ -0,0 +1,4 @@ +author: "Kolibri-B" +delete-after: True +changes: + - bugfix: "Fixed Obtenebration 3 \"Arms of the Abyss\" tentacle behaviour" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-908.yml b/html/changelogs/AutoChangeLog-pr-908.yml new file mode 100644 index 000000000000..2d0f7c715cd4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-908.yml @@ -0,0 +1,5 @@ +author: "FalloutFalcon" +delete-after: True +changes: + - rscadd: "Adds two werewolf fetishes; Nyxs Bangle and Dagger of retribution" + - refactor: "Cleans up some artifact code around ownership and power granting" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-946.yml b/html/changelogs/AutoChangeLog-pr-946.yml deleted file mode 100644 index 22411fb1beb0..000000000000 --- a/html/changelogs/AutoChangeLog-pr-946.yml +++ /dev/null @@ -1,10 +0,0 @@ -author: "chazzyjazzy, buffyuwu" -delete-after: True -changes: - - rscadd: "blush of health quirk" - - rscadd: "eat food quirk" - - bugfix: "aura hearts now beat only when they should" - - bugfix: "setites now get their clan keys" - - bugfix: "bloodpacks now actually increment bloodpool" - - bugfix: "sunglasses and other glasses now act in the same way masks do for masquerade violating eyes" - - bugfix: "dementation's missing sprite is now patched" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-947.yml b/html/changelogs/AutoChangeLog-pr-947.yml deleted file mode 100644 index 7225ecbbb8b0..000000000000 --- a/html/changelogs/AutoChangeLog-pr-947.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "chazzyjazzy" -delete-after: True -changes: - - rscadd: "gargoyles can now tuck their wings, preventing them from flying, but making them able to wear other clothes" - - rscadd: "gargoyle flight now makes a flapping noise" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-948.yml b/html/changelogs/AutoChangeLog-pr-948.yml new file mode 100644 index 000000000000..645c8f0d56ed --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-948.yml @@ -0,0 +1,7 @@ +author: "buffyuwu" +delete-after: True +changes: + - rscadd: "ghouls now get potence 1 for free" + - bugfix: "ghouls can now only have level 1 in their disciplines" + - bugfix: "solves bloodheal and potence harddels by removing the disciplines on_lose_or_destroy" + - bugfix: "fixes a bug with transformation disciplines causing disciplines to become unusable" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-957.yml b/html/changelogs/AutoChangeLog-pr-957.yml deleted file mode 100644 index 90f7555c7a7c..000000000000 --- a/html/changelogs/AutoChangeLog-pr-957.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "chazzyjazzy" -delete-after: True -changes: - - bugfix: "negative stat modifiers now work" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-968.yml b/html/changelogs/AutoChangeLog-pr-968.yml deleted file mode 100644 index ad238d431d88..000000000000 --- a/html/changelogs/AutoChangeLog-pr-968.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "chazzyjazzy" -delete-after: True -changes: - - rscadd: "store owners now say unique things to you when you open their store" - - rscadd: "store owners now have revamped outfits for unique and cool looks" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-969.yml b/html/changelogs/AutoChangeLog-pr-969.yml deleted file mode 100644 index 5f9e57ad30c5..000000000000 --- a/html/changelogs/AutoChangeLog-pr-969.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "chazzyjazzy" -delete-after: True -changes: - - bugfix: "readds bank vault door to giovanni kindred roles" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-973.yml b/html/changelogs/AutoChangeLog-pr-973.yml deleted file mode 100644 index 3123762b46ea..000000000000 --- a/html/changelogs/AutoChangeLog-pr-973.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "chazzyjazzy" -delete-after: True -changes: - - rscadd: "makes lightposts go out when the area power transformer is broken" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-974.yml b/html/changelogs/AutoChangeLog-pr-974.yml deleted file mode 100644 index fbd4ebdfb264..000000000000 --- a/html/changelogs/AutoChangeLog-pr-974.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "chazzyjazzy" -delete-after: True -changes: - - bugfix: "fixes the very smallest and the very tallest height from not being applied" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-975.yml b/html/changelogs/AutoChangeLog-pr-975.yml deleted file mode 100644 index 55baf52ae68a..000000000000 --- a/html/changelogs/AutoChangeLog-pr-975.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "buffyuwu" -delete-after: True -changes: - - bugfix: "Crime will no longer be automatically reported outside of masquerade enforced areas" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-977.yml b/html/changelogs/AutoChangeLog-pr-977.yml deleted file mode 100644 index 164b8e64dfe9..000000000000 --- a/html/changelogs/AutoChangeLog-pr-977.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "FalloutFalcon" -delete-after: True -changes: - - rscdel: "Removes dice output preference in favor of always outputting to chat unless declared by the roll." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-982.yml b/html/changelogs/AutoChangeLog-pr-982.yml new file mode 100644 index 000000000000..960620cefdc6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-982.yml @@ -0,0 +1,4 @@ +author: "chazzyjazzy" +delete-after: True +changes: + - rscadd: "adds the Society of Leopold, the largest subdivision of the Inquisiton, Vampire and Werewolf hunters" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-983.yml b/html/changelogs/AutoChangeLog-pr-983.yml deleted file mode 100644 index 2ca357f86c4a..000000000000 --- a/html/changelogs/AutoChangeLog-pr-983.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "FalloutFalcon" -delete-after: True -changes: - - config: "Adds config for if roleplay only merits are available" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-985.yml b/html/changelogs/AutoChangeLog-pr-985.yml deleted file mode 100644 index 5946c57a917d..000000000000 --- a/html/changelogs/AutoChangeLog-pr-985.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "chazzyjazzy" -delete-after: True -changes: - - rscadd: "empty bloodbags can now be bought at the pharmacy" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-986.yml b/html/changelogs/AutoChangeLog-pr-986.yml deleted file mode 100644 index e9ba16b73314..000000000000 --- a/html/changelogs/AutoChangeLog-pr-986.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "chazzyjazzy" -delete-after: True -changes: - - code_imp: "every job datum now has a faction" - - code_imp: "removes unused and useless 'is_gun_store' job on /obj/structure/retail" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-988.yml b/html/changelogs/AutoChangeLog-pr-988.yml new file mode 100644 index 000000000000..505cca2995cb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-988.yml @@ -0,0 +1,5 @@ +author: "chazzyjazzy" +delete-after: True +changes: + - rscadd: "adds blackout random event" + - code_imp: "cleaned up fusebox damage code" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-990.yml b/html/changelogs/AutoChangeLog-pr-990.yml deleted file mode 100644 index d15e8fa8867e..000000000000 --- a/html/changelogs/AutoChangeLog-pr-990.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "FalloutFalcon" -delete-after: True -changes: - - balance: "Fera claws are sharp and deal aggravated damage" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-992.yml b/html/changelogs/AutoChangeLog-pr-992.yml deleted file mode 100644 index a4616ca40e15..000000000000 --- a/html/changelogs/AutoChangeLog-pr-992.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "FalloutFalcon, CYBILIZE" -delete-after: True -changes: - - bugfix: "fixed separate phone calls occasionally sharing audio with each other" - - code_imp: "corrected secure phone frequency assignment logic" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-993.yml b/html/changelogs/AutoChangeLog-pr-993.yml deleted file mode 100644 index 70a15c6751fd..000000000000 --- a/html/changelogs/AutoChangeLog-pr-993.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "FalloutFalcon" -delete-after: True -changes: - - balance: "Claws are prefered to kicking" - - bugfix: "Claws get intended bonus dice on basic mobs" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-994.yml b/html/changelogs/AutoChangeLog-pr-994.yml deleted file mode 100644 index 6e0c019d6738..000000000000 --- a/html/changelogs/AutoChangeLog-pr-994.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "FalloutFalcon" -delete-after: True -changes: - - balance: "You can no longer jump while lying down" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-962.yml b/html/changelogs/AutoChangeLog-pr-997.yml similarity index 53% rename from html/changelogs/AutoChangeLog-pr-962.yml rename to html/changelogs/AutoChangeLog-pr-997.yml index 2a5c7c64ec6d..8ab2c4bc30ec 100644 --- a/html/changelogs/AutoChangeLog-pr-962.yml +++ b/html/changelogs/AutoChangeLog-pr-997.yml @@ -1,4 +1,4 @@ author: "FalloutFalcon" delete-after: True changes: - - qol: "Street signs tell you where you are" \ No newline at end of file + - rscadd: "Adds Wolf Sight Merit from W20" \ No newline at end of file diff --git a/html/changelogs/archive/2026-05.yml b/html/changelogs/archive/2026-05.yml new file mode 100644 index 000000000000..356dd54adaa1 --- /dev/null +++ b/html/changelogs/archive/2026-05.yml @@ -0,0 +1,54 @@ +2026-05-04: + Biplume: + - balance: Crinos, Hispo, and Lupus speeds were all nerfed. + - balance: Hispo and Lupus bites do aggravated damage. + FalloutFalcon: + - config: Adds config for if roleplay only merits are available + - balance: You can no longer jump while lying down + - qol: Street signs tell you where you are + - balance: Claws are prefered to kicking + - bugfix: Claws get intended bonus dice on basic mobs + - balance: Fera claws are sharp and deal aggravated damage + - rscadd: reworks frenzying to be a role-play/fluff effect rather then stealing + control of your character. + - bugfix: color effect from Kiss status effect should properly clear + - balance: fera warforms are considered large mobs + - balance: Gangrel forms are downgraded to large mobs instead of huge + - image: hair dye spray has an onfloor + - rscdel: Removes dice output preference in favor of always outputting to chat unless + declared by the roll. + - balance: reduces the rate at which cats breed + FalloutFalcon, CYBILIZE: + - bugfix: fixed separate phone calls occasionally sharing audio with each other + - code_imp: corrected secure phone frequency assignment logic + buffyuwu: + - bugfix: Crime will no longer be automatically reported outside of masquerade enforced + areas + chazzyjazzy: + - code_imp: every job datum now has a faction + - code_imp: removes unused and useless 'is_gun_store' job on /obj/structure/retail + - bugfix: fixes the very smallest and the very tallest height from not being applied + - rscadd: store owners now say unique things to you when you open their store + - rscadd: store owners now have revamped outfits for unique and cool looks + - rscadd: makes lightposts go out when the area power transformer is broken + - rscadd: gargoyles can now tuck their wings, preventing them from flying, but making + them able to wear other clothes + - rscadd: gargoyle flight now makes a flapping noise + - rscadd: fixes serpentis 1 + - bugfix: readds bank vault door to giovanni kindred roles + - bugfix: adds npc subtypes for the new store owners + - rscadd: empty bloodbags can now be bought at the pharmacy + - bugfix: negative stat modifiers now work + chazzyjazzy, buffyuwu: + - rscadd: blush of health quirk + - rscadd: eat food quirk + - bugfix: aura hearts now beat only when they should + - bugfix: setites now get their clan keys + - bugfix: bloodpacks now actually increment bloodpool + - bugfix: sunglasses and other glasses now act in the same way masks do for masquerade + violating eyes + - bugfix: dementation's missing sprite is now patched + dwinters99: + - rscadd: company logo element + theselfish: + - rscadd: Tremere may have a Third Eye. diff --git a/icons/effects/lighting_object.dmi b/icons/effects/lighting_object.dmi index d2e503958723..f2d5960d91b0 100644 Binary files a/icons/effects/lighting_object.dmi and b/icons/effects/lighting_object.dmi differ diff --git a/icons/map_icons/items/_item.dmi b/icons/map_icons/items/_item.dmi index 9988f49c6fa8..16535bf205f1 100644 Binary files a/icons/map_icons/items/_item.dmi and b/icons/map_icons/items/_item.dmi differ diff --git a/icons/mob/clothing/head/costume.dmi b/icons/mob/clothing/head/costume.dmi index ea18067ebc18..ac776302e255 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/spacehelm.dmi b/icons/mob/clothing/head/spacehelm.dmi index b623fa0beeaf..54ae72503986 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 25f10c4b648b..c55785d0412e 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 a44781036a0f..6dad4d75a7b0 100644 Binary files a/icons/mob/clothing/neck.dmi and b/icons/mob/clothing/neck.dmi differ diff --git a/icons/mob/clothing/under/syndicate.dmi b/icons/mob/clothing/under/syndicate.dmi index 0e9d8dfc91b0..f2ea936badd3 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 f22d3fc386cc..42185e3db54b 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 25b5feddc227..b2e48a848b21 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 f3a9caa91834..9ab5cb393814 100644 Binary files a/icons/mob/inhands/64x64_righthand.dmi and b/icons/mob/inhands/64x64_righthand.dmi differ diff --git a/icons/mob/silicon/aibots.dmi b/icons/mob/silicon/aibots.dmi index fa4c11f891a6..2df5bce43a32 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 e09af620e944..52073541f896 100644 Binary files a/icons/mob/simple/animal.dmi and b/icons/mob/simple/animal.dmi differ diff --git a/icons/obj/chairs.dmi b/icons/obj/chairs.dmi index b1432f16701c..26a1861af2f9 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 9e3ad9e212c9..fce68eb8f212 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/spacehelm.dmi b/icons/obj/clothing/head/spacehelm.dmi index 05362ab689f3..5bf888d1216d 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 a2dac17cc8b3..cb9c4a72e8de 100644 Binary files a/icons/obj/clothing/masks.dmi and b/icons/obj/clothing/masks.dmi differ diff --git a/icons/obj/clothing/neck.dmi b/icons/obj/clothing/neck.dmi index 0b19dff85b00..6fc8b054ca51 100644 Binary files a/icons/obj/clothing/neck.dmi and b/icons/obj/clothing/neck.dmi differ diff --git a/icons/obj/clothing/under/syndicate.dmi b/icons/obj/clothing/under/syndicate.dmi index de712a41f6b3..49407a02d4f2 100644 Binary files a/icons/obj/clothing/under/syndicate.dmi and b/icons/obj/clothing/under/syndicate.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 000000000000..fe54b6826cca 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 000000000000..ea4453bf0cc7 Binary files /dev/null and b/icons/obj/doors/syndicateshutters.dmi differ diff --git a/icons/obj/mining_zones/artefacts.dmi b/icons/obj/mining_zones/artefacts.dmi index 86cfdcd76248..4c4dda6aa20f 100644 Binary files a/icons/obj/mining_zones/artefacts.dmi and b/icons/obj/mining_zones/artefacts.dmi differ diff --git a/icons/obj/service/hand_of_god_structures.dmi b/icons/obj/service/hand_of_god_structures.dmi index cbbc36d77188..e9d94cef78f9 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/signboards.dmi b/icons/obj/signboards.dmi new file mode 100644 index 000000000000..c1db06ee9b70 Binary files /dev/null and b/icons/obj/signboards.dmi differ diff --git a/interface/skin.dmf b/interface/skin.dmf index 61d8248ce24f..efb4047e95fe 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -138,7 +138,6 @@ window "info_and_buttons" size = 640x477 anchor1 = 0,0 anchor2 = 100,100 - background-color = #ffc41f saved-params = "splitter" left = "infobuttons" right = "infowindow" @@ -149,33 +148,58 @@ window "info_and_buttons" 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 "outputwindow" - elem "outputwindow" +window "input_buttons" + elem "input_buttons_main" type = MAIN pos = 0,0 size = 640x475 - anchor1 = -1,-1 - anchor2 = -1,-1 + anchor1 = 0,0 + anchor2 = 100,100 saved-params = "pos;size;is-minimized;is-maximized" is-pane = true - elem "output_input_child" + elem "input_buttons_child" type = CHILD pos = 0,0 size = 640x475 @@ -183,14 +207,14 @@ window "outputwindow" anchor2 = 100,100 background-color = #ffc41f saved-params = "splitter" - left = "output_selector" - right = "input_and_buttons" - is-vert = false - splitter = 96 + left = "inputwindow" + right = "inputbuttons" + is-vert = true + splitter = 70 show-splitter = false -window "output_selector" - elem "output_selector" +window "outputwindow" + elem "outputwindow" type = MAIN pos = 0,0 size = 640x475 @@ -198,36 +222,33 @@ window "output_selector" anchor2 = -1,-1 saved-params = "pos;size;is-minimized;is-maximized" is-pane = true - elem "legacy_output_selector" + elem "output_selector_screen" type = CHILD - pos = 0,0 size = 640x475 anchor1 = 0,0 anchor2 = 100,100 saved-params = "splitter" - left = "output_legacy" - is-vert = false + background-color = #ffc41f + left = "output_selector" -window "input_and_buttons" - elem "input_and_buttons" +window "output_selector" + elem "output_selector" type = MAIN - pos = 291,0 - size = 640x20 + pos = 0,0 + size = 640x475 anchor1 = -1,-1 anchor2 = -1,-1 saved-params = "pos;size;is-minimized;is-maximized" is-pane = true - elem "input_buttons_child" + elem "legacy_output_selector" type = CHILD pos = 0,0 - size = 640x20 + size = 640x475 anchor1 = 0,0 anchor2 = 100,100 - background-color = #ffc41f saved-params = "splitter" - left = "inputwindow" - right = "inputbuttons" - is-vert = true + left = "output_legacy" + is-vert = false splitter = 80 show-splitter = false @@ -235,16 +256,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 @@ -256,8 +277,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 @@ -266,38 +287,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 "mebutton" + elem "whisperbutton" type = BUTTON pos = 40,0 size = 40x20 - anchor1 = 33,0 - anchor2 = 66,100 + 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 = 80,0 + size = 40x20 + 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 7d325ec04380..72b1c80de406 100644 --- a/interface/stylesheet.dm +++ b/interface/stylesheet.dm @@ -137,21 +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;} -} - -.phobia {color: #dd0000; font-weight: bold; animation: phobia 750ms infinite;} - @keyframes phobia { - 0% {color: #0d0d0d;} - 50% {color: #dd0000;} - 100% {color: #0d0d0d;} -} +.hypnophrase {color: #3bb5d3; font-weight: bold;} + +.phobia {color: #dd0000; font-weight: bold;} .icon {height: 1em; width: auto;} @@ -167,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/modular_darkpack/modules/merits_flaws/code/negative_quirks/blind.dm b/modular_darkpack/master_files/code/datums/quirks/negative_quirks/blind.dm similarity index 100% rename from modular_darkpack/modules/merits_flaws/code/negative_quirks/blind.dm rename to modular_darkpack/master_files/code/datums/quirks/negative_quirks/blind.dm diff --git a/modular_darkpack/modules/merits_flaws/code/negative_quirks/deaf.dm b/modular_darkpack/master_files/code/datums/quirks/negative_quirks/deaf.dm similarity index 100% rename from modular_darkpack/modules/merits_flaws/code/negative_quirks/deaf.dm rename to modular_darkpack/master_files/code/datums/quirks/negative_quirks/deaf.dm diff --git a/modular_darkpack/modules/merits_flaws/code/negative_quirks/illiterate.dm b/modular_darkpack/master_files/code/datums/quirks/negative_quirks/illiterate.dm similarity index 68% rename from modular_darkpack/modules/merits_flaws/code/negative_quirks/illiterate.dm rename to modular_darkpack/master_files/code/datums/quirks/negative_quirks/illiterate.dm index 5f4cd9985306..509ed80f6ce8 100644 --- a/modular_darkpack/modules/merits_flaws/code/negative_quirks/illiterate.dm +++ b/modular_darkpack/master_files/code/datums/quirks/negative_quirks/illiterate.dm @@ -1,4 +1,4 @@ /datum/quirk/illiterate - desc = "Perhaps you communicate best through illustration, dance, or impassioned speech; but you can’t read or write." + desc = "Perhaps you communicate best through illustration, dance, or impassioned speech; but you can't read or write." value = -2 darkpack_allowed = TRUE diff --git a/modular_darkpack/modules/merits_flaws/code/negative_quirks/mute.dm b/modular_darkpack/master_files/code/datums/quirks/negative_quirks/mute.dm similarity index 100% rename from modular_darkpack/modules/merits_flaws/code/negative_quirks/mute.dm rename to modular_darkpack/master_files/code/datums/quirks/negative_quirks/mute.dm diff --git a/modular_darkpack/master_files/code/modules/mob/living/living_defines.dm b/modular_darkpack/master_files/code/modules/mob/living/living_defines.dm index 79f30da41133..c4fa9ff11c8d 100644 --- a/modular_darkpack/master_files/code/modules/mob/living/living_defines.dm +++ b/modular_darkpack/master_files/code/modules/mob/living/living_defines.dm @@ -31,6 +31,7 @@ /// Multiplier for how efficently bloodpool is spent for BLOODPOWER SPECIFICLY var/blood_efficiency = 1 var/thaum_damage_plus = 0 + // DARKPACK TODO - FRENZY - (This never did FUCK anything.) var/frenzy_chance_boost = 10 var/resistant_to_disciplines = FALSE diff --git a/modular_darkpack/master_files/icons/obj/machines/smartfridge.dmi b/modular_darkpack/master_files/icons/obj/machines/smartfridge.dmi new file mode 100644 index 000000000000..6688e5f9ff05 Binary files /dev/null and b/modular_darkpack/master_files/icons/obj/machines/smartfridge.dmi differ diff --git a/modular_darkpack/modules/aggravated_damage/code/generic_healing.dm b/modular_darkpack/modules/aggravated_damage/code/generic_healing.dm index 938dd1c8db78..74e65aac5e2b 100644 --- a/modular_darkpack/modules/aggravated_damage/code/generic_healing.dm +++ b/modular_darkpack/modules/aggravated_damage/code/generic_healing.dm @@ -8,7 +8,7 @@ var/healed_dots = 0 if(heal_blood) - adjust_blood_volume(dots_to_heal * 2) + adjust_blood_volume(dots_to_heal * 2, maximum = BLOOD_VOLUME_NORMAL) if(heal_scars && dots_to_heal > 0) healed_dots += heal_storyteller_scars(dots_to_heal) diff --git a/modular_darkpack/modules/areas/code/__vtm.dm b/modular_darkpack/modules/areas/code/__vtm.dm index 6988767d90d3..26706fa23215 100644 --- a/modular_darkpack/modules/areas/code/__vtm.dm +++ b/modular_darkpack/modules/areas/code/__vtm.dm @@ -14,11 +14,6 @@ // is this able to be classified as a domain? e.g, territorial flaw, later political implementation var/domain = FALSE -/area/vtm/powered(chan) - if (!requires_power) - return TRUE - return FALSE - /area/vtm/proc/break_elysium() if (zone_type != ZONE_MASQUERADE) return diff --git a/modular_darkpack/modules/areas/code/outsides/__outside.dm b/modular_darkpack/modules/areas/code/outsides/__outside.dm index bda55e51622e..5ffbf9b72a2a 100644 --- a/modular_darkpack/modules/areas/code/outsides/__outside.dm +++ b/modular_darkpack/modules/areas/code/outsides/__outside.dm @@ -2,4 +2,3 @@ /area/vtm/outside outdoors = TRUE sound_environment = SOUND_ENVIRONMENT_CITY - requires_power = FALSE // set false in subtypes -- most outside areas require power and have lampposts and such in big cities // APOC EDIT CHANGE - (Temp) diff --git a/modular_darkpack/modules/books/code/books.dm b/modular_darkpack/modules/books/code/books.dm index 2936ddb2f9c1..96153c2e5405 100644 --- a/modular_darkpack/modules/books/code/books.dm +++ b/modular_darkpack/modules/books/code/books.dm @@ -42,3 +42,12 @@ /obj/item/vampirebook/quran/read_book(mob/living/carbon/human/user) quote = pick(GLOB.quran_quotes) + +/obj/item/vampirebook/bible + name = "Bible" + icon_state = "bible" + +// note to self - fucking move this to the parent type +/obj/item/vampirebook/bible/read_book(mob/living/carbon/human/user) + . = ..() + quote = pick(GLOB.bible_quotes) diff --git a/modular_darkpack/modules/cars/code/car.dm b/modular_darkpack/modules/cars/code/car.dm index f5a83940f720..53d9d4be11a7 100644 --- a/modular_darkpack/modules/cars/code/car.dm +++ b/modular_darkpack/modules/cars/code/car.dm @@ -476,20 +476,20 @@ if(istype(bumped_atom, /mob/living)) var/mob/living/hit_mob = bumped_atom switch(hit_mob.mob_size) - if(MOB_SIZE_HUGE) //gangrel warforms, werewolves, bears, ppl with fortitude + if(MOB_SIZE_HUGE) // zulo form playsound(src, 'modular_darkpack/modules/cars/sounds/bump.ogg', 75, TRUE) speed_in_pixels = 0 COOLDOWN_START(src, impact_delay, 2 SECONDS) hit_mob.Paralyze(1 SECONDS) - if(MOB_SIZE_LARGE) //ppl with fat bodytype + if(MOB_SIZE_LARGE) // gangrel warforms, werewolves, bears playsound(src, 'modular_darkpack/modules/cars/sounds/bump.ogg', 60, TRUE) speed_in_pixels = round(speed_in_pixels * 0.35) hit_mob.Knockdown(1 SECONDS) - if(MOB_SIZE_SMALL) //small animals + if(MOB_SIZE_SMALL) //small animals playsound(src, 'modular_darkpack/modules/cars/sounds/bump.ogg', 40, TRUE) speed_in_pixels = round(speed_in_pixels * 0.75) hit_mob.Knockdown(1 SECONDS) - else //everything else + else //everything else playsound(src, 'modular_darkpack/modules/cars/sounds/bump.ogg', 50, TRUE) speed_in_pixels = round(speed_in_pixels * 0.5) hit_mob.Knockdown(1 SECONDS) diff --git a/modular_darkpack/modules/cars/code/subtypes.dm b/modular_darkpack/modules/cars/code/subtypes.dm index 4bd94b6a4c7e..5aaf4f3807ae 100644 --- a/modular_darkpack/modules/cars/code/subtypes.dm +++ b/modular_darkpack/modules/cars/code/subtypes.dm @@ -92,8 +92,8 @@ /obj/darkpack_car/police/unmarked icon_state = "unmarked" -/obj/darkpack_car/police/process() - // If the light is not on, OR if we only have 1 light color, there is 0 reason to swap between light states +/obj/darkpack_car/police/process(seconds_per_tick) + // If the light is not on, OR if we only have 1 light color, there is 0 reason to swap between light states if(!light_on || (primary_light_color == secondary_light_color)) return ..() if(!COOLDOWN_FINISHED(src, last_color_change)) diff --git a/modular_darkpack/modules/city_time/code/city_time_subsystem.dm b/modular_darkpack/modules/city_time/code/city_time_subsystem.dm index 6af4924b5855..53dda83bd15b 100644 --- a/modular_darkpack/modules/city_time/code/city_time_subsystem.dm +++ b/modular_darkpack/modules/city_time/code/city_time_subsystem.dm @@ -1,6 +1,3 @@ -/proc/station_time_passed(display_only = FALSE, wtime=world.time) - return ((((wtime - SSticker.round_start_time) * SSticker.station_time_rate_multiplier)) % 864000) - (display_only? GLOB.timezoneOffset : 0) - SUBSYSTEM_DEF(city_time) name = "City Time" wait = 5 SECONDS @@ -27,25 +24,25 @@ SUBSYSTEM_DEF(city_time) return SS_INIT_SUCCESS /datum/controller/subsystem/city_time/fire() - if(station_time_passed() > time_till_daytime - 30 MINUTES && !first_warning && !shifting_colors) + if(city_time_passed() > time_till_daytime - 30 MINUTES && !first_warning && !shifting_colors) first_warning = TRUE shifting_colors = TRUE transition_light("#584d88") to_chat(world, span_ghostalert("The night is ending...")) - if(station_time_passed() > time_till_daytime - 15 MINUTES && !second_warning && !shifting_colors) + if(city_time_passed() > time_till_daytime - 15 MINUTES && !second_warning && !shifting_colors) second_warning = TRUE shifting_colors = TRUE transition_light("#dd80b0") to_chat(world, span_ghostalert("First rays of the sun illuminate the sky...")) - if(station_time_passed() > time_till_daytime && !daytime_started && !shifting_colors) + if(city_time_passed() > time_till_daytime && !daytime_started && !shifting_colors) daytime_started = TRUE shifting_colors = TRUE transition_light("#faeacb", 1, 0.75) to_chat(world, span_ghostalert("THE NIGHT IS OVER.")) - if(station_time_passed() > time_till_roundend && !roundend_started) + if(city_time_passed() > time_till_roundend && !roundend_started) roundend_started = TRUE if(daytime_started) @@ -54,8 +51,8 @@ SUBSYSTEM_DEF(city_time) H.apply_status_effect(/datum/status_effect/sunlight_burning) /datum/controller/subsystem/city_time/proc/extend_round(amount) - time_till_daytime += amount * SSticker.station_time_rate_multiplier - time_till_roundend += amount * SSticker.station_time_rate_multiplier + time_till_daytime += amount * SSticker.city_time_rate_multiplier + time_till_roundend += amount * SSticker.city_time_rate_multiplier log_admin("the round was extended to [SScity_time.time_till_roundend]/[DisplayTimeText(SScity_time.time_till_roundend)].") message_admins("the round was extended to [SScity_time.time_till_roundend]/[DisplayTimeText(SScity_time.time_till_roundend)].") diff --git a/modular_darkpack/modules/city_time/code/clock_structure.dm b/modular_darkpack/modules/city_time/code/clock_structure.dm index 7e7ca53350fc..cb23bb46d4b4 100644 --- a/modular_darkpack/modules/city_time/code/clock_structure.dm +++ b/modular_darkpack/modules/city_time/code/clock_structure.dm @@ -8,7 +8,7 @@ /obj/structure/coclock/examine(mob/user) . = ..() - . += "The clock reads: [station_time_timestamp()]" + . += "[src] reads: [server_timestamp("hh:mm:ss", ic_time = TRUE, twelve_hour_clock = user.client?.prefs.read_preference(/datum/preference/toggle/twelve_hour))]" /obj/structure/coclock/grandpa icon = 'modular_darkpack/modules/city_time/icons/grandpa_cock.dmi' diff --git a/modular_darkpack/modules/city_time/code/helpers.dm b/modular_darkpack/modules/city_time/code/helpers.dm new file mode 100644 index 000000000000..23b84dc31296 --- /dev/null +++ b/modular_darkpack/modules/city_time/code/helpers.dm @@ -0,0 +1,12 @@ +///returns the current IC station time in a world.time format +/proc/city_time(wtime = world.time) + return (((wtime - SSticker.round_start_time) * SSticker.city_time_rate_multiplier) + SSticker.gametime_offset) % (24 HOURS) + +/* // use server_timestamp(ic_time = TRUE) +///returns the current IC station time in a human readable format +/proc/city_time_timestamp(format = "hh:mm:ss", wtime) + return time2text(city_time(wtime), format, NO_TIMEZONE) +*/ + +/proc/city_time_passed(display_only = FALSE, wtime=world.time) + return ((((wtime - SSticker.round_start_time) * SSticker.city_time_rate_multiplier)) % 864000) - (display_only? GLOB.timezoneOffset : 0) diff --git a/modular_darkpack/modules/city_time/code/time_configs.dm b/modular_darkpack/modules/city_time/code/time_configs.dm new file mode 100644 index 000000000000..2f16ce46a7df --- /dev/null +++ b/modular_darkpack/modules/city_time/code/time_configs.dm @@ -0,0 +1,17 @@ +/// The difference betwen midnight (of the host computer) and 0 world.ticks. +GLOBAL_VAR_INIT(timezoneOffset, 0) + +/datum/config_entry/number/shift_time_start_hour + default = 12 + min_val = 0 + max_val = 23 + +// In deciseconds and using city_time_rate_multiplier +/datum/config_entry/number/time_till_day + default = 198000 + protection = CONFIG_ENTRY_LOCKED + +// In deciseconds and using city_time_rate_multiplier +/datum/config_entry/number/time_till_roundend + default = 216000 + protection = CONFIG_ENTRY_LOCKED diff --git a/modular_darkpack/modules/city_time/code/wrist_watch.dm b/modular_darkpack/modules/city_time/code/wrist_watch.dm index 0af823222149..6a29f65b656b 100644 --- a/modular_darkpack/modules/city_time/code/wrist_watch.dm +++ b/modular_darkpack/modules/city_time/code/wrist_watch.dm @@ -14,5 +14,5 @@ /obj/item/watch/examine(mob/user) . = ..() - . += "The watch reads: [station_time_timestamp("hh:mm:ss, MMM DD")]" - . += "That should make it [station_time_timestamp("Day")]" + . += "[src]: [server_timestamp("hh:mm:ss", ic_time = TRUE, twelve_hour_clock = user.client?.prefs.read_preference(/datum/preference/toggle/twelve_hour))], [server_timestamp("MMM DD", ic_time = TRUE)]" + . += "That should make it [server_timestamp("Day", ic_time = TRUE)]" diff --git a/modular_darkpack/modules/city_traits/code/negative_traits.dm b/modular_darkpack/modules/city_traits/code/negative_traits.dm index 1f0ff9742bd6..ba2b4f7305b8 100644 --- a/modular_darkpack/modules/city_traits/code/negative_traits.dm +++ b/modular_darkpack/modules/city_traits/code/negative_traits.dm @@ -39,10 +39,7 @@ /datum/station_trait/faulty_power_grid/on_round_start() . = ..() - // Fuck I hate it, rework fusebox code - for(var/obj/fusebox/broken_box in world) + for(var/obj/fusebox/F in GLOB.fuseboxes) if(prob(75)) continue - broken_box.damaged += rand(50, 200) - broken_box.check_damage() - + F.take_damage(rand(50,200)) diff --git a/modular_darkpack/modules/computers/code/app_types.dm b/modular_darkpack/modules/computers/code/app_types.dm index fe69ff27d236..2a23eb97e2f0 100644 --- a/modular_darkpack/modules/computers/code/app_types.dm +++ b/modular_darkpack/modules/computers/code/app_types.dm @@ -108,7 +108,7 @@ sender = param_sender subject = param_subject message = param_message - date = station_time_timestamp("hh:mm") + date = server_timestamp("hh:mm", ic_time = TRUE) /datum/email/proc/to_data() var/list/data = list("subject"=subject, "sender" = sender, "message" = message, "date" = date, "checked" = checked, "stared" = stared) diff --git a/modular_darkpack/modules/decor/code/decor.dm b/modular_darkpack/modules/decor/code/decor.dm index beb70c0ac67d..9a8e432409dd 100644 --- a/modular_darkpack/modules/decor/code/decor.dm +++ b/modular_darkpack/modules/decor/code/decor.dm @@ -52,10 +52,11 @@ if(check_holidays(FESTIVE_SEASON)) if(istype(my_area) && my_area.outdoors) icon_state = "[initial(icon_state)]-snow" - if(my_area.requires_power) - RegisterSignal(my_area, COMSIG_AREA_POWER_CHANGE, PROC_REF(on_power_change)) - if(my_area.powered()) - create_lights() + RegisterSignal(my_area, COMSIG_AREA_POWER_CHANGE, PROC_REF(on_power_change)) + // DARKPACK TODO - fuseboxes and areas aren't meaningfully connected to each other, and thusly aren't meaningfully connected to lights/devices that may need poer. + // TLDR we need to basically re-evaluate how we approach power... the current system is flavcode spaghetti shit. + if(my_area.powered(AREA_USAGE_LIGHT)) + create_lights() /obj/structure/lamppost/proc/on_power_change(area/A) SIGNAL_HANDLER diff --git a/modular_darkpack/modules/decor/code/stick.dm b/modular_darkpack/modules/decor/code/stick.dm index 1d8ae1f18702..7368c5e0e7c4 100644 --- a/modular_darkpack/modules/decor/code/stick.dm +++ b/modular_darkpack/modules/decor/code/stick.dm @@ -45,6 +45,8 @@ if(stepper.mob_size >= MOB_SIZE_HUMAN) var/datum/storyteller_roll/step_roll = new() step_roll.applicable_stats = list(STAT_PERCEPTION, STAT_STEALTH) + step_roll.roll_output_type = ROLL_PRIVATE + step_roll.spammy_roll = TRUE var/roll_result = step_roll.st_roll(triggerer, src) if(roll_result != ROLL_SUCCESS) mineEffect(triggerer) diff --git a/modular_darkpack/modules/doors/code/vampdoor.dm b/modular_darkpack/modules/doors/code/vampdoor.dm index 6ea11036e7a5..1158f4192fdd 100644 --- a/modular_darkpack/modules/doors/code/vampdoor.dm +++ b/modular_darkpack/modules/doors/code/vampdoor.dm @@ -112,14 +112,15 @@ /obj/structure/vampdoor/atom_break(damage_flag) . = ..() - if(!door_broken) - break_door() + break_door() /obj/structure/vampdoor/atom_fix() . = ..() fix_door() /obj/structure/vampdoor/proc/break_door(mob/user) + if(door_broken) + return FALSE playsound(get_turf(src), 'modular_darkpack/master_files/sounds/effects/door/get_bent.ogg', 100, FALSE) var/obj/item/shield/door/broken_door = new(get_turf(src)) broken_door.icon_state = base_icon_state @@ -136,6 +137,7 @@ locked = FALSE icon_state = "[base_icon_state]-b" update_icon() + return TRUE /obj/structure/vampdoor/proc/fix_door() name = initial(name) @@ -194,10 +196,10 @@ . = ..() if(.) return - var/mob/living/living_user = user if(door_broken) to_chat(user, span_warning("There is no door to use here.")) return + var/mob/living/living_user = user if(living_user.combat_mode) pixel_z = pixel_z+rand(-1, 1) pixel_w = pixel_w+rand(-1, 1) @@ -214,6 +216,9 @@ . = ..() if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) return + if(door_broken) + to_chat(user, span_warning("There is no door to use here.")) + return var/mob/living/living_user = user if(living_user.combat_mode) if(ishuman(user)) diff --git a/modular_darkpack/modules/drugs/code/weed/fake_steam.dm b/modular_darkpack/modules/drugs/code/weed/fake_steam.dm index 561d5a545fdd..87ef36ba0789 100644 --- a/modular_darkpack/modules/drugs/code/weed/fake_steam.dm +++ b/modular_darkpack/modules/drugs/code/weed/fake_steam.dm @@ -21,7 +21,7 @@ STOP_PROCESSING(SSobj, src) return ..() -/obj/effect/abstract/fake_steam/process() +/obj/effect/abstract/fake_steam/process(seconds_per_tick) if(next_stage_down > world.time) return stage_down() diff --git a/modular_darkpack/modules/electricity/code/fusebox.dm b/modular_darkpack/modules/electricity/code/fusebox.dm index a0bbd69e9226..eba8178d52c5 100644 --- a/modular_darkpack/modules/electricity/code/fusebox.dm +++ b/modular_darkpack/modules/electricity/code/fusebox.dm @@ -1,3 +1,5 @@ +GLOBAL_LIST_EMPTY(fuseboxes) + // The way this completely bypasses the entire power system is so strange /obj/fusebox name = "fuse box" @@ -7,50 +9,68 @@ base_icon_state = "fusebox" layer = SIGN_LAYER anchored = TRUE - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF + resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF pixel_y = 32 - + max_integrity = 100 + prevent_destruction = TRUE //Damage on the fusebox var/damaged = 0 - //If our door is open/closed. bool - var/open = FALSE //Repairing var for the loop var/repairing = FALSE //Soundloop for Transformers var/datum/looping_sound/generator/soundloop +/obj/fusebox/Initialize(mapload) + . = ..() + GLOB.fuseboxes += src + +/obj/fusebox/atom_destruction(damage_flag) + . = ..() + power_off() + + +//they shouldnt really ever be destroyed, but... +/obj/fusebox/Destroy() + GLOB.fuseboxes -= src + return ..() + /obj/fusebox/update_icon_state() . = ..() - if(damaged > 100) + if(atom_integrity <= 0) icon_state = "[base_icon_state]_off" else icon_state = base_icon_state /obj/fusebox/proc/update_sound_state() if(!isnull(soundloop)) - if(damaged > 100) + if(atom_integrity <= 0) soundloop.stop() else soundloop.start(src) -/obj/fusebox/proc/check_damage(mob/living/user) - if(damaged > 100 && !open) - open = TRUE - var/area/power_area = get_area(src) - power_area.power_light = FALSE - power_area.power_equip = FALSE - power_area.power_environ = FALSE - power_area.power_change() - power_area.fire_controled = FALSE - var/datum/effect_system/basic/spark_spread/local_spark = new(get_turf(src), 5, 1) - local_spark.start() - for(var/obj/machinery/light/L in power_area) - L.update(FALSE) - playsound(loc, 'modular_darkpack/modules/electricity/sounds/generator_break.ogg', 100, TRUE) - user?.electrocute_act(50, src, siemens_coeff = 1, flags = NONE) +/obj/fusebox/proc/power_off() + var/area/power_area = get_area(src) + power_area.power_light = FALSE + power_area.power_equip = FALSE + power_area.power_environ = FALSE + power_area.power_change() + power_area.fire_controled = FALSE + var/datum/effect_system/basic/spark_spread/local_spark = new(get_turf(src), 5, 1) + local_spark.start() + for(var/obj/machinery/light/L in power_area) + L.update(FALSE) + playsound(loc, 'modular_darkpack/modules/electricity/sounds/generator_break.ogg', 100, TRUE) + for(var/mob/living/M in range(1, src)) + M.electrocute_act(50, src, siemens_coeff = 1, flags = NONE) update_icon() update_sound_state() +/datum/storyteller_roll/fusebox_repair + bumper_text = "electrical repair" + applicable_stats = list(STAT_INTELLIGENCE, STAT_TECHNOLOGY) + difficulty = 7 + numerical = TRUE + /obj/fusebox/item_interaction(mob/living/user, obj/item/tool, list/modifiers) if(tool.tool_behaviour == TOOL_WIRECUTTER) if(!repairing) @@ -59,32 +79,31 @@ repairing = FALSE return ITEM_INTERACT_BLOCKING - damaged = 0 - update_icon_state() - update_sound_state() - playsound(get_turf(src),'modular_darkpack/modules/electricity/sounds/fusebox_fix.ogg', 50, FALSE) - var/area/power_area = get_area(src) - power_area.power_light = TRUE - power_area.power_equip = TRUE - power_area.power_environ = TRUE - power_area.power_change() - if(initial(power_area.fire_controled)) - power_area.fire_controled = TRUE - for(var/obj/machinery/light/L in power_area) - L.update(FALSE) - - repairing = FALSE - return ITEM_INTERACT_SUCCESS + var/datum/storyteller_roll/fusebox_repair/fusebox_roll = new() + var/successes = fusebox_roll.st_roll(user, src) + var/repair_amount = successes * 40 + if(repair_amount > 0) + repair_damage(repair_amount) + update_icon_state() + update_sound_state() + playsound(get_turf(src), 'modular_darkpack/modules/electricity/sounds/fusebox_fix.ogg', 50, FALSE) + var/area/power_area = get_area(src) + power_area.power_light = TRUE + power_area.power_equip = TRUE + power_area.power_environ = TRUE + power_area.power_change() + if(initial(power_area.fire_controled)) + power_area.fire_controled = TRUE + for(var/obj/machinery/light/L in power_area) + L.update(FALSE) + repairing = FALSE + return ITEM_INTERACT_SUCCESS + if(repair_amount <= 0) + user.electrocute_act(50, src, siemens_coeff = 1, flags = NONE) + repairing = FALSE return NONE -// This sucks. Snowflaking its own integrity system is always bad. -/obj/fusebox/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers) - . = ..() - if(attacking_item.force) - damaged += attacking_item.force - check_damage(user) - // transformers (another type of fusebox) /obj/fusebox/transformer name = "transformer" @@ -96,4 +115,3 @@ /obj/fusebox/transformer/Initialize(mapload) . = ..() soundloop = new(src, TRUE) - diff --git a/modular_darkpack/modules/events/attributions.txt b/modular_darkpack/modules/events/attributions.txt new file mode 100644 index 000000000000..9184d81866e8 --- /dev/null +++ b/modular_darkpack/modules/events/attributions.txt @@ -0,0 +1,2 @@ +thank you to yfjesse on freesound.org for news_notification.ogg +https://freesound.org/people/yfjesse/sounds/235911/ diff --git a/modular_darkpack/modules/events/code/_darkpack_event.dm b/modular_darkpack/modules/events/code/_darkpack_event.dm new file mode 100644 index 000000000000..7e354a05fced --- /dev/null +++ b/modular_darkpack/modules/events/code/_darkpack_event.dm @@ -0,0 +1,4 @@ +/datum/round_event_control/darkpack + darkpack_allowed = TRUE + +// note - no need for a /datum/round_event/darkpack subtype. they only fire if the above exists. diff --git a/modular_darkpack/modules/events/code/blackout_event.dm b/modular_darkpack/modules/events/code/blackout_event.dm new file mode 100644 index 000000000000..ab7036ba74d3 --- /dev/null +++ b/modular_darkpack/modules/events/code/blackout_event.dm @@ -0,0 +1,30 @@ +/datum/round_event_control/darkpack/blackout + name = "Blackout" + typepath = /datum/round_event/blackout + weight = 6 + min_players = 5 + max_occurrences = 2 + earliest_start = 10 MINUTES + category = EVENT_CATEGORY_ENGINEERING + description = "A cascading failure in the city's power grid." + darkpack_allowed = TRUE + +/datum/round_event/blackout + start_when = 1 + announce_when = 5 + +/datum/round_event/blackout/announce(fake) + priority_announce( + "A breaking news notification has appeared on your phone - rolling blackouts are affecting your area due to inclement weather.", + "Local BREAKING NEWS Alert", + 'modular_darkpack/modules/events/sounds/news_notification.ogg', + ANNOUNCEMENT_TYPE_PRIORITY, + color_override = "red", + ) + +/datum/round_event/blackout/start() + for(var/obj/fusebox/F in GLOB.fuseboxes) + if(prob(50)) + continue + F.take_damage(101) + F.power_off() diff --git a/modular_darkpack/modules/events/sounds/news_notification.ogg b/modular_darkpack/modules/events/sounds/news_notification.ogg new file mode 100644 index 000000000000..571fecf098e1 Binary files /dev/null and b/modular_darkpack/modules/events/sounds/news_notification.ogg differ diff --git a/modular_darkpack/modules/flavor_text/code/examine.dm b/modular_darkpack/modules/flavor_text/code/examine.dm index 8cbcbb9ee47d..b4177352fb43 100644 --- a/modular_darkpack/modules/flavor_text/code/examine.dm +++ b/modular_darkpack/modules/flavor_text/code/examine.dm @@ -36,10 +36,17 @@ var/mob/living/carbon/human/holder_human = holder obscured = holder_human.obscured_slots & HIDEFACE + var/main_flavor_text_key = EXAMINE_DNA_FLAVOR_TEXT + + if(iscrinos(holder)) + main_flavor_text_key = EXAMINE_DNA_WAR_FORM_FLAVOR_TEXT + else if(ishispo(holder) || islupus(holder)) + main_flavor_text_key = EXAMINE_DNA_FERAL_FORM_FLAVOR_TEXT + //Check if the mob is obscured, then continue to headshot if(isobserver(user) || show_flavor_text_when_masked || !obscured) headshot = holder_human.dna.features[EXAMINE_DNA_HEADSHOT] - flavor_text = holder_human.dna.features[EXAMINE_DNA_FLAVOR_TEXT] + flavor_text = holder_human.dna.features[main_flavor_text_key] flavor_text_nsfw = holder.dna.features[EXAMINE_DNA_NSFW_FLAVOR_TEXT] ooc_notes = holder.dna.features[EXAMINE_DNA_OOC_NOTES] character_notes = holder.dna.features[EXAMINE_DNA_CHARACTER_NOTES] @@ -63,7 +70,14 @@ /mob/living/carbon/proc/flavor_text_creation() var/flavor_text_to_show - var/preview_text = copytext_char(dna.features[EXAMINE_DNA_FLAVOR_TEXT], 1, FLAVOR_PREVIEW_LIMIT) + + var/main_flavor_text_key = EXAMINE_DNA_FLAVOR_TEXT + if(iscrinos(src)) + main_flavor_text_key = EXAMINE_DNA_WAR_FORM_FLAVOR_TEXT + else if(ishispo(src) || islupus(src)) + main_flavor_text_key = EXAMINE_DNA_FERAL_FORM_FLAVOR_TEXT + + var/preview_text = copytext_char(dna.features[main_flavor_text_key], 1, FLAVOR_PREVIEW_LIMIT) // What examine_tgui.dm uses to determine if flavor text appears as "Obscured". var/face_obscured = obscured_slots & HIDEFACE if(!face_obscured || (face_obscured && client?.prefs.read_preference(/datum/preference/toggle/show_flavor_text_when_masked))) diff --git a/modular_darkpack/modules/flavor_text/code/preferences.dm b/modular_darkpack/modules/flavor_text/code/preferences.dm index e3e5773da942..af433a1c6259 100644 --- a/modular_darkpack/modules/flavor_text/code/preferences.dm +++ b/modular_darkpack/modules/flavor_text/code/preferences.dm @@ -69,6 +69,32 @@ /datum/preference/text/flavor_text/apply_to_human(mob/living/carbon/human/target, value) target.dna.features[EXAMINE_DNA_FLAVOR_TEXT] = value + +/datum/preference/text/war_form_flavor_text + category = PREFERENCE_CATEGORY_NON_CONTEXTUAL + priority = PREFERENCE_PRIORITY_BODYPARTS + savefile_identifier = PREFERENCE_CHARACTER + savefile_key = "war_form_flavor_text" + maximum_value_length = MAX_FLAVOR_LEN + relevant_inherent_trait = TRAIT_FERA_FORMS + must_have_relevant_trait = TRUE + +/datum/preference/text/war_form_flavor_text/apply_to_human(mob/living/carbon/human/target, value) + target.dna.features[EXAMINE_DNA_WAR_FORM_FLAVOR_TEXT] = value + + +/datum/preference/text/feral_form_flavor_text + category = PREFERENCE_CATEGORY_NON_CONTEXTUAL + priority = PREFERENCE_PRIORITY_BODYPARTS + savefile_identifier = PREFERENCE_CHARACTER + savefile_key = "feral_form_flavor_text" + maximum_value_length = MAX_FLAVOR_LEN + relevant_inherent_trait = TRAIT_FERA_FORMS + must_have_relevant_trait = TRUE + +/datum/preference/text/feral_form_flavor_text/apply_to_human(mob/living/carbon/human/target, value) + target.dna.features[EXAMINE_DNA_FERAL_FORM_FLAVOR_TEXT] = value + /////////////////////////////////////////////////////////////////////////// /datum/preference/text/nsfw_flavor_text diff --git a/modular_darkpack/modules/forensics/code/forensic_gatherer.dm b/modular_darkpack/modules/forensics/code/forensic_gatherer.dm index 3db4826a7e43..2c8008c6c145 100644 --- a/modular_darkpack/modules/forensics/code/forensic_gatherer.dm +++ b/modular_darkpack/modules/forensics/code/forensic_gatherer.dm @@ -53,7 +53,7 @@ // Start gathering log_entry.scan_target = scanned_atom.name - log_entry.scan_time = station_time_timestamp() + log_entry.scan_time = server_timestamp(ic_time = TRUE) var/list/atom_fibers = GET_ATOM_FIBRES(scanned_atom) if(length(atom_fibers)) diff --git a/modular_darkpack/modules/jobs/code/_departments.dm b/modular_darkpack/modules/jobs/code/_departments.dm index bc42706a0805..323beef07c9e 100644 --- a/modular_darkpack/modules/jobs/code/_departments.dm +++ b/modular_darkpack/modules/jobs/code/_departments.dm @@ -129,3 +129,12 @@ display_order = 1 label_class = "pentex" ui_color = COLOR_CORP_ENDRON + +/datum/job_department/society_of_leopold + department_name = DEPARTMENT_SOCIETY_OF_LEOPOLD + department_bitflags = DEPARTMENT_BITFLAG_SOCIETY_OF_LEOPOLD + department_head = /datum/job/vampire/abbe + department_experience_type = EXP_TYPE_CHURCH + display_order = 1 + label_class = "society" + ui_color = "#fff022" diff --git a/modular_darkpack/modules/jobs/code/_job_assignment.dm b/modular_darkpack/modules/jobs/code/_job_assignment.dm index 2be9f5d08170..d73b23cacffc 100644 --- a/modular_darkpack/modules/jobs/code/_job_assignment.dm +++ b/modular_darkpack/modules/jobs/code/_job_assignment.dm @@ -52,8 +52,12 @@ /datum/controller/subsystem/job/proc/check_kindred_prefs(client/player_client, mob/dead/new_player/player, datum/job/possible_job, debug_prefix = "", add_job_to_log = FALSE) if((player_client.prefs.read_preference(/datum/preference/numeric/immortal_age) < possible_job.minimum_immortal_age)) - job_debug("[debug_prefix] Error: [get_job_unavailable_error_message(JOB_UNAVAILABLE_KINDRED_AGE, possible_job.title)], Player: [player][add_job_to_log ? ", Job: [possible_job]" : ""]") - return JOB_UNAVAILABLE_KINDRED_AGE + job_debug("[debug_prefix] Error: [get_job_unavailable_error_message(JOB_UNAVAILABLE_KINDRED_AGE_MIN, possible_job.title)], Player: [player][add_job_to_log ? ", Job: [possible_job]" : ""]") + return JOB_UNAVAILABLE_KINDRED_AGE_MIN + + if((!isnull(possible_job.maximum_immortal_age) && (player_client.prefs.read_preference(/datum/preference/numeric/immortal_age) > possible_job.maximum_immortal_age))) + job_debug("[debug_prefix] Error: [get_job_unavailable_error_message(JOB_UNAVAILABLE_KINDRED_AGE_MAX, possible_job.title)], Player: [player][add_job_to_log ? ", Job: [possible_job]" : ""]") + return JOB_UNAVAILABLE_KINDRED_AGE_MAX if((player_client.prefs.read_preference(/datum/preference/numeric/generation) > possible_job.minimal_generation)) job_debug("[debug_prefix] Error: [get_job_unavailable_error_message(JOB_UNAVAILABLE_KINDRED_GENERATION, possible_job.title)], Player: [player][add_job_to_log ? ", Job: [possible_job]" : ""]") diff --git a/modular_darkpack/modules/jobs/code/_jobs.dm b/modular_darkpack/modules/jobs/code/_jobs.dm index a27318d451d6..0ef1d9bb4443 100644 --- a/modular_darkpack/modules/jobs/code/_jobs.dm +++ b/modular_darkpack/modules/jobs/code/_jobs.dm @@ -15,6 +15,8 @@ var/minimal_masquerade = 0 /// Character must be at least this age (in years) since embrace (chronological_age - age) to join as role. var/minimum_immortal_age = 0 + /// Character must not be over this age (in years) since embrace (chronological_age - age) to join as role. (Defaults null, set to desired age.) + var/maximum_immortal_age = null ///List of Clans that are allowed to do this job. var/list/allowed_clans ///List of Clans that are disallowed to do this job. diff --git a/modular_darkpack/modules/jobs/code/hunters/abbe.dm b/modular_darkpack/modules/jobs/code/hunters/abbe.dm new file mode 100644 index 000000000000..52ee3a11bd5b --- /dev/null +++ b/modular_darkpack/modules/jobs/code/hunters/abbe.dm @@ -0,0 +1,33 @@ +/datum/job/vampire/abbe + title = JOB_ABBE + description = "You are an Abbé for the Society of Leopold who answers to the Provincial of this region, and who serves the local Cenacle of Inquisitors beneath you. You're tasked by the Inquisition in ensuring the Cenaculum are well-supplied and accounted for, as well as rooting out any heresy or infiltration. Act as the leaders of the Inquisitors, as your Lord has commanded you to be your brother's keeper." + auto_deadmin_role_flags = DEADMIN_POSITION_SECURITY + faction = FACTION_CITY + total_positions = 1 + spawn_positions = 1 + supervisors = SUPERVISOR_SOCIETY_OF_LEOPOLD + minimal_player_age = 7 + config_tag = "ABBE" + job_flags = CITY_JOB_FLAGS + outfit = /datum/outfit/job/vampire/abbe + + display_order = JOB_DISPLAY_ORDER_ABBE + department_for_prefs = /datum/job_department/society_of_leopold + departments_list = list( + /datum/job_department/society_of_leopold, + ) + allowed_splats = list(SPLAT_NONE) + +/datum/outfit/job/vampire/abbe + name = "Abbe" + jobtype = /datum/job/vampire/abbe + + id = /obj/item/card/hunter + uniform = /obj/item/clothing/under/vampire/suit + gloves = /obj/item/clothing/gloves/vampire/work + suit = /obj/item/clothing/suit/vampire/orthodox + shoes = /obj/item/clothing/shoes/vampire + glasses = /obj/item/clothing/glasses/vampire/perception + r_pocket = /obj/item/vamp/keys/hunter + l_pocket = /obj/item/smartphone/abbe + backpack_contents = list(/obj/item/vampire_stake=1, /obj/item/vampirebook/bible=1, /obj/item/card/credit=1) diff --git a/modular_darkpack/modules/jobs/code/hunters/condottieri.dm b/modular_darkpack/modules/jobs/code/hunters/condottieri.dm new file mode 100644 index 000000000000..5bafb5d99c3c --- /dev/null +++ b/modular_darkpack/modules/jobs/code/hunters/condottieri.dm @@ -0,0 +1,36 @@ +/datum/job/vampire/condottieri + title = JOB_CONDOTTIERI + description = "You are a Condottieri for the Society of Leopold - assigned to this Cenacle to protect the Inquisitors and the Novices undergoing their Novitiate. Your role is closer to defense than it is the actual completion of offensive missions undertaken by the other Inquisitors - however, the Condottieri remain highly respected as an elite and deadly subdivision of the Society of Leopold." + auto_deadmin_role_flags = DEADMIN_POSITION_SECURITY + faction = FACTION_CITY + total_positions = 2 + spawn_positions = 2 + supervisors = SUPERVISOR_SHERIFF + minimal_player_age = 7 + + config_tag = "CONDOTTIERI" + job_flags = CITY_JOB_FLAGS + outfit = /datum/outfit/job/vampire/condottieri + + display_order = JOB_DISPLAY_ORDER_CONDOTTIERI + department_for_prefs = /datum/job_department/society_of_leopold + departments_list = list( + /datum/job_department/society_of_leopold, + ) + + allowed_splats = list(SPLAT_NONE) + +/datum/outfit/job/vampire/condottieri + name = "Condottieri" + jobtype = /datum/job/vampire/condottieri + + id = /obj/item/card/hunter + uniform = /obj/item/clothing/under/vampire/black + gloves = /obj/item/clothing/gloves/vampire/leather + suit = /obj/item/clothing/suit/vampire/vest/medieval + head = /obj/item/clothing/head/vampire/helmet/spain + shoes = /obj/item/clothing/shoes/jackboots + glasses = /obj/item/clothing/glasses/vampire/sun + r_pocket = /obj/item/vamp/keys/hunter + l_pocket = /obj/item/smartphone/condottieri + backpack_contents = list(/obj/item/vampire_stake=1, /obj/item/card/credit=1, /obj/item/vampirebook/bible=1) diff --git a/modular_darkpack/modules/jobs/code/hunters/inquisitor.dm b/modular_darkpack/modules/jobs/code/hunters/inquisitor.dm new file mode 100644 index 000000000000..093d4a29182a --- /dev/null +++ b/modular_darkpack/modules/jobs/code/hunters/inquisitor.dm @@ -0,0 +1,35 @@ +/datum/job/vampire/inquisitor + title = JOB_INQUISITOR + description = "You are a seasoned member of the Society of Leopold, having passed your Novitiate and becoming a Councilor after many hard years of careful study of the supernatural. Now your task is simple - root out any emergence of the supernatural which threaten God's kingdom and it's Children - do not suffer even one to exist, for God makes it clear who these 'Kindred' or 'Garou' really serve." + auto_deadmin_role_flags = DEADMIN_POSITION_SECURITY + faction = FACTION_CITY + total_positions = 3 + spawn_positions = 3 + supervisors = SUPERVISOR_SOCIETY_OF_LEOPOLD + minimal_player_age = 7 + config_tag = "INQUISITOR" + job_flags = CITY_JOB_FLAGS + outfit = /datum/outfit/job/vampire/inquisitor + + display_order = JOB_DISPLAY_ORDER_INQUISITOR + department_for_prefs = /datum/job_department/society_of_leopold + departments_list = list( + /datum/job_department/society_of_leopold, + ) + splat_slots = list(SPLAT_GHOUL = 1, SPLAT_KINFOLK = 1, SPLAT_NONE = 3) + allowed_splats = list(SPLAT_NONE, SPLAT_GHOUL, SPLAT_KINFOLK) // infiltrators and betrayal arcs + +/datum/outfit/job/vampire/inquisitor + name = "Inquisitor" + jobtype = /datum/job/vampire/inquisitor + + id = /obj/item/card/hunter + head = /obj/item/clothing/head/vampire/cowboy + uniform = /obj/item/clothing/under/vampire/brujah + gloves = /obj/item/clothing/gloves/vampire/leather + suit = /obj/item/clothing/suit/vampire/trench/alt/armored + shoes = /obj/item/clothing/shoes/vampire/jackboots + glasses = /obj/item/clothing/glasses/vampire/sun + r_pocket = /obj/item/vamp/keys/hunter + l_pocket = /obj/item/smartphone/inquisitor + backpack_contents = list(/obj/item/vampire_stake=2, /obj/item/vampirebook/bible=1, /obj/item/masquerade_contract=1, /obj/item/card/credit=1) diff --git a/modular_darkpack/modules/jobs/code/hunters/novice.dm b/modular_darkpack/modules/jobs/code/hunters/novice.dm new file mode 100644 index 000000000000..624363a2836f --- /dev/null +++ b/modular_darkpack/modules/jobs/code/hunters/novice.dm @@ -0,0 +1,33 @@ +/datum/job/vampire/novice + title = JOB_NOVICE + description = "You are Novice who is undergoing, or a Tertiary who has just passed, their Novitiate in the Inquisition's organization The Society of Saint Leopold. Whether you were a lay-person or undergoing official clerical or religious training, your main task in the Society is now to study, scout, document, and be educated on the various supernatural creatures that threaten God's kingdom and it's balance - as well as remaining prepared for when your name is called." + faction = FACTION_CITY + total_positions = 3 + spawn_positions = 3 + supervisors = SUPERVISOR_SOCIETY_OF_LEOPOLD + minimal_player_age = 7 + + config_tag = "NOVICE" + job_flags = CITY_JOB_FLAGS + outfit = /datum/outfit/job/vampire/novice + + display_order = JOB_DISPLAY_ORDER_NOVICE + department_for_prefs = /datum/job_department/society_of_leopold + departments_list = list( + /datum/job_department/society_of_leopold, + ) + + allowed_splats = list(SPLAT_NONE) + + +/datum/outfit/job/vampire/novice + name = "Novice" + jobtype = /datum/job/vampire/novice + + id = /obj/item/card/hunter + uniform = /obj/item/clothing/under/vampire/turtleneck_white + suit = /obj/item/clothing/suit/vampire/labcoat + shoes = /obj/item/clothing/shoes/vampire/jackboots + r_pocket = /obj/item/vamp/keys/hunter + l_pocket = /obj/item/smartphone/novice + backpack_contents = list(/obj/item/camera=1, /obj/item/vampirebook/bible=1, /obj/item/card/credit=1) diff --git a/modular_darkpack/modules/jobs/code/landmarks.dm b/modular_darkpack/modules/jobs/code/landmarks.dm index 8529c79c62ae..7bb104aca0c2 100644 --- a/modular_darkpack/modules/jobs/code/landmarks.dm +++ b/modular_darkpack/modules/jobs/code/landmarks.dm @@ -140,4 +140,13 @@ JOB_START_HELPER(voivode/voivode, JOB_VOIVODE) JOB_START_HELPER(voivode/bogatyr, JOB_BOGATYR) JOB_START_HELPER(voivode/zadruga, JOB_ZADRUGA) +/* Society of Leopold */ +/obj/effect/landmark/start/darkpack/society_of_leopold + name = "generic hunter start" + +JOB_START_HELPER(society_of_leopold/abbe, JOB_ABBE) +JOB_START_HELPER(society_of_leopold/condittieri, JOB_CONDOTTIERI) +JOB_START_HELPER(society_of_leopold/inquisitor, JOB_INQUISITOR) +JOB_START_HELPER(society_of_leopold/novice, JOB_NOVICE) + #undef JOB_START_HELPER diff --git a/modular_darkpack/modules/jobs/icons/landmarks.dmi b/modular_darkpack/modules/jobs/icons/landmarks.dmi index 6ca55a600355..0b7a01cff0e1 100644 Binary files a/modular_darkpack/modules/jobs/icons/landmarks.dmi and b/modular_darkpack/modules/jobs/icons/landmarks.dmi differ diff --git a/modular_darkpack/modules/merits_flaws/code/negative_quirks/horrific_appearance_quirk.dm b/modular_darkpack/modules/merits_flaws/code/negative_quirks/horrific_appearance_quirk.dm index 44c0ac503f1e..b440d0ecbb70 100644 --- a/modular_darkpack/modules/merits_flaws/code/negative_quirks/horrific_appearance_quirk.dm +++ b/modular_darkpack/modules/merits_flaws/code/negative_quirks/horrific_appearance_quirk.dm @@ -10,15 +10,15 @@ icon = FA_ICON_SKULL failure_message = "The skin on your corpsely flesh returns to normal." -/datum/quirk/darkpack/horrific_appearance/add_to_holder(mob/living/new_holder, quirk_transfer, client/client_source, unique, announce) - . = ..() - if(ishuman(new_holder)) - var/mob/living/carbon/human/human_holder = new_holder - var/years_undead = human_holder.chronological_age - human_holder.age - switch(years_undead) - if (-INFINITY to 500) - human_holder.rot_body(3) - if (500 to INFINITY) - human_holder.rot_body(4) - if(human_holder.st_get_stat(STAT_APPEARANCE) > 0) - human_holder.st_add_stat_mod(STAT_APPEARANCE, -(STAT_APPEARANCE), "Monstrous") +/datum/quirk/darkpack/horrific_appearance/add(client/client_source) + var/mob/living/carbon/human/human_holder = astype(quirk_holder) + if(!human_holder) + return + var/years_undead = human_holder.chronological_age - human_holder.age + switch(years_undead) + if (-INFINITY to 500) + human_holder.rot_body(3) + if (500 to INFINITY) + human_holder.rot_body(4) + if(human_holder.st_get_stat(STAT_APPEARANCE) > 0) + human_holder.st_add_stat_mod(STAT_APPEARANCE, -(STAT_APPEARANCE), "Monstrous") diff --git a/modular_darkpack/modules/merits_flaws/code/negative_quirks/mage_blood.dm b/modular_darkpack/modules/merits_flaws/code/negative_quirks/mage_blood.dm index 9faffbd7d074..3a81f8eca09e 100644 --- a/modular_darkpack/modules/merits_flaws/code/negative_quirks/mage_blood.dm +++ b/modular_darkpack/modules/merits_flaws/code/negative_quirks/mage_blood.dm @@ -6,8 +6,7 @@ allowed_splats = list(SPLAT_KINDRED) included_clans = list(VAMPIRE_CLAN_TREMERE) -/datum/quirk/darkpack/mage_blood/add_to_holder(mob/living/new_holder, quirk_transfer, client/client_source, unique, announce) - . = ..() +/datum/quirk/darkpack/mage_blood/add(client/client_source) var/datum/splat/vampire/kindred/kindred_splat = get_kindred_splat(quirk_holder) if(!kindred_splat) return diff --git a/modular_darkpack/modules/merits_flaws/code/negative_quirks/monstrous_quirk.dm b/modular_darkpack/modules/merits_flaws/code/negative_quirks/monstrous_quirk.dm index b79e362e2d48..31250e037bf7 100644 --- a/modular_darkpack/modules/merits_flaws/code/negative_quirks/monstrous_quirk.dm +++ b/modular_darkpack/modules/merits_flaws/code/negative_quirks/monstrous_quirk.dm @@ -10,11 +10,11 @@ icon = FA_ICON_FACE_ANGRY failure_message = "Your appearance softens, as though a great weight is lifted - you may bare your face again." -/datum/quirk/darkpack/monstrous/add_to_holder(mob/living/new_holder, quirk_transfer, client/client_source, unique, announce) - . = ..() - if(ishuman(new_holder)) - var/mob/living/carbon/human/human_holder = new_holder - human_holder.rot_body(1) - ADD_TRAIT(human_holder, TRAIT_MASQUERADE_VIOLATING_FACE, "Monstrous") - if(human_holder.st_get_stat(STAT_APPEARANCE) > 0) - human_holder.st_add_stat_mod(STAT_APPEARANCE, -human_holder.st_get_stat(STAT_APPEARANCE), "Monstrous") +/datum/quirk/darkpack/monstrous/add(client/client_source) + var/mob/living/carbon/human/human_holder = astype(quirk_holder) + if(!human_holder) + return + human_holder.rot_body(1) + ADD_TRAIT(human_holder, TRAIT_MASQUERADE_VIOLATING_FACE, "Monstrous") + if(human_holder.st_get_stat(STAT_APPEARANCE) > 0) + human_holder.st_add_stat_mod(STAT_APPEARANCE, -human_holder.st_get_stat(STAT_APPEARANCE), "Monstrous") diff --git a/modular_darkpack/modules/merits_flaws/code/negative_quirks/thaumaturgically_inept.dm b/modular_darkpack/modules/merits_flaws/code/negative_quirks/thaumaturgically_inept.dm index a28dd948d995..a5bbe779b9bd 100644 --- a/modular_darkpack/modules/merits_flaws/code/negative_quirks/thaumaturgically_inept.dm +++ b/modular_darkpack/modules/merits_flaws/code/negative_quirks/thaumaturgically_inept.dm @@ -6,9 +6,8 @@ allowed_splats = list(SPLAT_KINDRED) included_clans = list(VAMPIRE_CLAN_TREMERE) -/datum/quirk/darkpack/thaumaturgically_inept/add_to_holder(mob/living/new_holder, quirk_transfer, client/client_source, unique, announce) - . = ..() - var/datum/splat/vampire/kindred/kindred_splat = get_kindred_splat(new_holder) +/datum/quirk/darkpack/thaumaturgically_inept/add(client/client_source) + var/datum/splat/vampire/kindred/kindred_splat = get_kindred_splat(quirk_holder) if(!kindred_splat) return kindred_splat.remove_power(/datum/discipline/thaumaturgy) diff --git a/modular_darkpack/modules/merits_flaws/code/neutral_quirks/illegal_identity.dm b/modular_darkpack/modules/merits_flaws/code/neutral_quirks/illegal_identity.dm index 7011d373b5b4..e798c18f029b 100644 --- a/modular_darkpack/modules/merits_flaws/code/neutral_quirks/illegal_identity.dm +++ b/modular_darkpack/modules/merits_flaws/code/neutral_quirks/illegal_identity.dm @@ -14,9 +14,10 @@ /datum/quirk/darkpack/illegal_identity/add() . = ..() - if(!ishuman(quirk_holder)) + var/mob/living/carbon/human/criminal = astype(quirk_holder) + if(!criminal) return - var/mob/living/carbon/human/criminal = quirk_holder + var/obj/item/passport/passport = locate() in criminal // In pockets if(!passport && criminal.back) passport = locate() in criminal.back // In backpack diff --git a/modular_darkpack/modules/merits_flaws/code/old_quirks.dm b/modular_darkpack/modules/merits_flaws/code/old_quirks.dm index 932adc99a81a..b7868645b0bc 100644 --- a/modular_darkpack/modules/merits_flaws/code/old_quirks.dm +++ b/modular_darkpack/modules/merits_flaws/code/old_quirks.dm @@ -271,7 +271,7 @@ Dancer medical_record_text = "Patient has aggressive flesh eating bacteria in their boody." allowed_splats = list("Vampire", "Ghoul", "Human", "Kuei-Jin") -/datum/quirk/consumption/on_process(delta_time) +/datum/quirk/consumption/on_process(seconds_per_tick) if(prob(5)) quirk_holder.adjust_brute_loss(5, TRUE) diff --git a/modular_darkpack/modules/merits_flaws/code/positive_quirks/eat_food_quirk.dm b/modular_darkpack/modules/merits_flaws/code/positive_quirks/eat_food_quirk.dm index 943e5326d545..d6733ff44ca0 100644 --- a/modular_darkpack/modules/merits_flaws/code/positive_quirks/eat_food_quirk.dm +++ b/modular_darkpack/modules/merits_flaws/code/positive_quirks/eat_food_quirk.dm @@ -8,14 +8,11 @@ allowed_splats = list(SPLAT_KINDRED) icon = FA_ICON_UTENSILS -/datum/quirk/darkpack/eat_food/add_to_holder(mob/living/new_holder, quirk_transfer, client/client_source, unique, announce) - . = ..() - if(. == FALSE) +/datum/quirk/darkpack/eat_food/add(client/client_source) + var/mob/living/carbon/human/human_holder = astype(quirk_holder) + if(!human_holder) return - - if(ishuman(new_holder)) - var/mob/living/carbon/human/human_holder = new_holder - var/obj/item/organ/tongue/tongue = human_holder.get_organ_by_type(/obj/item/organ/tongue) - tongue?.liked_foodtypes = initial(tongue.liked_foodtypes) - tongue?.disliked_foodtypes = initial(tongue.disliked_foodtypes) - tongue?.toxic_foodtypes = initial(tongue.toxic_foodtypes) + var/obj/item/organ/tongue/tongue = human_holder.get_organ_by_type(/obj/item/organ/tongue) + tongue?.liked_foodtypes = initial(tongue.liked_foodtypes) + tongue?.disliked_foodtypes = initial(tongue.disliked_foodtypes) + tongue?.toxic_foodtypes = initial(tongue.toxic_foodtypes) diff --git a/modular_darkpack/modules/merits_flaws/code/positive_quirks/giovanni_sanguine_incongruity.dm b/modular_darkpack/modules/merits_flaws/code/positive_quirks/giovanni_sanguine_incongruity.dm index 7060fab2a8ce..f0d55034d7ea 100644 --- a/modular_darkpack/modules/merits_flaws/code/positive_quirks/giovanni_sanguine_incongruity.dm +++ b/modular_darkpack/modules/merits_flaws/code/positive_quirks/giovanni_sanguine_incongruity.dm @@ -10,12 +10,11 @@ icon = FA_ICON_SKULL_CROSSBONES failure_message = "Somehow the Giovanni's Curse of Lamia returns, and your bite becomes far more painful. At least now your skin is more flush with life." -/datum/quirk/darkpack/giovanni_sanguine_incongruity/add_to_holder(mob/living/new_holder, quirk_transfer, client/client_source, unique, announce) - . = ..() - if(!ishuman(new_holder)) +/datum/quirk/darkpack/giovanni_sanguine_incongruity/add(client/client_source) + var/mob/living/carbon/human/human_holder = astype(quirk_holder) + if(!human_holder) return - - var/mob/living/carbon/human/human_holder = new_holder + var/datum/splat/vampire/kindred/kindred = get_kindred_splat(human_holder) if(kindred) if(istype(kindred.clan, /datum/subsplat/vampire_clan/giovanni)) diff --git a/modular_darkpack/modules/merits_flaws/code/positive_quirks/stillness_of_death.dm b/modular_darkpack/modules/merits_flaws/code/positive_quirks/stillness_of_death.dm index 84f7913cef77..1fe2b40148ce 100644 --- a/modular_darkpack/modules/merits_flaws/code/positive_quirks/stillness_of_death.dm +++ b/modular_darkpack/modules/merits_flaws/code/positive_quirks/stillness_of_death.dm @@ -10,10 +10,9 @@ icon = FA_ICON_MOUNTAIN failure_message = "You don't want to hide as a statue anymore." -/datum/quirk/darkpack/stillness_of_death/add_to_holder(mob/living/new_holder, quirk_transfer, client/client_source, unique, announce) - . = ..() +/datum/quirk/darkpack/stillness_of_death/add(client/client_source) var/datum/action/gargoyle_statue_form/statue_action = new() - statue_action.Grant(new_holder) + statue_action.Grant(quirk_holder) /datum/action/gargoyle_statue_form name = "Statue Form" diff --git a/modular_darkpack/modules/merits_flaws/code/positive_quirks/time_sense.dm b/modular_darkpack/modules/merits_flaws/code/positive_quirks/time_sense.dm index 4e509358cb87..fbdf2633b20a 100644 --- a/modular_darkpack/modules/merits_flaws/code/positive_quirks/time_sense.dm +++ b/modular_darkpack/modules/merits_flaws/code/positive_quirks/time_sense.dm @@ -11,12 +11,12 @@ /mob/proc/get_time_status() . = list() - . += "Local City Time: [SSticker.round_start_timeofday ? "[station_time_timestamp("hh:mm MMM")] [CURRENT_STATION_YEAR]" : "The round hasn't started yet!"]" + . += "Local City Time: [SSticker.round_start_timeofday ? "[server_timestamp("hh:mm", ic_time = TRUE, twelve_hour_clock = client?.prefs.read_preference(/datum/preference/toggle/twelve_hour))] [server_timestamp("MMM YYYY", ic_time = TRUE)]" : "The round hasn't started yet!"]" /mob/living/get_time_status() . = list() if(HAS_TRAIT(src, TRAIT_TIME_SENSE)) - . += "Local City Time: [station_time_timestamp("hh:mm MMM")] [CURRENT_STATION_YEAR]" + . += "Local City Time: [server_timestamp("hh:mm", ic_time = TRUE, twelve_hour_clock = client?.prefs.read_preference(/datum/preference/toggle/twelve_hour))] [server_timestamp("MMM YYYY", ic_time = TRUE)]" . += "Phase of moon: [GLOB.moon_state]" else . += "Local City Time: [CURRENT_STATION_YEAR]? Get a watch." diff --git a/modular_darkpack/modules/merits_flaws/code/positive_quirks/wolf_sight.dm b/modular_darkpack/modules/merits_flaws/code/positive_quirks/wolf_sight.dm new file mode 100644 index 000000000000..6c07e73e1c1c --- /dev/null +++ b/modular_darkpack/modules/merits_flaws/code/positive_quirks/wolf_sight.dm @@ -0,0 +1,21 @@ +/datum/quirk/darkpack/wolf_sight + name = "Wolf Sight" + desc = {"In all your forms, you see colors and intensities of light as a wolf does. + Your color vision is slightly less distinct than that of humans, though you embrace the full spectrum of colors. + Your night vision, however, far surpasses human nocturnal vision."} + // Perception is not real yet. + // You also notice movement more readily. You gain an extra die to all visually-based Perception rolls that involve movement or take place at night."} + value = 1 + mob_trait = TRAIT_TRUE_NIGHT_VISION + icon = FA_ICON_DOG + allowed_splats = list(SPLAT_GAROU) + +/datum/quirk/darkpack/wolf_sight/add(client/client_source) + quirk_holder.add_client_colour(/datum/client_colour/wolf_sight, REF(src)) + +/datum/quirk/darkpack/wolf_sight/remove() + quirk_holder.remove_client_colour(REF(src)) + + +/datum/client_colour/wolf_sight + color = "#e6e6e6" diff --git a/modular_darkpack/modules/merits_flaws/merits_flaws.md b/modular_darkpack/modules/merits_flaws/readme.md similarity index 100% rename from modular_darkpack/modules/merits_flaws/merits_flaws.md rename to modular_darkpack/modules/merits_flaws/readme.md diff --git a/modular_darkpack/modules/npc/code/human/npc_types/gunstore.dm b/modular_darkpack/modules/npc/code/human/npc_types/gunstore.dm new file mode 100644 index 000000000000..ea19b80c2153 --- /dev/null +++ b/modular_darkpack/modules/npc/code/human/npc_types/gunstore.dm @@ -0,0 +1,7 @@ +/mob/living/carbon/human/npc/gunstore + staying = TRUE + +/mob/living/carbon/human/npc/gunstore/Initialize(mapload) + . = ..() + + AssignSocialRole(/datum/socialrole/shop/gunstore) diff --git a/modular_darkpack/modules/npc/code/human/npc_types/hardwarestore.dm b/modular_darkpack/modules/npc/code/human/npc_types/hardwarestore.dm new file mode 100644 index 000000000000..947aee85c158 --- /dev/null +++ b/modular_darkpack/modules/npc/code/human/npc_types/hardwarestore.dm @@ -0,0 +1,7 @@ +/mob/living/carbon/human/npc/hardwarestore + staying = TRUE + +/mob/living/carbon/human/npc/hardwarestore/Initialize(mapload) + . = ..() + + AssignSocialRole(/datum/socialrole/shop/hardwarestore) diff --git a/modular_darkpack/modules/npc/code/human/npc_types/huntingstore.dm b/modular_darkpack/modules/npc/code/human/npc_types/huntingstore.dm new file mode 100644 index 000000000000..4bb604f0d7e7 --- /dev/null +++ b/modular_darkpack/modules/npc/code/human/npc_types/huntingstore.dm @@ -0,0 +1,7 @@ +/mob/living/carbon/human/npc/campingstore + staying = TRUE + +/mob/living/carbon/human/npc/campingstore/Initialize(mapload) + . = ..() + + AssignSocialRole(/datum/socialrole/shop/campingstore) diff --git a/modular_darkpack/modules/npc/code/human/npc_types/pharmacystore.dm b/modular_darkpack/modules/npc/code/human/npc_types/pharmacystore.dm new file mode 100644 index 000000000000..55967597de12 --- /dev/null +++ b/modular_darkpack/modules/npc/code/human/npc_types/pharmacystore.dm @@ -0,0 +1,7 @@ +/mob/living/carbon/human/npc/pharmacystore + staying = TRUE + +/mob/living/carbon/human/npc/pharmacystore/Initialize(mapload) + . = ..() + + AssignSocialRole(/datum/socialrole/shop/pharmacystore) diff --git a/modular_darkpack/modules/npc/code/nonhuman/friendly/bird_ai.dm b/modular_darkpack/modules/npc/code/nonhuman/friendly/bird_ai.dm index c2858c2c4a87..1573ea48bb87 100644 --- a/modular_darkpack/modules/npc/code/nonhuman/friendly/bird_ai.dm +++ b/modular_darkpack/modules/npc/code/nonhuman/friendly/bird_ai.dm @@ -24,7 +24,7 @@ target_key = BB_LOW_PRIORITY_HUNTING_TARGET hunting_behavior = /datum/ai_behavior/hunt_target/find_shiney finding_behavior = /datum/ai_behavior/find_hunt_target/find_shiney - hunt_targets = list(/obj/item/ammo_casing, /obj/item/watch, /obj/item/vamp/keys, /obj/item/vtm_artifact, /obj/item/knife) + hunt_targets = list(/obj/item/ammo_casing, /obj/item/watch, /obj/item/vamp/keys, /obj/item/occult_artifact, /obj/item/knife) hunt_range = 10 /datum/ai_behavior/find_hunt_target/find_shiney diff --git a/modular_darkpack/modules/npc/code/nonhuman/hostile/abyss_tentacle.dm b/modular_darkpack/modules/npc/code/nonhuman/hostile/abyss_tentacle.dm index bdcf80203bf9..cb28a7a75525 100644 --- a/modular_darkpack/modules/npc/code/nonhuman/hostile/abyss_tentacle.dm +++ b/modular_darkpack/modules/npc/code/nonhuman/hostile/abyss_tentacle.dm @@ -23,6 +23,7 @@ GLOBAL_LIST_EMPTY(global_tentacle_grabs) speak_emote = list("writhes") basic_mob_flags = DEL_ON_DEATH mobility_flags = NONE + move_resist = MOVE_FORCE_EXTREMELY_STRONG environment_smash = ENVIRONMENT_SMASH_NONE @@ -47,7 +48,7 @@ GLOBAL_LIST_EMPTY(global_tentacle_grabs) /datum/ai_planning_subtree/tentacle_grab_and_crush -/datum/ai_planning_subtree/tentacle_grab_and_crush/SelectBehaviors(datum/ai_controller/controller, delta_time) +/datum/ai_planning_subtree/tentacle_grab_and_crush/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) var/mob/living/basic/abyss_tentacle/tentacle = controller.pawn if(!istype(tentacle)) return @@ -128,14 +129,20 @@ GLOBAL_LIST_EMPTY(global_tentacle_grabs) . = ..() if(summoner) owner = summoner - if(owner?.tentacle_aggro_mode) - aggro_mode = owner.tentacle_aggro_mode + if(owner) + var/datum/splat/vampire/vampire = get_splat_with_discipline(owner) + var/datum/discipline_power/obtenebration/arms_of_the_abyss/abyss_power = vampire?.get_discipline_power(/datum/discipline_power/obtenebration/arms_of_the_abyss) + if(abyss_power) + aggro_mode = abyss_power.aggro_mode /mob/living/basic/abyss_tentacle/Destroy(force) if(owner) var/datum/splat/vampire/vampire = get_splat_with_discipline(owner) - var/datum/discipline_power/obtenebration/arms_of_the_abyss/power = vampire.get_discipline_power(/datum/discipline_power/obtenebration/arms_of_the_abyss) - power.active_tentacles -= src + var/datum/discipline_power/obtenebration/arms_of_the_abyss/abyss_power = vampire?.get_discipline_power(/datum/discipline_power/obtenebration/arms_of_the_abyss) + if(abyss_power) + abyss_power.active_tentacles -= src + if(grabbed_mob) + release_grabbed_mob() . = ..() diff --git a/modular_darkpack/modules/occult_artifacts/code/_artifact.dm b/modular_darkpack/modules/occult_artifacts/code/_artifact.dm new file mode 100644 index 000000000000..b68d7037b54e --- /dev/null +++ b/modular_darkpack/modules/occult_artifacts/code/_artifact.dm @@ -0,0 +1,132 @@ +/obj/item/occult_artifact/pickup(mob/user) + . = ..() + if(identified) + bind(user) + +/obj/item/occult_artifact/dropped(mob/user, silent = FALSE) + . = ..() + if(identified) + if(isturf(loc)) + unbind(user) + + +/obj/item/occult_artifact/process(seconds_per_tick) + if(owner && !in_contents_of(owner)) + unbind(owner) + +/obj/item/occult_artifact + name = "unidentified occult fetish" + desc = "Who knows what secrets it could contain..." + icon_state = "arcane" + icon = 'modular_darkpack/modules/occult_artifacts/icons/artifacts.dmi' + ONFLOOR_ICON_HELPER('modular_darkpack/modules/occult_artifacts/icons/artifacts_onfloor.dmi') + abstract_type = /obj/item/occult_artifact + w_class = WEIGHT_CLASS_SMALL + var/mob/living/owner + var/true_name = "artifact" + var/true_desc = "Debug" + var/identified = FALSE + var/research_value = 0 + var/can_be_identified_without_ritual = TRUE + + var/grant_sound // = 'sound/effects/magic/swap.ogg' + var/ungrant_sound // = 'sound/effects/magic/teleport_diss.ogg' + + var/datum/controller/subsystem/processing/subsystem_type = /datum/controller/subsystem/processing/obj + + var/datum/storyteller_roll/identify_occult/identify_roll + +/obj/item/occult_artifact/proc/identify(mob/living/artifact_identifier) + if(!identified) + name = true_name + desc = true_desc + identified = TRUE + if(src in artifact_identifier?.get_all_contents()) + bind(artifact_identifier) + +/obj/item/occult_artifact/proc/bind(mob/user) + if(!identified) + return + if(owner) // Dont bind twice + return + owner = user + + var/datum/controller/subsystem/processing/subsystem = locate(subsystem_type) in Master.subsystems + START_PROCESSING(subsystem, src) + + grant_powers() + +/obj/item/occult_artifact/proc/unbind(mob/user) + var/datum/controller/subsystem/processing/subsystem = locate(subsystem_type) in Master.subsystems + STOP_PROCESSING(subsystem, src) + + if(owner) + ungrant_powers() + owner = null + +/obj/item/occult_artifact/proc/grant_powers() + SHOULD_CALL_PARENT(TRUE) + + if(grant_sound) + playsound(owner, grant_sound, 5) + return + +/obj/item/occult_artifact/proc/ungrant_powers() + SHOULD_CALL_PARENT(TRUE) + + if(ungrant_sound) + playsound(owner, ungrant_sound, 5) + return + + +/obj/item/occult_artifact/attack_self(mob/user, modifiers) + . = ..() + if(!isliving(user)) + return + + if(identified) + to_chat(user, span_notice("This artifact is already identified.")) + return + + var/mob/living/artifact_identifier = user + if(artifact_identifier.st_get_stat(STAT_OCCULT) < 3) + to_chat(artifact_identifier, span_warning("What is this thing? Some kind of yard sale item?")) + return + + if(!can_be_identified_without_ritual) + to_chat(artifact_identifier, span_warning("You've seen some occult artifacts, trinkets, and powerful relics, but this, you've either never seen it before, or it's power can only be awakened by few...")) + return + + to_chat(artifact_identifier, span_cult("You might have seen this before in an occult text. You start identifying it...")) + if(!do_after(artifact_identifier, 1 TURNS, src)) + return + + if(!identify_roll) + identify_roll = new() + var/roll = identify_roll.st_roll(user, src) + if(roll == ROLL_SUCCESS) + identify(artifact_identifier) + to_chat(artifact_identifier, span_cult("You successfully identify [src]!")) + else + to_chat(artifact_identifier, span_warning("You stop examining [src].")) + +/obj/effect/spawner/random/occult + name = "occult spawner" + icon = 'modular_darkpack/modules/occult_artifacts/icons/artifacts.dmi' + icon_state = "art_rand" + +/obj/effect/spawner/random/occult/artifact + name = "random occult artifact" + loot_subtype_path = /obj/item/occult_artifact + +/obj/effect/spawner/random/occult/artifact/Initialize(mapload) + spawn_loot_chance = CONFIG_GET(number/artifact_random_probability) + . = ..() + +/obj/effect/spawner/random/occult/artifact/vampire_only + name = "random vampire artifact" + loot_subtype_path = /obj/item/occult_artifact/vampire + +/obj/effect/spawner/random/occult/artifact/werewolf_only + name = "random garou fetish" + loot_subtype_path = /obj/item/occult_artifact/werewolf diff --git a/modular_darkpack/modules/occult_artifacts/code/artifacts/_artifact_config.dm b/modular_darkpack/modules/occult_artifacts/code/_artifact_config.dm similarity index 51% rename from modular_darkpack/modules/occult_artifacts/code/artifacts/_artifact_config.dm rename to modular_darkpack/modules/occult_artifacts/code/_artifact_config.dm index 88ad397bbe66..464bf8b5a3a4 100644 --- a/modular_darkpack/modules/occult_artifacts/code/artifacts/_artifact_config.dm +++ b/modular_darkpack/modules/occult_artifacts/code/_artifact_config.dm @@ -1,9 +1,9 @@ /datum/config_entry/number/artifact_crate_probability - default = 20 - min_val = 0 - max_val = 100 + default = 20 + min_val = 0 + max_val = 100 /datum/config_entry/number/artifact_random_probability - default = 50 - min_val = 0 - max_val = 100 + default = 50 + min_val = 0 + max_val = 100 diff --git a/modular_darkpack/modules/occult_artifacts/code/_vampire.dm b/modular_darkpack/modules/occult_artifacts/code/_vampire.dm new file mode 100644 index 000000000000..7b803e33bc5f --- /dev/null +++ b/modular_darkpack/modules/occult_artifacts/code/_vampire.dm @@ -0,0 +1,2 @@ +/obj/item/occult_artifact/vampire + abstract_type = /obj/item/occult_artifact/vampire diff --git a/modular_darkpack/modules/occult_artifacts/code/_werewolf.dm b/modular_darkpack/modules/occult_artifacts/code/_werewolf.dm new file mode 100644 index 000000000000..945b57b1091d --- /dev/null +++ b/modular_darkpack/modules/occult_artifacts/code/_werewolf.dm @@ -0,0 +1,33 @@ +GLOBAL_LIST_INIT(night_spirits, world.file2list("modular_darkpack/modules/occult_artifacts/strings/night_spirits.txt")) +GLOBAL_LIST_INIT(darkness_spirits, world.file2list("modular_darkpack/modules/occult_artifacts/strings/darkness_spirits.txt")) +GLOBAL_LIST_INIT(vengeance_spirits, world.file2list("modular_darkpack/modules/occult_artifacts/strings/vengeance_spirits.txt")) + +/obj/item/occult_artifact/werewolf + icon = 'modular_darkpack/modules/occult_artifacts/icons/fetishes.dmi' + worn_icon = 'modular_darkpack/modules/occult_artifacts/icons/fetishes_worn.dmi' + lefthand_file = 'modular_darkpack/modules/occult_artifacts/icons/fetishes_lefthand.dmi' + righthand_file = 'modular_darkpack/modules/occult_artifacts/icons/fetishes_righthand.dmi' + ONFLOOR_ICON_HELPER('modular_darkpack/modules/occult_artifacts/icons/fetishes_onfloor.dmi') + icon_state = "dagger" + abstract_type = /obj/item/occult_artifact/werewolf + var/spirit_name = "Glitchimus" + var/spirit_type = "ahelp" + +/proc/generate_spirit_name(spirit_type) // TODO: make this better. there are 50+ spirits in WoD, and that's not condusive to this format. + var/spirit_name + var/spirit_table + var/spirit_desc + + switch(spirit_type) + if(SPIRIT_NIGHT) + spirit_table = GLOB.night_spirits + if(SPIRIT_DARKNESS) + spirit_table = GLOB.darkness_spirits + if(SPIRIT_VENGEANCE) + spirit_table = GLOB.vengeance_spirits + + if(length(spirit_table)) + spirit_name = pick(spirit_table) + spirit_desc = "[spirit_name], a spirit of [spirit_type]" + + return spirit_desc diff --git a/modular_darkpack/modules/occult_artifacts/code/artifacts/_artifact.dm b/modular_darkpack/modules/occult_artifacts/code/artifacts/_artifact.dm deleted file mode 100644 index 693b72bbfcb4..000000000000 --- a/modular_darkpack/modules/occult_artifacts/code/artifacts/_artifact.dm +++ /dev/null @@ -1,98 +0,0 @@ -/obj/item/vtm_artifact/pickup(mob/user) - . = ..() - if(identified) - owner = user - START_PROCESSING(SSobj, src) - get_powers() - -/obj/item/vtm_artifact/dropped(mob/user) - . = ..() - if(identified) - if(isturf(loc)) - STOP_PROCESSING(SSobj, src) - if(owner) - remove_powers() - owner = null - -/obj/item/vtm_artifact/process(delta_time) - if(owner != loc && owner != loc.loc) - forceMove(get_turf(src)) - STOP_PROCESSING(SSobj, src) - if(owner) - remove_powers() - owner = null - -/obj/item/vtm_artifact - name = "unidentified occult fetish" - desc = "Who knows what secrets it could contain..." - icon_state = "arcane" - icon = 'modular_darkpack/modules/occult_artifacts/icons/artifacts.dmi' - ONFLOOR_ICON_HELPER('modular_darkpack/modules/occult_artifacts/icons/artifacts_onfloor.dmi') - w_class = WEIGHT_CLASS_SMALL - var/mob/living/owner - var/true_name = "artifact" - var/true_desc = "Debug" - var/identified = FALSE - var/gained_boosts = FALSE - var/research_value = 0 - var/can_be_identified_without_ritual = TRUE - - var/datum/storyteller_roll/identify_occult/identify_roll - -/obj/item/vtm_artifact/proc/identify() - if(!identified) - name = true_name - desc = true_desc - identified = TRUE - -/obj/item/vtm_artifact/proc/get_powers() - if(!identified) - return - -/obj/item/vtm_artifact/proc/remove_powers() - if(!identified) - return - -/obj/item/vtm_artifact/attack_self(mob/user, modifiers) - . = ..() - if(!isliving(user)) - return - - if(identified) - to_chat(user, span_notice("This artifact is already identified.")) - return - - var/mob/living/artifact_identifier = user - if(artifact_identifier.st_get_stat(STAT_OCCULT) < 3) - to_chat(artifact_identifier, span_warning("What is this thing? Some kind of yard sale item?")) - return - - if(can_be_identified_without_ritual == FALSE) - to_chat(artifact_identifier, span_warning("You've seen some occult artifacts, trinkets, and powerful relics, but this, you've either never seen it before, or it's power can only be awakened by few...")) - return - - to_chat(artifact_identifier, span_cult("You might have seen this before in an occult text. You start identifying it...")) - if(do_after(artifact_identifier, 1 TURNS, src)) - if(!identify_roll) - identify_roll = new() - identify_roll.difficulty = 8 - var/roll = identify_roll.st_roll(user, src) - if(roll == ROLL_SUCCESS) - identify() - to_chat(artifact_identifier, span_cult("You successfully identify [src]!")) - else - to_chat(artifact_identifier, span_warning("You stop examining [src].")) - -/obj/effect/spawner/random/occult - name = "occult spawner" - icon = 'modular_darkpack/modules/occult_artifacts/icons/artifacts.dmi' - icon_state = "art_rand" - -/obj/effect/spawner/random/occult/artifact - name = "random occult fetish" - //spawn_loot_chance = CONFIG_GET(number/artifact_random_probability) - loot_subtype_path = /obj/item/vtm_artifact - -/obj/effect/spawner/random/occult/artifact/Initialize(mapload) - spawn_loot_chance = CONFIG_GET(number/artifact_random_probability) - . = ..() diff --git a/modular_darkpack/modules/occult_artifacts/code/artifacts/bloodstar.dm b/modular_darkpack/modules/occult_artifacts/code/artifacts/bloodstar.dm index f8f5e58d45ec..bc69b137dcdf 100644 --- a/modular_darkpack/modules/occult_artifacts/code/artifacts/bloodstar.dm +++ b/modular_darkpack/modules/occult_artifacts/code/artifacts/bloodstar.dm @@ -1,13 +1,13 @@ -/obj/item/vtm_artifact/bloodstar +/obj/item/occult_artifact/vampire/bloodstar true_name = "Bloodstar" true_desc = "Increases Bloodpower efficiency." icon_state = "bloodstar" research_value = 10 -/obj/item/vtm_artifact/bloodstar/get_powers() +/obj/item/occult_artifact/vampire/bloodstar/grant_powers() . = ..() owner.blood_efficiency = 0.8 -/obj/item/vtm_artifact/bloodstar/remove_powers() +/obj/item/occult_artifact/vampire/bloodstar/ungrant_powers() . = ..() owner.blood_efficiency = 1 diff --git a/modular_darkpack/modules/occult_artifacts/code/artifacts/bloodstone.dm b/modular_darkpack/modules/occult_artifacts/code/artifacts/bloodstone.dm index 82d0b1103c0a..32d489a1e46a 100644 --- a/modular_darkpack/modules/occult_artifacts/code/artifacts/bloodstone.dm +++ b/modular_darkpack/modules/occult_artifacts/code/artifacts/bloodstone.dm @@ -1,4 +1,4 @@ -/obj/item/vtm_artifact/bloodstone +/obj/item/occult_artifact/vampire/bloodstone true_name = "bloodstone" true_desc = "A pulsing crimson stone that creates a mystical bond with its identifier." icon = 'modular_darkpack/modules/paths/icons/bloodstone_artifact.dmi' @@ -9,7 +9,7 @@ var/datum/action/bloodstone_track/tracking_action research_value = 15 -/obj/item/vtm_artifact/bloodstone/identify() +/obj/item/occult_artifact/vampire/bloodstone/identify() . = ..() if(identified && !bound_identifier) var/mob/living/carbon/human/user = usr @@ -20,7 +20,7 @@ tracking_action = new /datum/action/bloodstone_track(user, src) tracking_action.Grant(user) -/obj/item/vtm_artifact/bloodstone/Destroy() +/obj/item/occult_artifact/vampire/bloodstone/Destroy() if(tracking_action) var/mob/living/carbon/human/user = bound_identifier.resolve() if(user) @@ -37,7 +37,7 @@ check_flags = AB_CHECK_CONSCIOUS var/datum/weakref/tracked_stone -/datum/action/bloodstone_track/New(Target, obj/item/vtm_artifact/bloodstone/stone) +/datum/action/bloodstone_track/New(Target, obj/item/occult_artifact/vampire/bloodstone/stone) . = ..() tracked_stone = WEAKREF(stone) @@ -46,7 +46,7 @@ if(!.) return - var/obj/item/vtm_artifact/bloodstone/bloodstone = tracked_stone.resolve() + var/obj/item/occult_artifact/vampire/bloodstone/bloodstone = tracked_stone.resolve() if(!bloodstone) to_chat(owner, span_warning("The bloodstone bond has been severed.")) Remove(owner) diff --git a/modular_darkpack/modules/occult_artifacts/code/artifacts/daimonori.dm b/modular_darkpack/modules/occult_artifacts/code/artifacts/daimonori.dm index 80eefc379d88..27bd2c9f4114 100644 --- a/modular_darkpack/modules/occult_artifacts/code/artifacts/daimonori.dm +++ b/modular_darkpack/modules/occult_artifacts/code/artifacts/daimonori.dm @@ -1,13 +1,13 @@ -/obj/item/vtm_artifact/daimonori +/obj/item/occult_artifact/vampire/daimonori true_name = "Daimonori" true_desc = "Increases thaumaturgy damage." icon_state = "daimonori" research_value = 20 -/obj/item/vtm_artifact/daimonori/get_powers() +/obj/item/occult_artifact/vampire/daimonori/grant_powers() . = ..() owner.thaum_damage_plus = 20 -/obj/item/vtm_artifact/daimonori/remove_powers() +/obj/item/occult_artifact/vampire/daimonori/ungrant_powers() . = ..() owner.thaum_damage_plus = 0 diff --git a/modular_darkpack/modules/occult_artifacts/code/artifacts/fae_charm.dm b/modular_darkpack/modules/occult_artifacts/code/artifacts/fae_charm.dm index 776d2a7b1ebe..40a7898f1012 100644 --- a/modular_darkpack/modules/occult_artifacts/code/artifacts/fae_charm.dm +++ b/modular_darkpack/modules/occult_artifacts/code/artifacts/fae_charm.dm @@ -1,16 +1,13 @@ -/obj/item/vtm_artifact/fae_charm +/obj/item/occult_artifact/vampire/fae_charm true_name = "Fae Charm" true_desc = "Dexterity boost." icon_state = "fae_charm" research_value = 35 -/obj/item/vtm_artifact/fae_charm/get_powers() +/obj/item/occult_artifact/vampire/fae_charm/grant_powers() . = ..() owner.st_add_stat_mod(STAT_DEXTERITY, 1, type) -/obj/item/vtm_artifact/fae_charm/remove_powers() +/obj/item/occult_artifact/vampire/fae_charm/ungrant_powers() . = ..() owner.st_remove_stat_mod(STAT_DEXTERITY, 1, type) - -/datum/movespeed_modifier/fae_charm - multiplicative_slowdown = -0.20 diff --git a/modular_darkpack/modules/occult_artifacts/code/artifacts/galdjum.dm b/modular_darkpack/modules/occult_artifacts/code/artifacts/galdjum.dm index 9b3cd310b289..d54e646bf84b 100644 --- a/modular_darkpack/modules/occult_artifacts/code/artifacts/galdjum.dm +++ b/modular_darkpack/modules/occult_artifacts/code/artifacts/galdjum.dm @@ -1,13 +1,13 @@ -/obj/item/vtm_artifact/galdjum +/obj/item/occult_artifact/vampire/galdjum true_name = "Galdjum" true_desc = "Increases disciplines duration." icon_state = "galdjum" research_value = 10 -/obj/item/vtm_artifact/galdjum/get_powers() +/obj/item/occult_artifact/vampire/galdjum/grant_powers() . = ..() owner.discipline_time_plus = 25 -/obj/item/vtm_artifact/galdjum/remove_powers() +/obj/item/occult_artifact/vampire/galdjum/ungrant_powers() . = ..() owner.discipline_time_plus = 0 diff --git a/modular_darkpack/modules/occult_artifacts/code/artifacts/heart_of_eliza.dm b/modular_darkpack/modules/occult_artifacts/code/artifacts/heart_of_eliza.dm index cc14745e5782..f84fa5fb8ba6 100644 --- a/modular_darkpack/modules/occult_artifacts/code/artifacts/heart_of_eliza.dm +++ b/modular_darkpack/modules/occult_artifacts/code/artifacts/heart_of_eliza.dm @@ -1,13 +1,13 @@ -/obj/item/vtm_artifact/heart_of_eliza +/obj/item/occult_artifact/vampire/heart_of_eliza true_name = "Heart of Eliza" true_desc = "Melee damage boost." icon_state = "h_eliza" research_value = 30 -/obj/item/vtm_artifact/heart_of_eliza/get_powers() +/obj/item/occult_artifact/vampire/heart_of_eliza/grant_powers() . = ..() owner.st_add_stat_mod(STAT_STRENGTH, 1, type) -/obj/item/vtm_artifact/heart_of_eliza/remove_powers() +/obj/item/occult_artifact/vampire/heart_of_eliza/ungrant_powers() . = ..() owner.st_remove_stat_mod(STAT_STRENGTH, 1, type) diff --git a/modular_darkpack/modules/occult_artifacts/code/artifacts/key_of_alamut.dm b/modular_darkpack/modules/occult_artifacts/code/artifacts/key_of_alamut.dm index 43557a4f24bc..914bf9fbebe4 100644 --- a/modular_darkpack/modules/occult_artifacts/code/artifacts/key_of_alamut.dm +++ b/modular_darkpack/modules/occult_artifacts/code/artifacts/key_of_alamut.dm @@ -1,10 +1,10 @@ -/obj/item/vtm_artifact/key_of_alamut +/obj/item/occult_artifact/vampire/key_of_alamut true_name = "Key of Alamut" true_desc = "Decreases incoming damage." icon_state = "k_alamut" research_value = 30 -/obj/item/vtm_artifact/key_of_alamut/get_powers() +/obj/item/occult_artifact/vampire/key_of_alamut/grant_powers() . = ..() var/mob/living/carbon/human/H = owner if(H.dna.species.damage_modifier >= 70) @@ -12,7 +12,7 @@ if(H.dna) H.dna.species.damage_modifier = H.dna.species.damage_modifier+20 -/obj/item/vtm_artifact/key_of_alamut/remove_powers() +/obj/item/occult_artifact/vampire/key_of_alamut/ungrant_powers() . = ..() var/mob/living/carbon/human/H = owner if(H.dna.species.damage_modifier >= 50) diff --git a/modular_darkpack/modules/occult_artifacts/code/artifacts/mummywrap_fetish.dm b/modular_darkpack/modules/occult_artifacts/code/artifacts/mummywrap_fetish.dm index 086912eee32a..6e2c5f3be540 100644 --- a/modular_darkpack/modules/occult_artifacts/code/artifacts/mummywrap_fetish.dm +++ b/modular_darkpack/modules/occult_artifacts/code/artifacts/mummywrap_fetish.dm @@ -1,11 +1,11 @@ -/obj/item/vtm_artifact/mummywrap_fetish +/obj/item/occult_artifact/vampire/mummywrap_fetish true_name = "Mummywrap Fetish" true_desc = "Passive health regeneration." icon_state = "m_fetish" var/last_regen = 0 research_value = 10 -/obj/item/vtm_artifact/mummywrap_fetish/process(delta_time) +/obj/item/occult_artifact/vampire/mummywrap_fetish/process(seconds_per_tick) . = ..() if(identified && owner) if(last_regen+60 < world.time) diff --git a/modular_darkpack/modules/occult_artifacts/code/artifacts/odious_chalice.dm b/modular_darkpack/modules/occult_artifacts/code/artifacts/odious_chalice.dm index b1a491dfb394..ac6a05228d28 100644 --- a/modular_darkpack/modules/occult_artifacts/code/artifacts/odious_chalice.dm +++ b/modular_darkpack/modules/occult_artifacts/code/artifacts/odious_chalice.dm @@ -1,15 +1,15 @@ -/obj/item/vtm_artifact/odious_chalice +/obj/item/occult_artifact/vampire/odious_chalice true_name = "Odious Chalice" true_desc = "Stores blood from every attack." icon_state = "o_chalice" var/stored_blood = 0 research_value = 30 -/obj/item/vtm_artifact/odious_chalice/examine(mob/user) +/obj/item/occult_artifact/vampire/odious_chalice/examine(mob/user) . = ..() . += "[src] contains [stored_blood] blood points..." -/obj/item/vtm_artifact/odious_chalice/attack(mob/living/M, mob/living/user) +/obj/item/occult_artifact/vampire/odious_chalice/attack(mob/living/M, mob/living/user) . = ..() if(!get_kindred_splat(M)) return diff --git a/modular_darkpack/modules/occult_artifacts/code/artifacts/tarulfang.dm b/modular_darkpack/modules/occult_artifacts/code/artifacts/tarulfang.dm new file mode 100644 index 000000000000..80ddaac33023 --- /dev/null +++ b/modular_darkpack/modules/occult_artifacts/code/artifacts/tarulfang.dm @@ -0,0 +1,13 @@ +// DARKPACK TODO - FRENZY - (This never did FUCK anything.) +/obj/item/occult_artifact/vampire/tarulfang + true_name = "Tarulfang" + true_desc = "Decreases chance of frenzy." + icon_state = "tarulfang" + +/obj/item/occult_artifact/vampire/tarulfang/grant_powers() + . = ..() + owner.frenzy_chance_boost = 5 + +/obj/item/occult_artifact/vampire/tarulfang/ungrant_powers() + . = ..() + owner.frenzy_chance_boost = 10 diff --git a/modular_darkpack/modules/occult_artifacts/code/artifacts/weekapaug_thistle.dm b/modular_darkpack/modules/occult_artifacts/code/artifacts/weekapaug_thistle.dm index e5bfdd8a594e..406bd60fe0fb 100644 --- a/modular_darkpack/modules/occult_artifacts/code/artifacts/weekapaug_thistle.dm +++ b/modular_darkpack/modules/occult_artifacts/code/artifacts/weekapaug_thistle.dm @@ -2,31 +2,22 @@ melee = 10 bullet = 10 -/obj/item/vtm_artifact/weekapaug_thistle +/obj/item/occult_artifact/vampire/weekapaug_thistle true_name = "Weekapaug Thistle" true_desc = "Increases combat defense." icon_state = "w_thistle" research_value = 10 -/obj/item/vtm_artifact/weekapaug_thistle/get_powers() +/obj/item/occult_artifact/vampire/weekapaug_thistle/grant_powers() . = ..() - var/mob/living/carbon/human/H = owner - H.physiology.armor = H.physiology.armor.add_other_armor(/datum/armor/weekapaug_thistle) + var/mob/living/carbon/human/human_owner = astype(owner) + if(!human_owner) + return + human_owner.physiology.armor = human_owner.physiology.armor.add_other_armor(/datum/armor/weekapaug_thistle) -/obj/item/vtm_artifact/weekapaug_thistle/remove_powers() +/obj/item/occult_artifact/vampire/weekapaug_thistle/ungrant_powers() . = ..() - var/mob/living/carbon/human/H = owner - H.physiology.armor = H.physiology.armor.subtract_other_armor(/datum/armor/weekapaug_thistle) - -/obj/item/vtm_artifact/tarulfang - true_name = "Tarulfang" - true_desc = "Decreases chance of frenzy." - icon_state = "tarulfang" - -/obj/item/vtm_artifact/weekapaug_thistle/get_powers() - . = ..() - owner.frenzy_chance_boost = 5 - -/obj/item/vtm_artifact/weekapaug_thistle/remove_powers() - . = ..() - owner.frenzy_chance_boost = 10 + var/mob/living/carbon/human/human_owner = astype(owner) + if(!human_owner) + return + human_owner.physiology.armor = human_owner.physiology.armor.subtract_other_armor(/datum/armor/weekapaug_thistle) diff --git a/modular_darkpack/modules/occult_artifacts/code/fetishes/dagger_of_retribution.dm b/modular_darkpack/modules/occult_artifacts/code/fetishes/dagger_of_retribution.dm new file mode 100644 index 000000000000..5e2c55097ac8 --- /dev/null +++ b/modular_darkpack/modules/occult_artifacts/code/fetishes/dagger_of_retribution.dm @@ -0,0 +1,160 @@ +/obj/item/occult_artifact/werewolf/dagger_of_retribution + name = "iron knife" + desc = "A crude knife wrought from iron." + true_name = "dagger of retribution" + true_desc = "An ugly iron dagger imbued with a vengeance-spirit." + worn_icon = 'modular_darkpack/modules/weapons/icons/worn_melee.dmi' + worn_icon_state = "knife" + icon_state = "dagger" + force = 30 + wound_bonus = -5 + throwforce = 15 + attack_verb_continuous = list("slashes", "cuts") + attack_verb_simple = list("slash", "cut") + hitsound = 'sound/items/weapons/slash.ogg' + armour_penetration = 35 + block_chance = 5 + sharpness = SHARP_EDGED + w_class = WEIGHT_CLASS_SMALL + slot_flags = ITEM_SLOT_BELT + resistance_flags = FIRE_PROOF + subsystem_type = /datum/controller/subsystem/processing/fastprocess + + spirit_type = SPIRIT_VENGEANCE + + var/obj/bound_item + var/spinning = FALSE + + +/obj/item/occult_artifact/werewolf/dagger_of_retribution/Initialize(mapload) + . = ..() + spirit_name = generate_spirit_name(spirit_type) + +/obj/item/occult_artifact/werewolf/dagger_of_retribution/Destroy(force) + stop_live_tracking() + . = ..() + +/obj/item/occult_artifact/werewolf/dagger_of_retribution/identify() + . = ..() + say("I am [spirit_name]... That which is lost will be found...") + +/obj/item/occult_artifact/werewolf/dagger_of_retribution/examine(mob/user) + . = ..() + if(identified) + . += span_nicegreen("Concentrate on a lost item while holding the dagger; the weapon will gently tug in the direction of the item until you reclaim it.") + . += span_purple("Imbued with [spirit_name].") + if(bound_item) + . += span_purple("Bound to [bound_item].") + if(iscarbon(loc)) + var/mob/living/carbon/C = loc + + var/obj/item/mainhand = C.get_active_held_item() + var/obj/item/offhand = C.get_inactive_held_item() + + if(mainhand == src || offhand == src) + . += span_notice("It's tugging you to the [angle2text(targets_angle())]") + + . += span_notice("
    Bind an item by CLICKing on it with [src]. Unbind [src] by right clicking it.") + + + +/obj/item/occult_artifact/werewolf/dagger_of_retribution/pickup(mob/user) + . = ..() + if(bound_item) + start_live_tracking(user) + + +/obj/item/occult_artifact/werewolf/dagger_of_retribution/dropped(mob/user, silent = FALSE) + . = ..() + stop_live_tracking(user) + + + +/obj/item/occult_artifact/werewolf/dagger_of_retribution/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) + if(!identified) + return NONE + + if(user.combat_mode) + return NONE + + if(!istype(interacting_with, /obj)) // is it an object? + if(!istype(interacting_with, /turf)) + to_chat(user, span_warning("[src] refuses to be bound to [interacting_with]!")) + return ITEM_INTERACT_BLOCKING + return NONE + + if(bound_item) // do we have an item bound to us already? + to_chat(user, span_warning("[src] is already bound to [bound_item]!")) + return ITEM_INTERACT_BLOCKING + + // We are clicking on an object, we're on the right intent, and we're not bound. + bound_item = interacting_with + start_live_tracking(user) + return ITEM_INTERACT_SUCCESS + + +/obj/item/occult_artifact/werewolf/dagger_of_retribution/proc/start_live_tracking(mob/user) + RegisterSignal(bound_item, COMSIG_QDELETING, PROC_REF(stop_live_tracking)) + + if(bound_item && user) + to_chat(user, span_notice("[src] starts tugging you towards [bound_item].")) + +/obj/item/occult_artifact/werewolf/dagger_of_retribution/proc/stop_live_tracking(mob/user) + if(!bound_item) + return + + UnregisterSignal(bound_item, COMSIG_QDELETING) + + if(QDELING(bound_item)) + bound_item = null + + if(user) + to_chat(user, span_warning("[src] stops tugging.")) + + var/matrix/M = matrix(0, MATRIX_ROTATE) + animate(src, transform = M, time = 5, loop = 0) + +/obj/item/occult_artifact/werewolf/dagger_of_retribution/process(seconds_per_tick) + . = ..() + if(!bound_item) + return + + var/turf/our_turf = get_turf(src) + var/turf/bound_item_turf = get_turf(bound_item) + + if(our_turf.z == bound_item_turf.z) + point_to_target() + spinning = FALSE + else if(!spinning) + SpinAnimation(5, -1) + spinning = TRUE + +/obj/item/occult_artifact/werewolf/dagger_of_retribution/proc/point_to_target() + if(iscarbon(loc)) + var/mob/living/carbon/C = loc + + var/obj/item/mainhand = C.get_active_held_item() + var/obj/item/offhand = C.get_inactive_held_item() + + if(mainhand == src || offhand == src) + var/bound_dir = targets_angle()-135 + if(bound_item) + var/matrix/M = matrix(bound_dir, MATRIX_ROTATE) + animate(src, transform = M, time = 5, loop = 0) + else + stop_live_tracking(C) + +/obj/item/occult_artifact/werewolf/dagger_of_retribution/proc/targets_angle() + var/datum/point/point_a = RETURN_PRECISE_POINT(get_turf(src)) + var/datum/point/point_b = RETURN_PRECISE_POINT(get_turf(bound_item)) + + return angle_between_points(point_a, point_b) + +/obj/item/occult_artifact/werewolf/dagger_of_retribution/attack_self_secondary(mob/user, modifiers) + . = ..() + if(bound_item) + to_chat(user, span_warning("You start to unbind [bound_item] from [src].")) + + if(do_after(user, 3 SECONDS, src)) + stop_live_tracking(user) + bound_item = null diff --git a/modular_darkpack/modules/occult_artifacts/code/fetishes/nyxs_bangle.dm b/modular_darkpack/modules/occult_artifacts/code/fetishes/nyxs_bangle.dm new file mode 100644 index 000000000000..ebef20658b84 --- /dev/null +++ b/modular_darkpack/modules/occult_artifacts/code/fetishes/nyxs_bangle.dm @@ -0,0 +1,62 @@ +/* Nyx's Bangle */ +/obj/item/occult_artifact/werewolf/nyxs_bangle + name = "silver bracelet" + desc = "A chain bracelet made of silver." + true_name = "Nyx's Bangle" + true_desc = "A silver bracelet with numerous glyphs." + icon_state = "bangle" + worn_icon_state = "bangle" + slot_flags = ITEM_SLOT_GLOVES | ITEM_SLOT_ID + + subsystem_type = /datum/controller/subsystem/processing/fastprocess + + ungrant_sound = 'sound/effects/hallucinations/growl1.ogg' + +/obj/item/occult_artifact/werewolf/nyxs_bangle/identify() + . = ..() + say("I am [spirit_name]... Hide now, in shadow.") + +/obj/item/occult_artifact/werewolf/nyxs_bangle/ungrant_powers() + . = ..() + + owner.alpha = 255 + + +/obj/item/occult_artifact/werewolf/nyxs_bangle/process(seconds_per_tick) + . = ..() + + var/mob/living/carbon/carbon_owner = astype(owner) + if(identified && carbon_owner) + var/turf/owner_turf = get_turf(owner) + var/light_amount = owner_turf.get_lumcount() + + if(light_amount <= 0.2) + if(src == carbon_owner.gloves || src == carbon_owner.get_active_held_item() || src == carbon_owner.get_inactive_held_item()) + carbon_owner.alpha = max(carbon_owner.alpha-12.75, 25.5) + else + carbon_owner.alpha = min (carbon_owner.alpha+25.5, 255) + else + carbon_owner.alpha = min (carbon_owner.alpha+25.5, 255) + +/obj/item/occult_artifact/werewolf/nyxs_bangle/proc/get_held_mob() + if(isnull(loc)) + return null + if(isliving(loc)) + return loc + var/nested_loc = loc.loc + if (isliving(nested_loc)) + return nested_loc + return null + +/obj/item/occult_artifact/werewolf/nyxs_bangle/Initialize(mapload) + . = ..() + spirit_type = pick(SPIRIT_NIGHT, SPIRIT_DARKNESS) + spirit_name = generate_spirit_name(spirit_type) + + +/obj/item/occult_artifact/werewolf/nyxs_bangle/examine(mob/user) + . = ..() + if(identified) + . += span_nicegreen("Hide everything but your bestial eyes in shadow.") + . += span_notice("EQUIP [src] in the ID slot or GLOVES slot or HOLD it in your hand to become partially invisible in shadow.") + . += span_purple("Imbued with [spirit_name].") diff --git a/modular_darkpack/modules/occult_artifacts/icons/fetishes.dmi b/modular_darkpack/modules/occult_artifacts/icons/fetishes.dmi new file mode 100644 index 000000000000..38ff0797477a Binary files /dev/null and b/modular_darkpack/modules/occult_artifacts/icons/fetishes.dmi differ diff --git a/modular_darkpack/modules/occult_artifacts/icons/fetishes_lefthand.dmi b/modular_darkpack/modules/occult_artifacts/icons/fetishes_lefthand.dmi new file mode 100644 index 000000000000..6c5c6c0aebd8 Binary files /dev/null and b/modular_darkpack/modules/occult_artifacts/icons/fetishes_lefthand.dmi differ diff --git a/modular_darkpack/modules/occult_artifacts/icons/fetishes_onfloor.dmi b/modular_darkpack/modules/occult_artifacts/icons/fetishes_onfloor.dmi new file mode 100644 index 000000000000..fdeba6ce2516 Binary files /dev/null and b/modular_darkpack/modules/occult_artifacts/icons/fetishes_onfloor.dmi differ diff --git a/modular_darkpack/modules/occult_artifacts/icons/fetishes_righthand.dmi b/modular_darkpack/modules/occult_artifacts/icons/fetishes_righthand.dmi new file mode 100644 index 000000000000..ef812a97539f Binary files /dev/null and b/modular_darkpack/modules/occult_artifacts/icons/fetishes_righthand.dmi differ diff --git a/modular_darkpack/modules/occult_artifacts/icons/fetishes_worn.dmi b/modular_darkpack/modules/occult_artifacts/icons/fetishes_worn.dmi new file mode 100644 index 000000000000..38aefa65d71d Binary files /dev/null and b/modular_darkpack/modules/occult_artifacts/icons/fetishes_worn.dmi differ diff --git a/modular_darkpack/modules/occult_artifacts/strings/darkness_spirits.txt b/modular_darkpack/modules/occult_artifacts/strings/darkness_spirits.txt new file mode 100644 index 000000000000..dba5931b56e2 --- /dev/null +++ b/modular_darkpack/modules/occult_artifacts/strings/darkness_spirits.txt @@ -0,0 +1,69 @@ +Aethra’s Hollow +Blackmere +Crepharion +Crepusar +Crepuscar +Crepusculus, Dark Traveller +Darkwave +Duskrine +Duskvein +Duskwalker +Ebonhollow +Ebonstride +Eclipsera +Eclipthra +Gloamrend +Mireveil +Morvaith +Mourncurrent +Mournveil +Nethrael +Nightrender +Nocthalis +Noctherin +Noctheros +Noctirion +Nyxfen +Obscuran +Obsidra +Ombryl +Sableheart +Shadeborne +Shadewarden +Shadowborne +Shadowstep +Silthra +Tenebralis +Tenebreth +Tenebrus +The Ashen Silence +The Black Flow +The Dark Water +The Dim Path +The Drowned Night +The Fading Tide +The Gloaming Wanderer +The Gray Hunger +The Hollow Shade +The Murkway +The Murmuring Dark +The Night Below +The Obsidian Wane +The Pale Gloom +The Silent Depth +The Silent Eclipse +The Veiled Flow +Thorn of Night +Thraen of Dusk +Umbracend +Umbraeth +Umbrathis +Umbravine +Velastra +Velkyn +Velmourn +Velquor +Veyloth +Veythar +Voidwender +Vorynth diff --git a/modular_darkpack/modules/occult_artifacts/strings/night_spirits.txt b/modular_darkpack/modules/occult_artifacts/strings/night_spirits.txt new file mode 100644 index 000000000000..0671a0621ea7 --- /dev/null +++ b/modular_darkpack/modules/occult_artifacts/strings/night_spirits.txt @@ -0,0 +1,105 @@ +Noctyss +Velunara +Mirethyn +Shadow Muse +Dreamveil +Eclipsera +Whisperlune +Lunathis +Velnara +Duskweaver +Moonglint +Nocthera +Selenithra +Aurevelle +Threnody of Stars +Nightbloom +Veylune +Somnara +Nightrill +Ombryn +Eclipshade +Nytheris +Vaymera +Moonstray +Lunacendre +Astrellia +Viorneth +Noctilisse +Dreamesse +Nightrhyme +Mournveil +Shadowdawn +Nyxthara +Velastra +Phantomine +Eclipsine +Moonriven +Sablelune +Nostravelle +Lunareign +Thaluneth +Dream’s Hollow +Night’s Embrace +Umbraelle +Velnisse +Phantyra +Celuneth +Noctharra +Whisperveil +Moonraith +Lunaclaire +Velunith +Astrethra +Dreamrend +Nightborn +Selunara +Veythral +Nocthyra +Eclissara +Vairenne +Mournshade +Duskwraith +Velunethra +Umbrylisse +Phanthera +Noctelle +Moonweft +Somnithra +Lunysse +Nightcaller +Whisperthorn +Velastrae +Starveil +Lunavryn +Nytherelle +Moondrift +Velnarae +Umbrosyne +Selithra +Dreamveil Daughter +Nightwither +Nocturne’s Bloom +Virella +Lunacendreth +Phasmerra +Thalynne of the Eclipse +Shadowlight +Vesperyn +Lunaraith +Astrevelle +Noctura +Mournsong +Velunisse +Lunethra +Duskworn +Moon’s Memory +Nyxaelle +Somnielle +Umbrelith +Phantyssa +Dreamlorn +Noctvale +Lunathra +Veythrae +Starlorn diff --git a/modular_darkpack/modules/occult_artifacts/strings/vengeance_spirits.txt b/modular_darkpack/modules/occult_artifacts/strings/vengeance_spirits.txt new file mode 100644 index 000000000000..e287875d49cb --- /dev/null +++ b/modular_darkpack/modules/occult_artifacts/strings/vengeance_spirits.txt @@ -0,0 +1,121 @@ +Ashen Pact +Ashen Sovereign +Ashen Veil +Ashfall Covenant +Ashveil +Blood of the Forgotten +Bloodharrow +Bloodmourn +Bloodsong of the Lost +Crown of Ruin +Grave of the Faithless +Graveblight +Gravebloom +Gravetide +Harrowlight +Harrowmire +Hollowwind +Mournspire +Mournveil +Night of the Unmourned +Oathbreaker’s Dawn +Oathbreaker’s Rest +Oathfire +Oathless Dawn +Ruinveil +Ruin’s Choir +Ruin’s Embrace +Shadeborn +Storm Upon the Barrow +Storm of the Faithless +The Ashen Reign +The Ashen Revenant +The Banished King +The Banshee’s Gift +The Bitter End +The Bitter Promise +The Black Eulogy +The Black Lament +The Black Rebirth +The Black Sermon +The Bladed Choir +The Bleak Ascendant +The Bleeding Hunt +The Bleeding Moon +The Blight of Kings +The Bloodlit Exile +The Bone Lantern +The Bone Sunder +The Broken Host +The Broken Pyre +The Burning Quiet +The Cinder Choir +The Crimson Reproach +The Crimson Wake +The Crimson Weald +The Cursed Benediction +The Deathlight Covenant +The Dread Covenant +The Eclipsed Throne +The Endless Hunt +The Endless Woe +The Eternal Lament +The Final Benediction +The Forgotten Banquet +The Forgotten Legion +The Forgotten Warden +The Frosted Grin +The Frozen Hymn +The Gilded Scourge +The Gloomfeast +The Grave Hymnal +The Graven Host +The Graven Oath +The Hollow Feast +The Hollow Glory +The Hollow Monarch +The Hollow Vow +The Iron Dirge +The Iron Wail +The Last Benediction +The Last Oathkeeper +The Last Winter’s Oath +The Long Mourning +The Lost Crusade +The Mourner’s Wake +The Mourning Gale +The Mourning Throne +The Nameless Howl +The Nameless Rite +The Pale Confessor +The Pale Dominion +The Pale Dread +The Pale Maw +The Pale Reckoner +The Pale Reclaiming +The Pale Requiem +The Pale Resurgence +The Pale Supplicant +The Red Pilgrimage +The Sable Pilgrimage +The Shadow’s Debt +The Shadow’s Triumph +The Shattered Crown +The Shattered Hymn +The Silent Dominion +The Silent Herald +The Silent Hunt +The Silent Reckoning +The Sorrow’s Feast +The Waking Grief +The Weeping Hunt +The Whispered End +The Widow’s Cry +The Withered Hunt +The Withering Crown +The Wraith’s Vow +Thornwake +Vowrend +Whisper of the Gallows +Wraithbound +Wraithspire diff --git a/modular_darkpack/modules/paths/code/conjured_items.dm b/modular_darkpack/modules/paths/code/conjured_items.dm index f82620658754..7b3b937a13a7 100644 --- a/modular_darkpack/modules/paths/code/conjured_items.dm +++ b/modular_darkpack/modules/paths/code/conjured_items.dm @@ -54,7 +54,7 @@ desc = "Your hand burns with supernatural fire." icon_state = "flame" inhand_icon_state = "flame" - force = 25 + force = 15 fancy = FALSE // Levinbolt items @@ -63,7 +63,7 @@ desc = "Your arm surges with electricity!" icon_state = "illuminate" inhand_icon_state = "illuminate" - force = 15 + force = 10 light_range = 2 light_power = 1 light_color = COLOR_WHITE diff --git a/modular_darkpack/modules/paths/code/thaumaturgy_archives.dm b/modular_darkpack/modules/paths/code/thaumaturgy_archives.dm index 1f37c3cbb39a..21b820333996 100644 --- a/modular_darkpack/modules/paths/code/thaumaturgy_archives.dm +++ b/modular_darkpack/modules/paths/code/thaumaturgy_archives.dm @@ -19,20 +19,20 @@ // ARTIFACTS // Lower tier artifacts - new /datum/data/vending_product("Weekapaug Thistle", /obj/item/vtm_artifact/weekapaug_thistle, 75), - new /datum/data/vending_product("Mummywrap Fetish", /obj/item/vtm_artifact/mummywrap_fetish, 70), - new /datum/data/vending_product("Galdjum", /obj/item/vtm_artifact/galdjum, 70), - new /datum/data/vending_product("Bloodstar", /obj/item/vtm_artifact/bloodstar, 70), + new /datum/data/vending_product("Weekapaug Thistle", /obj/item/occult_artifact/vampire/weekapaug_thistle, 75), + new /datum/data/vending_product("Mummywrap Fetish", /obj/item/occult_artifact/vampire/mummywrap_fetish, 70), + new /datum/data/vending_product("Galdjum", /obj/item/occult_artifact/vampire/galdjum, 70), + new /datum/data/vending_product("Bloodstar", /obj/item/occult_artifact/vampire/bloodstar, 70), // Mid tier artifacts - new /datum/data/vending_product("Fae Charm", /obj/item/vtm_artifact/fae_charm, 120), - new /datum/data/vending_product("Daimonori", /obj/item/vtm_artifact/daimonori, 120), - new /datum/data/vending_product("Key of Alamut", /obj/item/vtm_artifact/key_of_alamut, 130), - new /datum/data/vending_product("Heart of Eliza", /obj/item/vtm_artifact/heart_of_eliza, 140), - new /datum/data/vending_product("Bloodstone", /obj/item/vtm_artifact/bloodstone, 140), + new /datum/data/vending_product("Fae Charm", /obj/item/occult_artifact/vampire/fae_charm, 120), + new /datum/data/vending_product("Daimonori", /obj/item/occult_artifact/vampire/daimonori, 120), + new /datum/data/vending_product("Key of Alamut", /obj/item/occult_artifact/vampire/key_of_alamut, 130), + new /datum/data/vending_product("Heart of Eliza", /obj/item/occult_artifact/vampire/heart_of_eliza, 140), + new /datum/data/vending_product("Bloodstone", /obj/item/occult_artifact/vampire/bloodstone, 140), // High tier artifacts - new /datum/data/vending_product("Odious Chalice", /obj/item/vtm_artifact/odious_chalice, 180), + new /datum/data/vending_product("Odious Chalice", /obj/item/occult_artifact/vampire/odious_chalice, 180), ) @@ -262,8 +262,8 @@ //offer artifacts to the shop for research points AND increment stock /obj/structure/retail/occult/item_interaction(mob/living/user, obj/item/tool, list/modifiers) . = ..() - if(istype(tool, /obj/item/vtm_artifact)) - var/obj/item/vtm_artifact/artifact = tool + if(istype(tool, /obj/item/occult_artifact)) + var/obj/item/occult_artifact/artifact = tool if(!ishuman(user)) return ITEM_INTERACT_BLOCKING diff --git a/modular_darkpack/modules/phones/code/_phone.dm b/modular_darkpack/modules/phones/code/_phone.dm index fe1eed23f6f6..0236e401d8cc 100644 --- a/modular_darkpack/modules/phones/code/_phone.dm +++ b/modular_darkpack/modules/phones/code/_phone.dm @@ -267,8 +267,8 @@ data["calling_user"] = get_number_contact_name() - data["time"] = station_time_timestamp("hh:mm") - data["date"] = station_time_timestamp("Day, Month DD, ") + "[CURRENT_STATION_YEAR]" + data["time"] = server_timestamp("hh:mm", ic_time = TRUE) + data["date"] = server_timestamp("Day, Month DD, YYYY", ic_time = TRUE) data["background_url"] = phone_background var/list/conversations_list = list() @@ -611,8 +611,8 @@ var/new_post = list( "body" = trim(body), - "date" = station_time_timestamp("Day, Month DD, ") + "[CURRENT_STATION_YEAR]", - "time" = station_time_timestamp("hh:mm"), + "date" = server_timestamp("Day, Month DD, YYYY", ic_time = TRUE), + "time" = server_timestamp("hh:mm", ic_time = TRUE), "author" = endpost_username ) diff --git a/modular_darkpack/modules/phones/code/phone_procs.dm b/modular_darkpack/modules/phones/code/phone_procs.dm index 1e1bd7d7f5f2..635c67e7df20 100644 --- a/modular_darkpack/modules/phones/code/phone_procs.dm +++ b/modular_darkpack/modules/phones/code/phone_procs.dm @@ -44,7 +44,7 @@ new_contact.number = dialed_number ? dialed_number : incoming_phone_number new_contact.call_type = call_type new_contact.call_type_tooltip = call_type_tooltip - new_contact.time = station_time_timestamp("hh:mm:ss") + new_contact.time = server_timestamp("hh:mm:ss", ic_time = TRUE) phone_history_list += new_contact /obj/item/smartphone/proc/set_phone_state(new_state) diff --git a/modular_darkpack/modules/phones/code/phone_subtypes.dm b/modular_darkpack/modules/phones/code/phone_subtypes.dm index f2ce4f31a3ab..88c6051078bf 100644 --- a/modular_darkpack/modules/phones/code/phone_subtypes.dm +++ b/modular_darkpack/modules/phones/code/phone_subtypes.dm @@ -229,6 +229,27 @@ alist(NETWORK_ID = ENDRON_NETWORK, OUR_ROLE = "Endron Employee", USE_JOB_TITLE = TRUE) ) +/obj/item/smartphone/novice + contact_networks_pre_init = list( + alist(NETWORK_ID = SOCIETY_OF_LEOPOLD_NETWORK, OUR_ROLE = "Novice", USE_JOB_TITLE = TRUE) + ) + +/obj/item/smartphone/condottieri + contact_networks_pre_init = list( + alist(NETWORK_ID = SOCIETY_OF_LEOPOLD_NETWORK, OUR_ROLE = "Condottieri", USE_JOB_TITLE = TRUE) + ) + +/obj/item/smartphone/inquisitor + contact_networks_pre_init = list( + alist(NETWORK_ID = SOCIETY_OF_LEOPOLD_NETWORK, OUR_ROLE = "Inquisitor", USE_JOB_TITLE = TRUE) + ) + +/obj/item/smartphone/abbe + contact_networks_pre_init = list( + alist(NETWORK_ID = SOCIETY_OF_LEOPOLD_NETWORK, OUR_ROLE = "Abbé", USE_JOB_TITLE = TRUE) + ) + + #undef NETWORK_ID #undef OUR_ROLE #undef USE_JOB_TITLE diff --git a/modular_darkpack/modules/phones/code/phone_texting.dm b/modular_darkpack/modules/phones/code/phone_texting.dm index 0e2ba2d41888..eba9c594ee42 100644 --- a/modular_darkpack/modules/phones/code/phone_texting.dm +++ b/modular_darkpack/modules/phones/code/phone_texting.dm @@ -12,8 +12,8 @@ src.number = number src.message_text = message_text src.is_outgoing = is_outgoing - src.timestamp = station_time() - src.time = station_time_timestamp("hh:mm") + src.timestamp = city_time() + src.time = server_timestamp("hh:mm", ic_time = TRUE) /datum/phone_conversation var/contact_name = "" diff --git a/modular_darkpack/modules/powers/code/discipline/__discipline_power.dm b/modular_darkpack/modules/powers/code/discipline/__discipline_power.dm index 4fb7bcb7b075..f750a363bcef 100644 --- a/modular_darkpack/modules/powers/code/discipline/__discipline_power.dm +++ b/modular_darkpack/modules/powers/code/discipline/__discipline_power.dm @@ -77,7 +77,6 @@ cooldown_timer = null QDEL_LIST(duration_timers) grouped_powers = null - discipline = null owner = null return ..() diff --git a/modular_darkpack/modules/powers/code/discipline/animalism.dm b/modular_darkpack/modules/powers/code/discipline/animalism.dm index 34d3e8605213..a018c19e8287 100644 --- a/modular_darkpack/modules/powers/code/discipline/animalism.dm +++ b/modular_darkpack/modules/powers/code/discipline/animalism.dm @@ -138,6 +138,7 @@ melee_damage_lower = 3 melee_damage_upper = 8 obj_damage = 10 + bloodpool = 2 /mob/living/basic/mouse/vampire/summoned/Initialize(mapload) AddElement(/datum/element/ai_retaliate) @@ -153,6 +154,7 @@ melee_damage_lower = 5 melee_damage_upper = 12 obj_damage = 15 + bloodpool = 2 /mob/living/basic/pet/cat/darkpack/summoned/Initialize(mapload) . = ..() @@ -176,6 +178,7 @@ attack_verb_simple = "bite" attack_sound = 'modular_darkpack/modules/deprecated/sounds/dog.ogg' random_wolf_color = FALSE + bloodpool = 2 /mob/living/basic/pet/dog/wolf/summoned/Initialize(mapload) . = ..() @@ -192,6 +195,7 @@ obj_damage = 10 attack_verb_continuous = "bites" attack_verb_simple = "bite" + bloodpool = 2 /mob/living/basic/bat/summoned/Initialize(mapload) . = ..() diff --git a/modular_darkpack/modules/powers/code/discipline/auspex/aura_component.dm b/modular_darkpack/modules/powers/code/discipline/auspex/aura_component.dm index 46becb5f60d8..4f71dab12c0f 100644 --- a/modular_darkpack/modules/powers/code/discipline/auspex/aura_component.dm +++ b/modular_darkpack/modules/powers/code/discipline/auspex/aura_component.dm @@ -295,6 +295,7 @@ hsv_color_value[2] = hsv_color_value[2] * 0.7 // Reduce saturation for ghouls aura_smoke_image.color = hsv2rgb(hsv_color_value) aura_classic_image.icon_state = "old_aura_ghoul" + aura_smoke_image.alpha = 50 if(isavatar(parent_mob) || isobserver(parent_mob)) holder.opacity = holder.opacity * 0.5 diff --git a/modular_darkpack/modules/powers/code/discipline/auspex/heartbeat_sensing_component.dm b/modular_darkpack/modules/powers/code/discipline/auspex/heartbeat_sensing_component.dm index f35a3be780ce..b9b83db738a8 100644 --- a/modular_darkpack/modules/powers/code/discipline/auspex/heartbeat_sensing_component.dm +++ b/modular_darkpack/modules/powers/code/discipline/auspex/heartbeat_sensing_component.dm @@ -44,7 +44,7 @@ receivers -= list(echolocate_receiver) return ..() -/datum/component/heartbeat_sensing/process() +/datum/component/heartbeat_sensing/process(seconds_per_tick) var/mob/living/parent_mob = parent if(parent_mob.stat == DEAD) return diff --git a/modular_darkpack/modules/powers/code/discipline/daimonion/daimonion_hallucination.dm b/modular_darkpack/modules/powers/code/discipline/daimonion/daimonion_hallucination.dm index 60f787b29e3d..129ad9a7fe3d 100644 --- a/modular_darkpack/modules/powers/code/discipline/daimonion/daimonion_hallucination.dm +++ b/modular_darkpack/modules/powers/code/discipline/daimonion/daimonion_hallucination.dm @@ -23,7 +23,7 @@ target = null return ..() -/obj/effect/client_image_holder/baali_demon/process() +/obj/effect/client_image_holder/baali_demon/process(seconds_per_tick) if(QDELETED(target) || target.stat == DEAD) qdel(src) return diff --git a/modular_darkpack/modules/powers/code/discipline/obtenebration/obtenebration.dm b/modular_darkpack/modules/powers/code/discipline/obtenebration/obtenebration.dm index 28a51d6ccd0a..f08828f82ca8 100644 --- a/modular_darkpack/modules/powers/code/discipline/obtenebration/obtenebration.dm +++ b/modular_darkpack/modules/powers/code/discipline/obtenebration/obtenebration.dm @@ -119,6 +119,7 @@ cooldown_length = 1 TURNS var/list/active_tentacles = list() + var/aggro_mode = "Aggressive" /datum/discipline_power/obtenebration/arms_of_the_abyss/activate(atom/target) . = ..() @@ -137,7 +138,7 @@ var/has_action = !!(locate(/datum/action/aggro_mode) in owner.actions) if(!has_action) - var/datum/action/aggro_mode/A = new() + var/datum/action/aggro_mode/A = new(src) A.Grant(owner) // Create tentacles based on successes @@ -155,8 +156,9 @@ if(open_turfs.len) new_tentacle = new /mob/living/basic/abyss_tentacle(pick(open_turfs), owner) - // if we ended up making a new tentacle add it to our list + // if we ended up making a new tentacle add it to our list and inherit set aggro_mode if(new_tentacle) + new_tentacle.aggro_mode = aggro_mode active_tentacles += new_tentacle else to_chat(usr, span_warning("The area is too bright for the shadows to manifest!")) @@ -318,6 +320,12 @@ button_icon = 'icons/hud/screen_glass.dmi' button_icon_state = "harm" var/current_mode = "Aggressive" + var/datum/discipline_power/obtenebration/arms_of_the_abyss/abyss_power + +/datum/action/aggro_mode/New(Target) + . = ..() + abyss_power = Target + current_mode = abyss_power.aggro_mode /datum/action/aggro_mode/Trigger(mob/clicker, trigger_flags) . = ..() @@ -341,13 +349,10 @@ var/select = tgui_input_list(tentacle_owner, "Select tentacle behaviour", "Tentacle Mode", options) if(!select || !tentacle_owner) return - + if(!abyss_power) + return + abyss_power.aggro_mode = select current_mode = select - tentacle_owner.tentacle_aggro_mode = select - - // need to access the discipline_power so we can grab the list - var/datum/splat/vampire/vampire = get_splat_with_discipline(tentacle_owner) - var/datum/discipline_power/obtenebration/arms_of_the_abyss/abyss_power = vampire?.get_discipline_power(/datum/discipline_power/obtenebration/arms_of_the_abyss) var/tentacles = 0 for(var/mob/living/basic/abyss_tentacle/T in abyss_power?.active_tentacles) diff --git a/modular_darkpack/modules/powers/code/discipline/potence/potence.dm b/modular_darkpack/modules/powers/code/discipline/potence/potence.dm index 28b85b44c42d..11e318c84ce1 100644 --- a/modular_darkpack/modules/powers/code/discipline/potence/potence.dm +++ b/modular_darkpack/modules/powers/code/discipline/potence/potence.dm @@ -7,10 +7,35 @@ /datum/discipline_power/potence name = "Potence power name" desc = "Potence power description" + abstract_type = /datum/discipline_power/potence activate_sound = 'modular_darkpack/modules/powers/sounds/potence_activate.ogg' deactivate_sound = 'modular_darkpack/modules/powers/sounds/potence_deactivate.ogg' + check_flags = DISC_CHECK_CAPABLE + + toggled = TRUE + duration_length = 1 TURNS + +/datum/discipline_power/potence/post_gain() + owner.st_add_stat_mod(STAT_STRENGTH, level, "Potence") + +/datum/discipline_power/potence/post_loss() + owner.st_remove_stat_mod(STAT_STRENGTH, "Potence") + +/datum/discipline_power/potence/activate() + . = ..() + + if(level <= 5) + var/max_level = min(discipline.level, 5) + owner.apply_status_effect(/datum/status_effect/potence, max_level) + +/datum/discipline_power/potence/deactivate() + . = ..() + if(level <= 5) + owner.remove_status_effect(/datum/status_effect/potence) + + //POTENCE 1 /datum/discipline_power/potence/one name = "Potence 1" @@ -18,11 +43,6 @@ level = 1 - check_flags = DISC_CHECK_CAPABLE - - toggled = TRUE - duration_length = 2 TURNS - grouped_powers = list( /datum/discipline_power/potence/two, /datum/discipline_power/potence/three, @@ -30,18 +50,6 @@ /datum/discipline_power/potence/five ) -/datum/discipline_power/potence/one/activate() - . = ..() - - owner.apply_status_effect(/datum/status_effect/potence/one) - -/datum/discipline_power/potence/one/deactivate() - . = ..() - - owner.remove_status_effect(/datum/status_effect/potence/one) - -/datum/discipline_power/potence/one/post_gain() - owner.st_add_stat_mod(STAT_STRENGTH, 1, "Potence") //POTENCE 2 /datum/discipline_power/potence/two @@ -50,11 +58,6 @@ level = 2 - check_flags = DISC_CHECK_CAPABLE - - toggled = TRUE - duration_length = 2 TURNS - grouped_powers = list( /datum/discipline_power/potence/one, /datum/discipline_power/potence/three, @@ -62,16 +65,6 @@ /datum/discipline_power/potence/five ) -/datum/discipline_power/potence/two/activate() - . = ..() - owner.apply_status_effect(/datum/status_effect/potence/two) - -/datum/discipline_power/potence/two/deactivate() - . = ..() - owner.remove_status_effect(/datum/status_effect/potence/two) - -/datum/discipline_power/potence/two/post_gain() - owner.st_add_stat_mod(STAT_STRENGTH, 2, "Potence") //POTENCE 3 /datum/discipline_power/potence/three @@ -80,11 +73,6 @@ level = 3 - check_flags = DISC_CHECK_CAPABLE - - toggled = TRUE - duration_length = 2 TURNS - grouped_powers = list( /datum/discipline_power/potence/one, /datum/discipline_power/potence/two, @@ -92,16 +80,6 @@ /datum/discipline_power/potence/five ) -/datum/discipline_power/potence/three/activate() - . = ..() - owner.apply_status_effect(/datum/status_effect/potence/three) - -/datum/discipline_power/potence/three/deactivate() - . = ..() - owner.remove_status_effect(/datum/status_effect/potence/three) - -/datum/discipline_power/potence/three/post_gain() - owner.st_add_stat_mod(STAT_STRENGTH, 3, "Potence") //POTENCE 4 /datum/discipline_power/potence/four @@ -110,11 +88,6 @@ level = 4 - check_flags = DISC_CHECK_CAPABLE - - toggled = TRUE - duration_length = 2 TURNS - grouped_powers = list( /datum/discipline_power/potence/one, /datum/discipline_power/potence/two, @@ -122,16 +95,6 @@ /datum/discipline_power/potence/five ) -/datum/discipline_power/potence/four/activate() - . = ..() - owner.apply_status_effect(/datum/status_effect/potence/four) - -/datum/discipline_power/potence/four/deactivate() - . = ..() - owner.remove_status_effect(/datum/status_effect/potence/four) - -/datum/discipline_power/potence/four/post_gain() - owner.st_add_stat_mod(STAT_STRENGTH, 4, "Potence") //POTENCE 5 /datum/discipline_power/potence/five @@ -140,25 +103,9 @@ level = 5 - check_flags = DISC_CHECK_CAPABLE - - toggled = TRUE - duration_length = 2 TURNS - grouped_powers = list( /datum/discipline_power/potence/one, /datum/discipline_power/potence/two, /datum/discipline_power/potence/three, /datum/discipline_power/potence/four ) - -/datum/discipline_power/potence/five/activate() - . = ..() - owner.apply_status_effect(/datum/status_effect/potence/five) - -/datum/discipline_power/potence/five/deactivate() - . = ..() - owner.remove_status_effect(/datum/status_effect/potence/five) - -/datum/discipline_power/potence/five/post_gain() - owner.st_add_stat_mod(STAT_STRENGTH, 5, "Potence") diff --git a/modular_darkpack/modules/powers/code/discipline/potence/potence_status_effect.dm b/modular_darkpack/modules/powers/code/discipline/potence/potence_status_effect.dm index 8037974b58ff..6b8e073a45ef 100644 --- a/modular_darkpack/modules/powers/code/discipline/potence/potence_status_effect.dm +++ b/modular_darkpack/modules/powers/code/discipline/potence/potence_status_effect.dm @@ -3,15 +3,22 @@ status_type = STATUS_EFFECT_REPLACE alert_type = null - var/level + var/level = 1 var/datum/component/tackler/tackler var/list/obj/item/bodypart/affected_bodyparts +/datum/status_effect/potence/on_creation(mob/living/new_owner, level) + src.level = level + . = ..() + /datum/status_effect/potence/on_apply() . = ..() if (!.) return + owner.st_remove_stat_mod(STAT_STRENGTH, "Potence") + owner.st_add_auto_successes(STAT_STRENGTH, level, "Potence") + if (iscarbon(owner)) var/mob/living/carbon/carbon_owner = owner for (var/obj/item/bodypart/limb as anything in carbon_owner.bodyparts) @@ -19,15 +26,9 @@ continue LAZYADD(affected_bodyparts, limb) - - limb.unarmed_damage_low += 8 * level - limb.unarmed_damage_high += 8 * level limb.unarmed_attack_sound = 'modular_darkpack/modules/powers/sounds/heavypunch.ogg' else if (isbasicmob(owner)) var/mob/living/basic/basic_owner = owner - - basic_owner.melee_damage_lower += 8 * level - basic_owner.melee_damage_upper += 8 * level basic_owner.attack_sound = 'modular_darkpack/modules/powers/sounds/heavypunch.ogg' RegisterSignal(owner, COMSIG_MOB_ITEM_ATTACK, PROC_REF(apply_melee_modifier)) @@ -37,16 +38,14 @@ /datum/status_effect/potence/on_remove() . = ..() + owner.st_remove_auto_successes(STAT_STRENGTH, "Potence") + owner.st_add_stat_mod(STAT_STRENGTH, level, "Potence") + if (iscarbon(owner)) for (var/obj/item/bodypart/limb in affected_bodyparts) - limb.unarmed_damage_low -= 8 * level - limb.unarmed_damage_high -= 8 * level limb.unarmed_attack_sound = initial(limb.unarmed_attack_sound) else if (isbasicmob(owner)) var/mob/living/basic/basic_owner = owner - - basic_owner.melee_damage_lower -= 8 * level - basic_owner.melee_damage_upper -= 8 * level basic_owner.attack_sound = initial(basic_owner.attack_sound) LAZYCLEARLIST(affected_bodyparts) @@ -55,23 +54,7 @@ qdel(tackler) +// This is bad and bypasses it being a strength dice thing. Remove the second melee has any usage of strength for damage /datum/status_effect/potence/proc/apply_melee_modifier(mob/source, mob/M, mob/user, list/modifiers, list/attack_modifiers) SIGNAL_HANDLER - - attack_modifiers[FORCE_MULTIPLIER] += 0.4 * level - -// Status effect ranks -/datum/status_effect/potence/one - level = 1 - -/datum/status_effect/potence/two - level = 2 - -/datum/status_effect/potence/three - level = 3 - -/datum/status_effect/potence/four - level = 4 - -/datum/status_effect/potence/five - level = 5 + MODIFY_ATTACK_FORCE_MULTIPLIER(attack_modifiers, 1 + (0.4 * level)) diff --git a/modular_darkpack/modules/powers/code/discipline/protean/beast_form.dm b/modular_darkpack/modules/powers/code/discipline/protean/beast_form.dm index c691fce46dce..df92bd580470 100644 --- a/modular_darkpack/modules/powers/code/discipline/protean/beast_form.dm +++ b/modular_darkpack/modules/powers/code/discipline/protean/beast_form.dm @@ -55,7 +55,7 @@ icon_state = "gangrel_f" icon_living = "gangrel_f" mob_biotypes = MOB_ORGANIC|MOB_HUMANOID - mob_size = MOB_SIZE_HUGE + mob_size = MOB_SIZE_LARGE speed = -0.4 maxHealth = 275 health = 275 diff --git a/modular_darkpack/modules/powers/code/discipline/temporis/temporis.dm b/modular_darkpack/modules/powers/code/discipline/temporis/temporis.dm index 50e3be6470a5..015d780c0978 100644 --- a/modular_darkpack/modules/powers/code/discipline/temporis/temporis.dm +++ b/modular_darkpack/modules/powers/code/discipline/temporis/temporis.dm @@ -42,7 +42,7 @@ /datum/discipline_power/temporis/hourglass_of_the_mind/activate() . = ..() - to_chat(owner, "[station_time_timestamp("hh:mm:ss")]") + to_chat(owner, "[server_timestamp("hh:mm:ss", ic_time = TRUE, twelve_hour_clock = owner.client?.prefs.read_preference(/datum/preference/toggle/twelve_hour))]") // Check range for targets with that have warped time this round and display them, if any exist var/list/targets = list() diff --git a/modular_darkpack/modules/powers/code/discipline/thaumaturgy/path_of_blood.dm b/modular_darkpack/modules/powers/code/discipline/thaumaturgy/path_of_blood.dm index 90c78bcc3fc7..57439072b188 100644 --- a/modular_darkpack/modules/powers/code/discipline/thaumaturgy/path_of_blood.dm +++ b/modular_darkpack/modules/powers/code/discipline/thaumaturgy/path_of_blood.dm @@ -239,7 +239,7 @@ level = 4 - vitae_cost = 0 //Since 1 success should give one vitae, balancing. + vitae_cost = 1 effect_sound = 'sound/effects/magic/enter_blood.ogg' range = 8 // Within 50 feet (15 meters). check_flags = DISC_CHECK_CONSCIOUS | DISC_CHECK_CAPABLE | DISC_CHECK_TORPORED | DISC_CHECK_SEE | DISC_CHECK_DIRECT_SEE // The subject must be visible to the thaumaturge @@ -267,6 +267,8 @@ var/blood_gained = blood_taken * max(1, target.bloodquality-1) owner.adjust_blood_pool(blood_gained) else + if(!target.bloodpool || !target.blood_volume) + return var/blood_coefficient = (5 / target.bloodpool) // DARKPACK TODO - reimplement quirks -- potent blood /* @@ -277,6 +279,7 @@ target.blood_volume = max (0, (target.blood_volume - (blood_taken * (70*blood_coefficient)))) var/blood_gained = blood_taken * max(1, target.bloodquality - 1) + target.adjust_blood_pool(-blood_gained) owner.adjust_blood_pool(blood_gained) //------------------------------------------------------------------------------------------------ @@ -287,7 +290,7 @@ desc = "Boil your target's blood in their body, killing almost anyone." level = 5 - range = 1 //The Kindred must touch the subject + range = 1 check_flags = DISC_CHECK_FREE_HAND | DISC_CHECK_CONSCIOUS | DISC_CHECK_CAPABLE | DISC_CHECK_TORPORED target_type = TARGET_MOB | TARGET_SELF aggravating = TRUE diff --git a/modular_darkpack/modules/powers/code/discipline/thaumaturgy/paths/levinbolt.dm b/modular_darkpack/modules/powers/code/discipline/thaumaturgy/paths/levinbolt.dm index aef105534047..07ecc504117b 100644 --- a/modular_darkpack/modules/powers/code/discipline/thaumaturgy/paths/levinbolt.dm +++ b/modular_darkpack/modules/powers/code/discipline/thaumaturgy/paths/levinbolt.dm @@ -106,8 +106,8 @@ var/obj/fusebox/fuse = target // Break the fusebox - fuse.damaged += 101 - fuse.check_damage(owner, TRUE) + fuse.take_damage(101) + fuse.power_off() var/datum/effect_system/basic/spark_spread/spark_system = new(get_turf(target), 5, 1) spark_system.start() diff --git a/modular_darkpack/modules/powers/code/discipline/valeren.dm b/modular_darkpack/modules/powers/code/discipline/valeren.dm index 16765801fbcf..239c3a7e2553 100644 --- a/modular_darkpack/modules/powers/code/discipline/valeren.dm +++ b/modular_darkpack/modules/powers/code/discipline/valeren.dm @@ -472,13 +472,9 @@ if (!istype(limb, /obj/item/bodypart/arm) && !istype(limb, /obj/item/bodypart/leg)) continue LAZYADD(affected_bodyparts, limb) - limb.unarmed_damage_low += 8 * bonus - limb.unarmed_damage_high += 8 * bonus limb.unarmed_attack_sound = pick(list('sound/items/weapons/cqchit2.ogg', 'sound/items/weapons/cqchit1.ogg')) // i know kung fu else if (isbasicmob(owner)) var/mob/living/basic/basic_owner = owner - basic_owner.melee_damage_lower += 8 * bonus - basic_owner.melee_damage_upper += 8 * bonus basic_owner.attack_sound = pick(list('sound/items/weapons/cqchit2.ogg', 'sound/items/weapons/cqchit1.ogg')) RegisterSignal(owner, COMSIG_MOB_ITEM_ATTACK, PROC_REF(apply_melee_modifier)) tackler = owner.AddComponent(/datum/component/tackler, stamina_cost=0, base_knockdown = 1 SECONDS, range = 2 + bonus, speed = 1, skill_mod = 0, min_distance = 0) @@ -490,13 +486,9 @@ owner.st_remove_stat_mod(STAT_BRAWL, bonus, "vengeance_of_samiel") if (iscarbon(owner)) for (var/obj/item/bodypart/limb in affected_bodyparts) - limb.unarmed_damage_low -= 8 * bonus - limb.unarmed_damage_high -= 8 * bonus limb.unarmed_attack_sound = initial(limb.unarmed_attack_sound) else if (isbasicmob(owner)) var/mob/living/basic/basic_owner = owner - basic_owner.melee_damage_lower -= 8 * bonus - basic_owner.melee_damage_upper -= 8 * bonus basic_owner.attack_sound = initial(basic_owner.attack_sound) LAZYCLEARLIST(affected_bodyparts) UnregisterSignal(owner, COMSIG_MOB_ITEM_ATTACK) @@ -504,4 +496,4 @@ /datum/status_effect/vengeance_of_samiel/proc/apply_melee_modifier(mob/source, mob/M, mob/user, list/modifiers, list/attack_modifiers) SIGNAL_HANDLER - attack_modifiers[FORCE_MULTIPLIER] += 0.4 * bonus + MODIFY_ATTACK_FORCE_MULTIPLIER(attack_modifiers, 1 + (0.4 * bonus)) diff --git a/modular_darkpack/modules/powers/code/discipline_actions.dm b/modular_darkpack/modules/powers/code/discipline_actions.dm index bfa304a34d44..4e6d0af95f42 100644 --- a/modular_darkpack/modules/powers/code/discipline_actions.dm +++ b/modular_darkpack/modules/powers/code/discipline_actions.dm @@ -26,6 +26,10 @@ register_to_availability_signals() +/datum/action/discipline/Destroy() + QDEL_NULL(discipline) + return ..() + /datum/action/discipline/Remove(mob/owner) if(discipline) discipline.post_loss() @@ -49,7 +53,6 @@ SIGNAL_ADDTRAIT(TRAIT_PACIFISM), SIGNAL_REMOVETRAIT(TRAIT_PACIFISM), )) - QDEL_NULL(discipline) return ..() /datum/action/discipline/proc/register_to_availability_signals() diff --git a/modular_darkpack/modules/powers/code/discipline_pref_middleware.dm b/modular_darkpack/modules/powers/code/discipline_pref_middleware.dm index c883d7aff07e..c6359f727e9e 100644 --- a/modular_darkpack/modules/powers/code/discipline_pref_middleware.dm +++ b/modular_darkpack/modules/powers/code/discipline_pref_middleware.dm @@ -299,7 +299,7 @@ var/global/list/RARE_DISCIPLINE_TYPES = list( var/discipline = text2path(disc_path) if(!discipline) continue - var/level = discipline_levels[disc_path] + var/level = character.get_splat(/datum/splat/vampire/ghoul) ? 1 : discipline_levels[disc_path] if(!level) continue // prevent removing the disc by stopping here if they put 0 in it var/result = character.change_st_power_level(discipline, level) diff --git a/modular_darkpack/modules/ritual_abyss_mysticism/code/rituals/artifact_identification.dm b/modular_darkpack/modules/ritual_abyss_mysticism/code/rituals/artifact_identification.dm index 3ff4daf4eb1f..5b49f112cc7b 100644 --- a/modular_darkpack/modules/ritual_abyss_mysticism/code/rituals/artifact_identification.dm +++ b/modular_darkpack/modules/ritual_abyss_mysticism/code/rituals/artifact_identification.dm @@ -7,7 +7,11 @@ /obj/ritual_rune/abyss/identification/complete() . = ..() - for(var/obj/item/vtm_artifact/VA in loc) + for(var/obj/item/occult_artifact/VA in loc) + var/mob/living/carbon/human/identifier = usr + if(VA.identified) + to_chat(identifier, span_warning("You have already identified this artifact.")) + return VA.identify() qdel(src) return diff --git a/modular_darkpack/modules/ritual_thaumaturgy/rituals/artifact_identification.dm b/modular_darkpack/modules/ritual_thaumaturgy/rituals/artifact_identification.dm index 1c67a109fd28..6bb2a7190a5c 100644 --- a/modular_darkpack/modules/ritual_thaumaturgy/rituals/artifact_identification.dm +++ b/modular_darkpack/modules/ritual_thaumaturgy/rituals/artifact_identification.dm @@ -6,7 +6,7 @@ /obj/ritual_rune/thaumaturgy/identification/complete() . = ..() - for(var/obj/item/vtm_artifact/VA in loc) + for(var/obj/item/occult_artifact/VA in loc) var/mob/living/carbon/human/identifier = usr if(VA.identified) to_chat(identifier, span_warning("You have already identified this artifact.")) diff --git a/modular_darkpack/modules/ritual_thaumaturgy/rituals/chime_of_the_unseen_spirits.dm b/modular_darkpack/modules/ritual_thaumaturgy/rituals/chime_of_the_unseen_spirits.dm index ab7ceaa873fe..121128d171d5 100644 --- a/modular_darkpack/modules/ritual_thaumaturgy/rituals/chime_of_the_unseen_spirits.dm +++ b/modular_darkpack/modules/ritual_thaumaturgy/rituals/chime_of_the_unseen_spirits.dm @@ -89,7 +89,7 @@ STOP_PROCESSING(SSprocessing, src) return ..() -/obj/item/spirit_chime/process(delta_time) +/obj/item/spirit_chime/process(seconds_per_tick) var/valid_targets = FALSE if(!ringing || !anchored || !chime_field) ringing = FALSE diff --git a/modular_darkpack/modules/storyteller_dice/code/roll_datum.dm b/modular_darkpack/modules/storyteller_dice/code/roll_datum.dm index 1bbba5980296..0fabf7e4701e 100644 --- a/modular_darkpack/modules/storyteller_dice/code/roll_datum.dm +++ b/modular_darkpack/modules/storyteller_dice/code/roll_datum.dm @@ -48,11 +48,15 @@ return ROLL_FAILURE var/dice_amount = calculate_used_dice(roller, bonus) + var/auto_success_amount = calculate_auto_successes(roller) var/used_difficulty = calculate_used_difficulty(roller) - var/list/rolled_dice = roll_dice(dice_amount) + var/list/rolled_dice = roll_dice(dice_amount, auto_success_amount) - var/first_line = "[span_tooltip(show_rolling_with(roller, bonus), "[dice_amount] dice")] vs. difficulty [used_difficulty]." + var/dice_used_text = "[dice_amount] dice" + if(auto_success_amount) + dice_used_text += " + [auto_success_amount] auto successes" + var/first_line = "[span_tooltip(show_rolling_with(roller, bonus), dice_used_text)] vs. difficulty [used_difficulty]." if(successes_needed > 1) first_line += " [successes_needed] successes needed." last_output_text += span_notice(first_line) @@ -109,9 +113,16 @@ /datum/storyteller_roll/proc/calculate_used_dice(mob/living/roller, bonus = 0) var/dice_amount = 0 for(var/stat_type in using_stats(roller)) - dice_amount += roller.st_get_stat(stat_type) + dice_amount += roller.st_get_stat(stat_type, include_auto_successes = FALSE) return dice_amount + bonus +/datum/storyteller_roll/proc/calculate_auto_successes(mob/living/roller) + var/dice_amount = 0 + for(var/stat_type in using_stats(roller)) + var/datum/st_stat/given_stat = roller?.storyteller_stats[stat_type] + dice_amount += given_stat?.get_auto_success_score() + return dice_amount + // Unused rn but can be used for overides of `using_stats()` /datum/storyteller_roll/proc/return_higher_stat(mob/living/roller, list/stats) var/stat_to_use @@ -139,7 +150,7 @@ output += "+[bonus]" return "Rolling [output]" -/datum/storyteller_roll/proc/roll_dice(dice, sides = 10) +/datum/storyteller_roll/proc/roll_dice(dice, auto_successes, sides = 10) dice = max(dice, 1) var/list/rolled_dice = list() for(var/i in 1 to dice) @@ -151,6 +162,8 @@ extra_dice++ for(var/i in 1 to extra_dice) rolled_dice += rand(1, sides) + for(var/i in 1 to auto_successes) + rolled_dice += 11 return rolled_dice //Count the number of successes. @@ -168,7 +181,7 @@ sucess_amount-- else dice_text += span_danger("[get_dice_char(roll)]") - last_output_text += "[roll_result_text(roll_result(sucess_amount))] [dice_text]" + last_output_text += "[roll_result_text(roll_result(sucess_amount))] [span_slightly_larger(dice_text)]" return sucess_amount /datum/storyteller_roll/proc/roll_result(sucess_amount) @@ -195,7 +208,8 @@ return span_bold(span_danger(("Botch -"))) /datum/storyteller_roll/proc/get_dice_char(input) - var/static/list/dice_output = list("❶", "❷", "❸", "❹", "❺", "❻", "❼", "❽", "❾", "❿") + // "11" represents automatic successes + var/static/list/dice_output = list("❶", "❷", "❸", "❹", "❺", "❻", "❼", "❽", "❾", "❿", "☥") return dice_output[input] /* // This would require making it an assoc list and we dont every expect outside our given range. // So if someone faces a runtime because of this just make it an actual assoc and deal with the micro preformace hit diff --git a/modular_darkpack/modules/storyteller_dice/code/roll_subtypes.dm b/modular_darkpack/modules/storyteller_dice/code/roll_subtypes.dm index 0840a1409cd3..1f94e682f3f5 100644 --- a/modular_darkpack/modules/storyteller_dice/code/roll_subtypes.dm +++ b/modular_darkpack/modules/storyteller_dice/code/roll_subtypes.dm @@ -117,3 +117,4 @@ bumper_text = "identify" applicable_stats = list(STAT_INTELLIGENCE, STAT_OCCULT) reroll_cooldown = 1 SCENES + difficulty = 8 diff --git a/modular_darkpack/modules/storyteller_stats/code/_st_stats.dm b/modular_darkpack/modules/storyteller_stats/code/_st_stats.dm index 9d220703ca84..b7cd90e076fa 100644 --- a/modular_darkpack/modules/storyteller_stats/code/_st_stats.dm +++ b/modular_darkpack/modules/storyteller_stats/code/_st_stats.dm @@ -13,6 +13,8 @@ VAR_PROTECTED/score = 0 /// Temporary bonus score applied to this stat from various ingame sources. VAR_PROTECTED/bonus_score = 0 + /// Temporary bonus score applied to this stat from various ingame sources. These are directly added to results rather then added to dice pool + VAR_PROTECTED/auto_success_score = 0 /// The minimum score this stat can be. var/min_score = 0 /// The maximum score this stat can be. @@ -26,6 +28,8 @@ var/editable = TRUE /// A dictionary of modifiers to this attribute. var/list/modifiers = list() + /// A dictionary of auto success scores to this attribute. + var/list/auto_successes = list() /// What score does this stat start out with at character creation. var/starting_score = 0 /// How many points are in this stat category that the player can use. Used in abstract classes only. @@ -35,10 +39,13 @@ // Score -/datum/st_stat/proc/get_score(include_bonus = TRUE) +/datum/st_stat/proc/get_score(include_bonus = TRUE, include_auto_sucesses = TRUE) SHOULD_NOT_OVERRIDE(TRUE) if(include_bonus) - return score + bonus_score + if(include_auto_sucesses) + return score + bonus_score + auto_success_score + else + return score + bonus_score else return score @@ -46,6 +53,10 @@ SHOULD_NOT_OVERRIDE(TRUE) return bonus_score +/datum/st_stat/proc/get_auto_success_score() + SHOULD_NOT_OVERRIDE(TRUE) + return auto_success_score + /datum/st_stat/proc/can_set_score(amount) SHOULD_NOT_OVERRIDE(TRUE) if((amount < min_score) || (amount > max_score)) @@ -108,6 +119,24 @@ bonus_score += modifiers[source] bonus_score = clamp(bonus_score, -max_score, 10) + +/datum/st_stat/proc/add_auto_successes(amount, source) + SHOULD_NOT_OVERRIDE(TRUE) + LAZYSET(auto_successes, source, amount) + update_auto_successes() + +/datum/st_stat/proc/remove_auto_successes(source) + SHOULD_NOT_OVERRIDE(TRUE) + LAZYREMOVE(auto_successes, source) + update_auto_successes() + +/datum/st_stat/proc/update_auto_successes() + SHOULD_NOT_OVERRIDE(TRUE) + auto_success_score = initial(auto_success_score) + for(var/source in auto_successes) + auto_success_score += auto_successes[source] + auto_success_score = clamp(auto_success_score, 0, 10) + // Points /datum/st_stat/proc/get_points() diff --git a/modular_darkpack/modules/storyteller_stats/code/mob_affecting_adjustments/mob_procs.dm b/modular_darkpack/modules/storyteller_stats/code/mob_affecting_adjustments/mob_procs.dm index fcafd17fa869..4f7ff1e5b93e 100644 --- a/modular_darkpack/modules/storyteller_stats/code/mob_affecting_adjustments/mob_procs.dm +++ b/modular_darkpack/modules/storyteller_stats/code/mob_affecting_adjustments/mob_procs.dm @@ -1,14 +1,14 @@ /// Get a specific mob's stat from its stats list. -/mob/living/proc/st_get_stat(stat_path, include_bonus) +/mob/living/proc/st_get_stat(stat_path, include_bonus, include_auto_successes) var/datum/st_stat/given_stat = storyteller_stats[stat_path] - return given_stat?.get_score(include_bonus) + return given_stat?.get_score(include_bonus, include_auto_successes) /// Wrapper for st_get_stat to reduce copypaste. Get a specific mob's stat from its stats list. -/mob/living/proc/st_get_stats(list/stat_list, include_bonus) +/mob/living/proc/st_get_stats(list/stat_list, include_bonus, include_auto_successes) var/total_score = 0 for(var/stat_path in stat_list) var/datum/st_stat/given_stat = storyteller_stats[stat_path] - total_score += given_stat?.get_score(include_bonus) + total_score += given_stat?.get_score(include_bonus, include_auto_successes) return total_score /// Set a specific mob's stat from its stats list. @@ -42,6 +42,19 @@ return score +/mob/living/proc/st_add_auto_successes(stat_path, amount, source) + var/datum/st_stat/given_stat = storyteller_stats[stat_path] + var/score = given_stat?.add_auto_successes(amount, source) + update_modifiers_from_stats() + return score + +/mob/living/proc/st_remove_auto_successes(stat_path, source) + var/datum/st_stat/given_stat = storyteller_stats[stat_path] + var/score = given_stat?.remove_auto_successes(source) + update_modifiers_from_stats() + return score + + /mob/living/proc/update_modifiers_from_stats(initial = FALSE) for(var/stat_typepath in storyteller_stats) var/datum/st_stat/stat_datum = storyteller_stats[stat_typepath] diff --git a/modular_darkpack/modules/vampire_the_masquerade/code/splats/ghoul_splat/ghoul_splat.dm b/modular_darkpack/modules/vampire_the_masquerade/code/splats/ghoul_splat/ghoul_splat.dm index 8f4f711b17ad..e1662ce508e1 100644 --- a/modular_darkpack/modules/vampire_the_masquerade/code/splats/ghoul_splat/ghoul_splat.dm +++ b/modular_darkpack/modules/vampire_the_masquerade/code/splats/ghoul_splat/ghoul_splat.dm @@ -25,6 +25,7 @@ /datum/splat/vampire/ghoul/on_gain() owner.give_st_power(/datum/discipline/bloodheal, 1) + owner.give_st_power(/datum/discipline/potence, 1) // the below only runs if they have just been ghouled and domitor isnt null // ghouls who join from the menu have their discs handled by the disc pref middleware @@ -37,3 +38,7 @@ owner.give_st_power(discipline, 1) if(ispath(discipline, /datum/discipline/dementation)) owner.add_quirk(/datum/quirk/darkpack/derangement) + +/datum/splat/vampire/ghoul/on_lose_or_destroy() + owner.remove_st_power(/datum/discipline/bloodheal) + owner.remove_st_power(/datum/discipline/potence) diff --git a/modular_darkpack/modules/walls/code/floors/water.dm b/modular_darkpack/modules/walls/code/floors/water.dm index baec80ea8191..071baae6b100 100644 --- a/modular_darkpack/modules/walls/code/floors/water.dm +++ b/modular_darkpack/modules/walls/code/floors/water.dm @@ -78,7 +78,7 @@ SSsupermatter_cascade.can_fire = TRUE SSsupermatter_cascade.cascade_initiated = TRUE -/turf/open/water/bloodwave/process() +/turf/open/water/bloodwave/process(seconds_per_tick) if(!COOLDOWN_FINISHED(src, wave_cooldown)) return diff --git a/modular_darkpack/modules/werewolf_the_apocalypse/code/delirium.dm b/modular_darkpack/modules/werewolf_the_apocalypse/code/delirium.dm new file mode 100644 index 000000000000..21cc0c806757 --- /dev/null +++ b/modular_darkpack/modules/werewolf_the_apocalypse/code/delirium.dm @@ -0,0 +1,130 @@ +/datum/status_effect/delirium + id = "delirium" + status_type = STATUS_EFFECT_REFRESH + duration = 10 SECONDS + alert_type = /atom/movable/screen/alert/status_effect/delirium + COOLDOWN_DECLARE(message_cooldown) + var/static/list/willpower_levels = list( + "catatonic fear", + "panic", + "disbelief", + "beserk", + "terror", + "conciliatory", + "controlled fear", + "curiosity", + "bloodlust", + "no reaction" + ) + var/willpower_dots = 1 + var/datum/weakref/scary_wolf_ref + var/image/scary_static + +/datum/status_effect/delirium/on_creation(mob/living/new_owner, mob/big_wolf) + scary_wolf_ref = WEAKREF(big_wolf) + . = ..() + linked_alert.desc += " You are filled with [willpower_levels[willpower_dots]]." + +/datum/status_effect/delirium/on_apply() + . = ..() + var/mob/living/carbon/human/human_owner = astype(owner) + if(!human_owner) + return FALSE + if(!human_owner.affected_by_delirium()) + return FALSE + var/mob/living/wolf = scary_wolf_ref?.resolve() + if(!wolf) + return FALSE + + to_chat(owner, span_boldwarning("Something DEEP inside you fill you with [willpower_levels[willpower_dots]] at the sight of [wolf]")) + willpower_dots = clamp(human_owner.st_get_stat(STAT_PERMANENT_WILLPOWER), 1, 10) + + if(owner.client) + // dir SOUTH is admitting i compeletly lost the fight against this stupid bullshit and cant get the image to properly mimmic the direction of the mob. + var/image/overlay_image = image(loc = wolf, dir = SOUTH) + overlay_image.appearance = wolf.appearance + overlay_image.override = TRUE + overlay_image.name = "Unknown" + overlay_image.pixel_y = 0 + overlay_image.pixel_x = 0 + overlay_image.pixel_w = 0 + overlay_image.pixel_z = 0 + SET_PLANE_EXPLICIT(overlay_image, ABOVE_GAME_PLANE, wolf) + + var/mutable_appearance/static_effect = mutable_appearance('modular_darkpack/modules/werewolf_the_apocalypse/icons/garou_forms/big_static.dmi', "static_base") + static_effect.color = "#373642" + static_effect.blend_mode = BLEND_INSET_OVERLAY + overlay_image.overlays += static_effect + + owner.client.images += overlay_image + scary_static = overlay_image + +/datum/status_effect/delirium/on_remove() + . = ..() + to_chat(owner, span_notice("Your heightened emotions subside and you begin to calm.")) + owner.client?.images -= scary_static + QDEL_NULL(scary_static) + +/datum/status_effect/delirium/tick(seconds_between_ticks) + . = ..() + var/mob/living/carbon/human/human_owner = astype(owner) + if(!human_owner) + return + if(!human_owner.affected_by_delirium()) + return + if(COOLDOWN_FINISHED(src, message_cooldown)) + COOLDOWN_START(src, message_cooldown, rand(10, 15) SECONDS) + var/message = get_message() + if(message) + to_chat(owner, span_boldwarning(message)) + + +/datum/status_effect/delirium/proc/get_message() + switch(willpower_dots) + // Catatonic Fear + if(1) + return pick("FEAR", "FAINT", "COLLAPSE") + // Panic + if(2) + return pick("RUN", "RUN NOW", "GET DISTANCE") + // Disbelief + if(3) + return pick("HIDE", "COWER") + // Beserk + if(4) + return pick("FIGHT", "KICK", "PUNCH", "BITE", "SWING") + // Terror + if(5) + return pick("RUN", "RUN NOW", "GET DISTANCE", "THINK") + // Conciliatory + if(6) + return pick("PLEAD", "BARGIN", "WHIMPER") + // Controlled Fear + if(7) + return "fear" + // Curiosity + if(8) + return pick("learn", "discover") + // Bloodlust + if(9) + return "anger" + // No reaction + if(10) + return + + +/atom/movable/screen/alert/status_effect/delirium + name = "The Delirium" + desc = "A supernatural fear." + icon_state = "fear" + icon = 'modular_darkpack/modules/deprecated/icons/hud/screen_alert.dmi' + + +/mob/living/carbon/human/proc/affected_by_delirium() + if(issupernatural(src)) + return FALSE + + if(st_get_stat(STAT_PERMANENT_WILLPOWER) >= 10) + return FALSE + + return TRUE diff --git a/modular_darkpack/modules/werewolf_the_apocalypse/code/species/garou_organs.dm b/modular_darkpack/modules/werewolf_the_apocalypse/code/species/garou_organs.dm index 692d872c5f6b..b9622e53a320 100644 --- a/modular_darkpack/modules/werewolf_the_apocalypse/code/species/garou_organs.dm +++ b/modular_darkpack/modules/werewolf_the_apocalypse/code/species/garou_organs.dm @@ -6,13 +6,15 @@ head_flags = NONE unarmed_attack_sound = 'modular_darkpack/modules/werewolf_the_apocalypse/sounds/werewolf_bite.ogg' +/obj/item/bodypart/head/fera/aggravated + attack_type = AGGRAVATED + /obj/item/bodypart/chest/fera // limb_id = SPECIES_FERA /obj/item/bodypart/arm/left/fera // limb_id = SPECIES_FERA unarmed_sharpness = SHARP_EDGED - attack_type = AGGRAVATED unarmed_attack_verbs = list("claw") unarmed_attack_verbs_continuous = list("claws") appendage_noun = "paw" @@ -20,10 +22,12 @@ unarmed_attack_sound = 'modular_darkpack/modules/werewolf_the_apocalypse/sounds/werewolf_bite.ogg' unarmed_miss_sound = 'sound/items/weapons/slashmiss.ogg' +/obj/item/bodypart/arm/left/fera/aggravated + attack_type = AGGRAVATED + /obj/item/bodypart/arm/right/fera // limb_id = SPECIES_FERA unarmed_sharpness = SHARP_EDGED - attack_type = AGGRAVATED unarmed_attack_verbs = list("claw") unarmed_attack_verbs_continuous = list("claws") appendage_noun = "paw" @@ -31,6 +35,9 @@ unarmed_attack_sound = 'modular_darkpack/modules/werewolf_the_apocalypse/sounds/werewolf_bite.ogg' unarmed_miss_sound = 'sound/items/weapons/slashmiss.ogg' +/obj/item/bodypart/arm/right/fera/aggravated + attack_type = AGGRAVATED + /obj/item/bodypart/leg/left/fera unarmed_sharpness = SHARP_EDGED // limb_id = SPECIES_FERA diff --git a/modular_darkpack/modules/werewolf_the_apocalypse/code/splats/fera_species.dm b/modular_darkpack/modules/werewolf_the_apocalypse/code/splats/fera_species.dm index 40b7cee7e220..650ba44d65d8 100644 --- a/modular_darkpack/modules/werewolf_the_apocalypse/code/splats/fera_species.dm +++ b/modular_darkpack/modules/werewolf_the_apocalypse/code/splats/fera_species.dm @@ -24,6 +24,8 @@ species_language_holder = /datum/language_holder/garou var/mob_pixel_w var/mob_pixel_z + /// If declared will override the mob size. + var/mob_size_override /// Stats added and removed upon gaining the species var/list/form_bonus_stats = list() /// Dice roll difficulty required to shift into this form @@ -36,8 +38,8 @@ var/fallback_icon /// Speed mod applied and removed upon gaining this species var/speed_mod - /// Causes delerium, which if the user is affected by, does not cause breaches - var/causes_delerium + /// Causes delirium, which if the user is affected by, does not cause breaches + var/causes_delirium /// IF this form can be witnessed, causes masqurade breaches var/veil_breaching_form = FALSE @@ -48,6 +50,9 @@ human_who_gained_species.add_offsets(type, w_add = mob_pixel_w, z_add = mob_pixel_z) + if(mob_size_override) + human_who_gained_species.mob_size = mob_size_override + add_buffs(human_who_gained_species) /datum/species/human/shifter/on_species_loss(mob/living/carbon/human/human, datum/species/new_species, pref_load) @@ -55,6 +60,9 @@ if(speed_mod) human.remove_movespeed_modifier(speed_mod) + if(mob_size_override) + human.mob_size = human::mob_size + human.remove_offsets(type) clear_buffs(human) @@ -198,14 +206,14 @@ TRAIT_NO_LYING_ANGLE, TRAIT_TRANSFORM_UPDATES_ICON, ) - causes_delerium = TRUE + causes_delirium = TRUE veil_breaching_form = TRUE mutanttongue = /obj/item/organ/tongue/fera bodypart_overrides = list( - BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left/fera, - BODY_ZONE_R_ARM = /obj/item/bodypart/arm/right/fera, - BODY_ZONE_HEAD = /obj/item/bodypart/head/fera, + BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left/fera/aggravated, + BODY_ZONE_R_ARM = /obj/item/bodypart/arm/right/fera/aggravated, + BODY_ZONE_HEAD = /obj/item/bodypart/head/fera/aggravated, BODY_ZONE_L_LEG = /obj/item/bodypart/leg/left/fera, BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/fera, BODY_ZONE_CHEST = /obj/item/bodypart/chest/fera, @@ -215,6 +223,8 @@ visible_gender_override = "beast" + mob_pixel_w = -8 + mob_size_override = MOB_SIZE_LARGE form_bonus_stats = list( STAT_STRENGTH = 4, STAT_STAMINA = 3, @@ -222,11 +232,9 @@ STAT_MANIPULATION = -3, // STAT_APPEARANCE = 0 // NOT YET SUPPORTED ) - mob_pixel_w = -8 custom_body_render = TRUE custom_damage_render = TRUE fallback_icon = 'modular_darkpack/modules/werewolf_the_apocalypse/icons/garou_forms/crinos.dmi' - speed_mod = /datum/movespeed_modifier/shifter/war /datum/species/human/shifter/dire name = "dire form" @@ -238,15 +246,16 @@ TRAIT_TRANSFORM_UPDATES_ICON, TRAIT_FERAL_BITER, TRAIT_SMALL_HANDS, + TRAIT_NO_CUFF, ) veil_breaching_form = TRUE mutantbrain = /obj/item/organ/brain/fera mutanttongue = /obj/item/organ/tongue/fera bodypart_overrides = list( - BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left/fera, - BODY_ZONE_R_ARM = /obj/item/bodypart/arm/right/fera, - BODY_ZONE_HEAD = /obj/item/bodypart/head/fera, + BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left/fera/aggravated, + BODY_ZONE_R_ARM = /obj/item/bodypart/arm/right/fera/aggravated, + BODY_ZONE_HEAD = /obj/item/bodypart/head/fera/aggravated, BODY_ZONE_L_LEG = /obj/item/bodypart/leg/left/fera, BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/fera, BODY_ZONE_CHEST = /obj/item/bodypart/chest/fera, @@ -256,6 +265,8 @@ visible_gender_override = "beast" + mob_pixel_w = -16 + mob_pixel_z = -8 form_bonus_stats = list( STAT_STRENGTH = 3, STAT_STAMINA = 3, @@ -263,8 +274,6 @@ STAT_MANIPULATION = -3, ) shift_difficulty = 7 - mob_pixel_w = -16 - mob_pixel_z = -8 custom_body_render = TRUE custom_damage_render = TRUE fallback_icon = 'modular_darkpack/modules/werewolf_the_apocalypse/icons/garou_forms/hispo.dmi' @@ -280,6 +289,7 @@ TRAIT_TRANSFORM_UPDATES_ICON, TRAIT_FERAL_BITER, TRAIT_SMALL_HANDS, + TRAIT_NO_CUFF, ) mutantbrain = /obj/item/organ/brain/fera @@ -287,7 +297,7 @@ bodypart_overrides = list( BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left/fera, BODY_ZONE_R_ARM = /obj/item/bodypart/arm/right/fera, - BODY_ZONE_HEAD = /obj/item/bodypart/head/fera, + BODY_ZONE_HEAD = /obj/item/bodypart/head/fera/aggravated, BODY_ZONE_L_LEG = /obj/item/bodypart/leg/left/fera, BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/fera, BODY_ZONE_CHEST = /obj/item/bodypart/chest/fera, @@ -312,12 +322,8 @@ abstract_type = /datum/movespeed_modifier/shifter movetypes = GROUND -// Verify these nums are ttrpg accurate. -/datum/movespeed_modifier/shifter/war - multiplicative_slowdown = -0.1 - /datum/movespeed_modifier/shifter/dire - multiplicative_slowdown = -0.3 + multiplicative_slowdown = -0.2 /datum/movespeed_modifier/shifter/feral - multiplicative_slowdown = -0.5 + multiplicative_slowdown = -0.35 diff --git a/modular_darkpack/modules/werewolf_the_apocalypse/code/splats/fera_splat.dm b/modular_darkpack/modules/werewolf_the_apocalypse/code/splats/fera_splat.dm index 4ed9d06d10ee..b6d6eab37e21 100644 --- a/modular_darkpack/modules/werewolf_the_apocalypse/code/splats/fera_splat.dm +++ b/modular_darkpack/modules/werewolf_the_apocalypse/code/splats/fera_splat.dm @@ -86,6 +86,7 @@ /datum/splat/werewolf/shifter abstract_type = /datum/splat/werewolf/shifter splat_traits = list( + TRAIT_FERA_FORMS, TRAIT_WTA_GAROU_BREED, TRAIT_WTA_GAROU_AUSPICE, TRAIT_WTA_GAROU_TRIBE, @@ -146,8 +147,13 @@ COOLDOWN_START(src, passive_healing_cd, 1 TURNS) var/datum/species/human/shifter/shifter_species = owner.dna.species if(istype(shifter_species)) - if(shifter_species.is_veil_breaching_form(owner) && (!shifter_species.causes_delerium || HAS_TRAIT(owner, TRAIT_PIERCED_VEIL))) + if(shifter_species.is_veil_breaching_form(owner) && (!shifter_species.causes_delirium || HAS_TRAIT(owner, TRAIT_PIERCED_VEIL))) SEND_SIGNAL(owner, COMSIG_MASQUERADE_VIOLATION) + if(shifter_species.causes_delirium) + for(var/mob/living/carbon/human/guy in oviewers(owner, DEFAULT_SIGHT_DISTANCE)) + if(!guy.affected_by_delirium()) + continue + guy.apply_status_effect(STATUS_EFFECT_DELIRIUM, owner) // Being used to represent meditating in your caern /datum/splat/werewolf/shifter/proc/regain_gnosis_process(seconds_per_tick) diff --git a/modular_darkpack/modules/werewolf_the_apocalypse/code/splats/transformation.dm b/modular_darkpack/modules/werewolf_the_apocalypse/code/splats/transformation.dm index 966652e34c66..a11ab096902d 100644 --- a/modular_darkpack/modules/werewolf_the_apocalypse/code/splats/transformation.dm +++ b/modular_darkpack/modules/werewolf_the_apocalypse/code/splats/transformation.dm @@ -13,7 +13,8 @@ return if(!(form_to_transform in transformation_list)) return - if(owner?.dna?.species?.type == form_to_transform) + var/datum/species/human/shifter/current_form = owner?.dna?.species + if(istype(current_form, form_to_transform)) return if(!force && !COOLDOWN_FINISHED(src, transform_cd)) to_chat(owner, span_warning("Your shifting is on cooldown for one turn.")) @@ -37,7 +38,9 @@ // TODO: should accctually require an amount of successes equal to the forms your shifting through if(requires_roll) var/datum/storyteller_roll/fera_trans/transform_roll = new() - transform_roll.difficulty = form_to_transform::shift_difficulty + if(current_form) + transform_roll.difficulty = current_form.shift_difficulty + transform_roll.successes_needed = steps_between_forms(current_form.type, form_to_transform) switch(transform_roll.st_roll(owner, owner, PRIMAL_URGE_PLACEHOLDER)) if(ROLL_SUCCESS) pass() @@ -53,6 +56,9 @@ // owner.Stun(time_to_transform, ignore_canstun = TRUE) + for(var/obj/item/clothing/equipped in owner.get_equipped_items(INCLUDE_ABSTRACT)) + equipped.take_damage(rand(25, 50), sound_effect = FALSE) + var/matrix/ntransform = matrix(owner.transform) ntransform.Scale(1.1, 1.1) animate(owner, transform = ntransform, color = "#000000", time = time_to_transform * 0.9) @@ -61,6 +67,11 @@ addtimer(CALLBACK(src, PROC_REF(transform_finish), form_to_transform, time_to_transform), time_to_transform * 0.9) +/datum/splat/werewolf/shifter/proc/steps_between_forms(datum/species/human/shifter/first_form, datum/species/human/shifter/second_form) + var/first_index = transformation_list.Find(first_form) + var/second_index = transformation_list.Find(second_form) + return abs(first_index - second_index) + /datum/splat/werewolf/shifter/proc/revert_to_breed_form() if(HAS_TRAIT(owner, TRAIT_METAMORPH)) var/datum/storyteller_roll/metamorph/roll_datum = new() diff --git a/modular_darkpack/modules/werewolf_the_apocalypse/code/werewolf_globals.dm b/modular_darkpack/modules/werewolf_the_apocalypse/code/werewolf_globals.dm index e112a527852d..8357439a8323 100644 --- a/modular_darkpack/modules/werewolf_the_apocalypse/code/werewolf_globals.dm +++ b/modular_darkpack/modules/werewolf_the_apocalypse/code/werewolf_globals.dm @@ -8,9 +8,9 @@ GLOBAL_VAR_INIT(moon_state, get_moon_phase()) var/ref_month = 1 var/ref_day = 20 - var/year = text2num(station_time_timestamp("YYYY")) - var/month = text2num(station_time_timestamp("MM")) - var/day = text2num(station_time_timestamp("DD")) + var/year = text2num(server_timestamp("YYYY", ic_time = TRUE)) + var/month = text2num(server_timestamp("MM", ic_time = TRUE)) + var/day = text2num(server_timestamp("DD", ic_time = TRUE)) var/ref_days = ref_year * 365 + ref_month * 30 + ref_day var/current_days = year * 365 + month * 30 + day diff --git a/modular_darkpack/modules/werewolf_the_apocalypse/icons/garou_forms/big_static.dmi b/modular_darkpack/modules/werewolf_the_apocalypse/icons/garou_forms/big_static.dmi new file mode 100644 index 000000000000..aff62d6d2b3b Binary files /dev/null and b/modular_darkpack/modules/werewolf_the_apocalypse/icons/garou_forms/big_static.dmi differ diff --git a/sound/items/weapons/rust_sower_armbomb.ogg b/sound/items/weapons/rust_sower_armbomb.ogg index 0cc796ba2a8f..c8ab60df71cb 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 52b1cd8ec4cd..7888cb0cefae 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 7ffecac8d88c..000000000000 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 387bc64996ce..000000000000 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 caefb92a9c55..000000000000 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 3ee369280022..000000000000 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 000000000000..4c709873c563 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 000000000000..ff34af491cd5 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 000000000000..09d970bdc370 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 000000000000..1b2491925c71 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 957fb4cd1756..b5602ca73e93 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 5d6d00044917..d98474814904 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 1f99c32c61c7..7e79ebcbfa18 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/quotes/bible.txt b/strings/quotes/bible.txt new file mode 100644 index 000000000000..b94e6340dea1 --- /dev/null +++ b/strings/quotes/bible.txt @@ -0,0 +1,55 @@ +He that is unjust, let him be unjust still: and he which is filthy, let him be filthy still: and he that is righteous, let him be righteous still: and he that is holy, let him be holy still. +And, behold, I come quickly; and my reward is with me, to give every man according as his work shall be. I am Alpha and Omega, the beginning and the end, the first and the last. +He that hath an ear, let him hear what the Spirit saith unto the churches. +Yea, though I walk through the valley of the shadow of death, I will fear no evil: for thou art with me. +Deliver my soul from the sword; my darling from the power of the dog. Save me from the lion’s mouth: for thou hast heard me from the horns of the unicorns. I will declare thy name unto my brethren: in the midst of the congregation will I praise thee. +For in much wisdom is much grief: and he that increaseth knowledge increaseth sorrow. +Fear them not therefore: for there is nothing covered, that shall not be revealed; and hid, that shall not be known. +To every thing there is a season, and a time to every purpose under the heaven: A time to be born, and a time to die; a time to plant, and a time to pluck up that which is planted; A time to kill, and a time to heal; a time to break down, and a time to build up; A time to weep, and a time to laugh; a time to mourn, and a time to dance; A time to cast away stones, and a time to gather stones together; a time to embrace, and a time to refrain from embracing; A time to get, and a time to lose; a time to keep, and a time to cast away; A time to rend, and a time to sew; a time to keep silence, and a time to speak; A time to love, and a time to hate; a time of war, and a time of peace. +Then I saw that wisdom excelleth folly, as far as light excelleth darkness. +Woe unto them that call evil good, and good evil; that put darkness for light, and light for darkness; that put bitter for sweet, and sweet for bitter! Woe unto them that are wise in their own eyes, and prudent in their own sight! Woe unto them that are mighty to drink wine, and men of strength to mingle strong drink: Which justify the wicked for reward, and take away the righteousness of the righteous from him! Therefore as the fire devoureth the stubble, and the flame consumeth the chaff, so their root shall be as rottenness, and their blossom shall go up as dust: because they have cast away the law of the LORD of hosts, and despised the word of the Holy One of Israel. Therefore is the anger of the LORD kindled against his people, and he hath stretched forth his hand against them, and hath smitten them: and the hills did tremble, and their carcases were torn in the midst of the streets. For all this his anger is not turned away, but his hand is stretched out still. +Your new moons and your appointed feasts my soul hateth: they are a trouble unto me; I am weary to bear them. And when ye spread forth your hands, I will hide mine eyes from you: yea, when ye make many prayers, I will not hear: your hands are full of blood. +Why should ye be stricken any more? ye will revolt more and more: the whole head is sick, and the whole heart faint. From the sole of the foot even unto the head there is no soundness in it; but wounds, and bruises, and putrifying sores: they have not been closed, neither bound up, neither mollified with ointment. Your country is desolate, your cities are burned with fire: your land, strangers devour it in your presence, and it is desolate, as overthrown by strangers. And the daughter of Zion is left as a cottage in a vineyard, as a lodge in a garden of cucumbers, as a besieged city. Except the LORD of hosts had left unto us a very small remnant, we should have been as Sodom, and we should have been like unto Gomorrah. +But we are all as an unclean thing, and all our righteousnesses are as filthy rags; and we all do fade as a leaf; and our iniquities, like the wind, have taken us away. And there is none that calleth upon thy name, that stirreth up himself to take hold of thee: for thou hast hid thy face from us, and hast consumed us, because of our iniquities. But now, O LORD, thou art our father; we are the clay, and thou our potter; and we all are the work of thy hand. +Blessed are the poor in spirit: for theirs is the kingdom of heaven. Blessed are they that mourn: for they shall be comforted. Blessed are the meek: for they shall inherit the earth. Blessed are they which do hunger and thirst after righteousness: for they shall be filled. Blessed are the merciful: for they shall obtain mercy. Blessed are the pure in heart: for they shall see God. Blessed are the peacemakers: for they shall be called the children of God. Blessed are they which are persecuted for righteousness sake: for theirs is the kingdom of heaven. Blessed are ye, when men shall revile you, and persecute you, and shall say all manner of evil against you falsely, for my sake. Rejoice, and be exceeding glad: for great is your reward in heaven: for so persecuted they the prophets which were before you. +Ye are the salt of the earth: but if the salt have lost his savour, wherewith shall it be salted? it is thenceforth good for nothing, but to be cast out, and to be trodden under foot of men. Ye are the light of the world. A city that is set on an hill cannot be hid. Neither do men light a candle, and put it under a bushel, but on a candlestick; and it giveth light unto all that are in the house. Let your light so shine before men, that they may see your good works, and glorify your Father which is in heaven. +Think not that I am come to destroy the law, or the prophets: I am not come to destroy, but to fulfil. +But I say unto you, That whosoever looketh on a woman to lust after her hath committed adultery with her already in his heart. And if thy right eye offend thee, pluck it out, and cast it from thee: for it is profitable for thee that one of thy members should perish, and not that thy whole body should be cast into hell. And if thy right hand offend thee, cut if off, and cast it from thee: for it is profitable for thee that one of thy members should perish, and not that thy whole body should be cast into hell. +Ye have heard that it hath been said, An eye for an eye, and a tooth for a tooth: But I say unto you, That ye resist not evil: but whosoever shall smite thee on thy right cheek, turn to him the other also. And if any man will sue thee at the law, and take away thy coat, let him have thy cloke also. And whosoever shall compel thee to go a mile, go with him twain. Give to him that asketh thee, and from him that would borrow of thee turn not thou away. +Take heed that ye do not your alms before men, to be seen of them: otherwise ye have no reward of your Father which is in heaven. Therefore when thou doest thine alms, do not sound a trumpet before thee, as the hypocrites do in the synagogues and in the streets, that they may have glory of men. Verily I say unto you, They have their reward. But when thou doest alms, let not thy left hand know what thy right hand doeth: That thine alms may be in secret: and thy Father which seeth in secret himself shall reward thee openly. +Ye have heard that it hath been said, Thou shalt love thy neighbour, and hate thine enemy. But I say unto you, Love your enemies, bless them that curse you, do good to them that hate you, and pray for them which despitefully use you, and persecute you; That ye may be the children of your Father which is in heaven: for he maketh his sun to rise on the evil and on the good, and sendeth rain on the just and on the unjust. For if ye love them which love you, what reward have ye? do not even the publicans the same? And if ye salute your brethren only, what do ye more than others? do not even the publicans so? Be ye therefore perfect, even as your Father which is in heaven is perfect. +Our Father which art in heaven, Hallowed be thy name. Thy kingdom come. Thy will be done in earth, as it is in heaven. Give us this day our daily bread. And forgive us our debts, as we forgive our debtors. And lead us not into temptation, but deliver us from evil: For thine is the kingdom, and the power, and the glory, for ever. Amen. +Lay not up for yourselves treasures upon earth, where moth and rust doth corrupt, and where thieves break through and steal: But lay up for yourselves treasures in heaven, where neither moth nor rust doth corrupt, and where thieves do not break through nor steal: For where your treasure is, there will your heart be also. +For if ye forgive men their trespasses, your heavenly Father will also forgive you: But if ye forgive not men their trespasses, neither will your Father forgive your trespasses. +Judge not, that ye be not judged. For with what judgment ye judge, ye shall be judged: and with what measure ye mete, it shall be measured to you again. And why beholdest thou the mote that is in thy brother’s eye, but considerest not the beam that is in thine own eye? Or how wilt thou say to thy brother, Let me pull out the mote out of thine eye; and, behold, a beam is in thine own eye? Thou hypocrite, first cast out the beam out of thine own eye; and then shalt thou see clearly to cast out the mote out of thy brother’s eye. +Ask, and it shall be given you; seek, and ye shall find; knock, and it shall be opened unto you: For every one that asketh receiveth; and he that seeketh findeth; and to him that knocketh it shall be opened. Or what man is there of you, whom if his son ask bread, will he give him a stone? Or if he ask a fish, will he give him a serpent? If ye then, being evil, know how to give good gifts unto your children, how much more shall your Father which is in heaven give good things to them that ask him? Therefore all things whatsoever ye would that men should do to you, do ye even so to them: for this is the law and the prophets. +Beware of false prophets, which come to you in sheep’s clothing, but inwardly they are ravening wolves. Ye shall know them by their fruits. +And when they had platted a crown of thorns, they put it upon his head, and a reed in his right hand: and they bowed the knee before him, and mocked him, saying, Hail, King of the Jews! And they spit upon him, and took the reed, and smote him on the head. And after that they had mocked him, they took the robe off from him, and put his own raiment on him, and led him away to crucify him. +And they that passed by reviled him, wagging their heads, And saying, Thou that destroyest the temple, and buildest it in three days, save thyself. If thou be the Son of God, come down from the cross. Likewise also the chief priests mocking him, with the scribes and elders, said, He saved others; himself he cannot save. If he be the King of Israel, let him now come down from the cross, and we will believe him. He trusted in God; let him deliver him now, if he will have him: for he said, I am the Son of God. The thieves also, which were crucified with him, cast the same in his teeth. +Then said Jesus, Father, forgive them; for they know not what they do. +And one of the malefactors which were crucified next to him, saying, If thou be Christ, save thyself and us. But the other answering rebuked him, saying, Dost not thou fear God, seeing thou art in the same condemnation? And we indeed justly; for we receive the due reward of our deeds: but this man hath done nothing amiss. And he said unto Jesus, Lord, remember me when thou comest into thy kingdom. And Jesus said unto him, Verily I say unto thee, To day shalt thou be with me in paradise. And it was about the sixth hour, and there was a darkness over all the earth until the ninth hour. And the sun was darkened, and the veil of the temple was rent in the midst. +And when Jesus had cried with a loud voice, he said, Father, into thy hands I commit my spirit: and having said thus, he gave up the ghost. Now when the centurion saw what was done, he glorified God, saying, Certainly this was a righteous man. +And said unto them, Thus it is written, and thus it behoved Christ to suffer, and to rise from the dead the third day: And that repentance and remission of sins should be preached in his name among all nations, beginning at Jerusalem. And ye are witnesses of these things. +And I saw heaven opened, and behold a white horse; and he that sat upon him was called Faithful and True, and in righteousness he doth judge and make war. His eyes were as a flame of fire, and on his head were many crowns; and he had a name written, that no man knew, but he himself. And he was clothed with a vesture dipped in blood: and his name is called The Word of God. And the armies which were in heaven followed him upon white horses, clothed in fine linen, white and clean. And out of his mouth goeth a sharp sword, that with it he should smite the nations: and he shall rule them with a rod of iron: and he treadeth the winepress of the fierceness and wrath of Almighty God. +And when he had opened the seventh seal, there was silence in heaven about the space of half an hour. +And I saw the seven angels which stood before God; and to them were given seven trumpets. +And another angel came and stood at the altar, having a golden censer; and there was given unto him much incense, that he should offer it with the prayers of all saints upon the golden altar which was before the throne. +And the smoke of the incense, which came with the prayers of the saints, ascended up before God out of the angel's hand. And the angel took the censer, and filled it with fire of the altar, and cast it into the earth: and there were voices, and thunderings, and lightnings, and an earthquake. And the seven angels which had the seven trumpets prepared themselves to sound. +The first angel sounded, and there followed hail and fire mingled with blood, and they were cast upon the earth: and the third part of trees was burnt up, and all green grass was burnt up. +And the second angel sounded, and as it were a great mountain burning with fire was cast into the sea: and the third part of the sea became blood; And the third part of the creatures which were in the sea, and had life, died; and the third part of the ships were destroyed. +And the third angel sounded, and there fell a great star from heaven, burning as it were a lamp, and it fell upon the third part of the rivers, and upon the fountains of waters; And the name of the star is called Wormwood: and the third part of the waters became wormwood; and many men died of the waters, because they were made bitter. +And the fourth angel sounded, and the third part of the sun was smitten, and the third part of the moon, and the third part of the stars; so as the third part of them was darkened, and the day shone not for a third part of it, and the night likewise. +And the devil that deceived them was cast into the lake of fire and brimstone, where the beast and the false prophet are, and shall be tormented day and night for ever and ever. +And death and hell were cast into the lake of fire. This is the second death. +And God shall wipe away all tears from their eyes; and there shall be no more death, neither sorrow, nor crying, neither shall there be any more pain: for the former things are passed away. +And he said unto me, It is done. I am Alpha and Omega, the beginning and the end. I will give unto him that is athirst of the fountain of the water of life freely. +For, behold, the Lord will come with fire, and with his chariots like a whirlwind, to render his anger with fury, and his rebuke with flames of fire. +For by fire and by his sword will the Lord plead with all flesh: and the slain of the Lord shall be many. +The eyes of the Lord are in every place, beholding the evil and the good. +Thou shalt not be afraid for the terror by night; nor for the arrow that flieth by day. +Submit yourselves therefore to God. Resist the devil, and he will flee from you. +A thousand shall fall at thy side, and ten thousand at thy right hand; but it shall not come nigh thee. +Dearly beloved, avenge not yourselves, but rather give place unto wrath: for it is written, Vengeance is mine; I will repay, saith the Lord. +Come unto me, all ye that labour and are heavy laden, and I will give you rest. +The sun shall be turned into darkness, and the moon into blood, before the great and terrible day of the Lord come. +And it shall come to pass, that whosoever shall call on the name of the Lord shall be delivered: for in mount Zion and in Jerusalem shall be deliverance, as the Lord hath said, and in the remnant whom the Lord shall call. diff --git a/tgstation.dme b/tgstation.dme index 747a494f82f0..9bdb28a953dc 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -463,6 +463,7 @@ #include "code\__DEFINES\~darkpack\sight.dm" #include "code\__DEFINES\~darkpack\signals_kindred.dm" #include "code\__DEFINES\~darkpack\sound.dm" +#include "code\__DEFINES\~darkpack\spirit_defines.dm" #include "code\__DEFINES\~darkpack\splats.dm" #include "code\__DEFINES\~darkpack\status_effects_debuffs.dm" #include "code\__DEFINES\~darkpack\storyteller_dice.dm" @@ -619,6 +620,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" @@ -801,7 +803,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" @@ -1502,6 +1503,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" @@ -2466,6 +2468,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" @@ -2565,6 +2568,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" @@ -3142,6 +3146,8 @@ #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" @@ -3346,6 +3352,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\_wrappers.dm" #include "code\modules\admin\verbs\lua\helpers.dm" #include "code\modules\admin\verbs\lua\lua_editor.dm" @@ -3612,6 +3619,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" @@ -4190,6 +4198,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" @@ -4416,6 +4425,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" @@ -4452,6 +4462,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" @@ -5024,6 +5035,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" @@ -5257,6 +5269,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" @@ -5269,6 +5286,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" @@ -5745,10 +5768,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" @@ -6275,6 +6295,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" @@ -6499,6 +6525,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" @@ -6906,6 +6933,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" @@ -6993,6 +7023,10 @@ #include "modular_darkpack\master_files\code\datums\mapgen\woods_generator.dm" #include "modular_darkpack\master_files\code\datums\mind\_mind.dm" #include "modular_darkpack\master_files\code\datums\quirks\_quirk.dm" +#include "modular_darkpack\master_files\code\datums\quirks\negative_quirks\blind.dm" +#include "modular_darkpack\master_files\code\datums\quirks\negative_quirks\deaf.dm" +#include "modular_darkpack\master_files\code\datums\quirks\negative_quirks\illiterate.dm" +#include "modular_darkpack\master_files\code\datums\quirks\negative_quirks\mute.dm" #include "modular_darkpack\master_files\code\datums\station_traits\_station_trait.dm" #include "modular_darkpack\master_files\code\datums\storage\subtypes\bags.dm" #include "modular_darkpack\master_files\code\datums\storage\subtypes\dufflebags.dm" @@ -7127,8 +7161,10 @@ #include "modular_darkpack\modules\city_time\code\admin_verbs.dm" #include "modular_darkpack\modules\city_time\code\city_time_subsystem.dm" #include "modular_darkpack\modules\city_time\code\clock_structure.dm" +#include "modular_darkpack\modules\city_time\code\helpers.dm" #include "modular_darkpack\modules\city_time\code\moonlight.dm" #include "modular_darkpack\modules\city_time\code\status_effects.dm" +#include "modular_darkpack\modules\city_time\code\time_configs.dm" #include "modular_darkpack\modules\city_time\code\vote.dm" #include "modular_darkpack\modules\city_time\code\wrist_watch.dm" #include "modular_darkpack\modules\city_traits\code\negative_traits.dm" @@ -7216,6 +7252,8 @@ #include "modular_darkpack\modules\ert\code\outfits\first_team_outfits.dm" #include "modular_darkpack\modules\ert\code\outfits\national_guard_outfits.dm" #include "modular_darkpack\modules\ert\code\outfits\swat_outfits.dm" +#include "modular_darkpack\modules\events\code\_darkpack_event.dm" +#include "modular_darkpack\modules\events\code\blackout_event.dm" #include "modular_darkpack\modules\external_organs\code\gargoyle_wings.dm" #include "modular_darkpack\modules\external_organs\code\gargoyle_wings_sprite_accessory_datum.dm" #include "modular_darkpack\modules\fire\code\fire.dm" @@ -7293,6 +7331,10 @@ #include "modular_darkpack\modules\jobs\code\giovanni\capo.dm" #include "modular_darkpack\modules\jobs\code\giovanni\la_famiglia.dm" #include "modular_darkpack\modules\jobs\code\giovanni\la_squadra.dm" +#include "modular_darkpack\modules\jobs\code\hunters\abbe.dm" +#include "modular_darkpack\modules\jobs\code\hunters\condottieri.dm" +#include "modular_darkpack\modules\jobs\code\hunters\inquisitor.dm" +#include "modular_darkpack\modules\jobs\code\hunters\novice.dm" #include "modular_darkpack\modules\jobs\code\miscelllaneous\citizen.dm" #include "modular_darkpack\modules\jobs\code\miscelllaneous\club_worker.dm" #include "modular_darkpack\modules\jobs\code\miscelllaneous\graveyard_keeper.dm" @@ -7384,16 +7426,12 @@ #include "modular_darkpack\modules\merits_flaws\code\negative_quirks\animal_musk.dm" #include "modular_darkpack\modules\merits_flaws\code\negative_quirks\bad_sight.dm" #include "modular_darkpack\modules\merits_flaws\code\negative_quirks\betrayers_mark.dm" -#include "modular_darkpack\modules\merits_flaws\code\negative_quirks\blind.dm" -#include "modular_darkpack\modules\merits_flaws\code\negative_quirks\deaf.dm" #include "modular_darkpack\modules\merits_flaws\code\negative_quirks\derangement.dm" #include "modular_darkpack\modules\merits_flaws\code\negative_quirks\dulled_bite.dm" #include "modular_darkpack\modules\merits_flaws\code\negative_quirks\grip_of_the_damned.dm" #include "modular_darkpack\modules\merits_flaws\code\negative_quirks\horrific_appearance_quirk.dm" -#include "modular_darkpack\modules\merits_flaws\code\negative_quirks\illiterate.dm" #include "modular_darkpack\modules\merits_flaws\code\negative_quirks\mage_blood.dm" #include "modular_darkpack\modules\merits_flaws\code\negative_quirks\monstrous_quirk.dm" -#include "modular_darkpack\modules\merits_flaws\code\negative_quirks\mute.dm" #include "modular_darkpack\modules\merits_flaws\code\negative_quirks\one_armed.dm" #include "modular_darkpack\modules\merits_flaws\code\negative_quirks\organovore.dm" #include "modular_darkpack\modules\merits_flaws\code\negative_quirks\permanent_fangs.dm" @@ -7419,6 +7457,7 @@ #include "modular_darkpack\modules\merits_flaws\code\positive_quirks\stillness_of_death.dm" #include "modular_darkpack\modules\merits_flaws\code\positive_quirks\time_sense.dm" #include "modular_darkpack\modules\merits_flaws\code\positive_quirks\untamable.dm" +#include "modular_darkpack\modules\merits_flaws\code\positive_quirks\wolf_sight.dm" #include "modular_darkpack\modules\mob_spawners\code\citizen.dm" #include "modular_darkpack\modules\movie_theatre\code\areas.dm" #include "modular_darkpack\modules\movie_theatre\code\fluff.dm" @@ -7436,9 +7475,13 @@ #include "modular_darkpack\modules\npc\code\human\npc_types\garden.dm" #include "modular_darkpack\modules\npc\code\human\npc_types\guard.dm" #include "modular_darkpack\modules\npc\code\human\npc_types\gummaguts.dm" +#include "modular_darkpack\modules\npc\code\human\npc_types\gunstore.dm" +#include "modular_darkpack\modules\npc\code\human\npc_types\hardwarestore.dm" #include "modular_darkpack\modules\npc\code\human\npc_types\hobo.dm" +#include "modular_darkpack\modules\npc\code\human\npc_types\huntingstore.dm" #include "modular_darkpack\modules\npc\code\human\npc_types\illegal.dm" #include "modular_darkpack\modules\npc\code\human\npc_types\incel.dm" +#include "modular_darkpack\modules\npc\code\human\npc_types\pharmacystore.dm" #include "modular_darkpack\modules\npc\code\human\npc_types\police.dm" #include "modular_darkpack\modules\npc\code\human\npc_types\shop.dm" #include "modular_darkpack\modules\npc\code\human\npc_types\stripper.dm" @@ -7484,8 +7527,10 @@ #include "modular_darkpack\modules\npc\code\nonhuman\hostile\baali_guard.dm" #include "modular_darkpack\modules\npc\code\nonhuman\hostile\bear.dm" #include "modular_darkpack\modules\npc\code\nonhuman\hostile\werewolf.dm" -#include "modular_darkpack\modules\occult_artifacts\code\artifacts\_artifact.dm" -#include "modular_darkpack\modules\occult_artifacts\code\artifacts\_artifact_config.dm" +#include "modular_darkpack\modules\occult_artifacts\code\_artifact.dm" +#include "modular_darkpack\modules\occult_artifacts\code\_artifact_config.dm" +#include "modular_darkpack\modules\occult_artifacts\code\_vampire.dm" +#include "modular_darkpack\modules\occult_artifacts\code\_werewolf.dm" #include "modular_darkpack\modules\occult_artifacts\code\artifacts\bloodstar.dm" #include "modular_darkpack\modules\occult_artifacts\code\artifacts\bloodstone.dm" #include "modular_darkpack\modules\occult_artifacts\code\artifacts\daimonori.dm" @@ -7495,7 +7540,10 @@ #include "modular_darkpack\modules\occult_artifacts\code\artifacts\key_of_alamut.dm" #include "modular_darkpack\modules\occult_artifacts\code\artifacts\mummywrap_fetish.dm" #include "modular_darkpack\modules\occult_artifacts\code\artifacts\odious_chalice.dm" +#include "modular_darkpack\modules\occult_artifacts\code\artifacts\tarulfang.dm" #include "modular_darkpack\modules\occult_artifacts\code\artifacts\weekapaug_thistle.dm" +#include "modular_darkpack\modules\occult_artifacts\code\fetishes\dagger_of_retribution.dm" +#include "modular_darkpack\modules\occult_artifacts\code\fetishes\nyxs_bangle.dm" #include "modular_darkpack\modules\onfloor_icons\code\apply_onfloor_icon_element.dm" #include "modular_darkpack\modules\onfloor_icons\code\dynamic_item_icon.dm" #include "modular_darkpack\modules\onfloor_icons\code\gags_configs.dm" @@ -7831,6 +7879,7 @@ #include "modular_darkpack\modules\weapons\code\sheath.dm" #include "modular_darkpack\modules\weapons\code\stake.dm" #include "modular_darkpack\modules\weather\code\effects.dm" +#include "modular_darkpack\modules\werewolf_the_apocalypse\code\delirium.dm" #include "modular_darkpack\modules\werewolf_the_apocalypse\code\emotes.dm" #include "modular_darkpack\modules\werewolf_the_apocalypse\code\garou_languages.dm" #include "modular_darkpack\modules\werewolf_the_apocalypse\code\gauntlet.dm" diff --git a/tgui/bun.lock b/tgui/bun.lock index 6dd4971b730c..4e2a142f45b1 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/packages/tgfont/static/tgfont.css b/tgui/packages/tgfont/static/tgfont.css index 7b340f899b37..6bdf310a5025 100644 --- a/tgui/packages/tgfont/static/tgfont.css +++ b/tgui/packages/tgfont/static/tgfont.css @@ -14,6 +14,7 @@ } :root { + /* biome-ignore-start lint/suspicious/noUselessEscapeInString: The escapes are needed */ --tg-air-tank-slash: "\ea01"; --tg-air-tank: "\ea02"; --tg-bad-touch: "\ea03"; @@ -26,6 +27,7 @@ --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-panel/chat/constants.ts b/tgui/packages/tgui-panel/chat/constants.ts index f910853732b6..31d76f084b81 100644 --- a/tgui/packages/tgui-panel/chat/constants.ts +++ b/tgui/packages/tgui-panel/chat/constants.ts @@ -107,7 +107,7 @@ export const MESSAGE_TYPES: MessageType[] = [ description: 'The bluewall of global OOC messages', selector: '.ooc, .adminooc, .adminobserverooc, .oocplain', }, - // DARKPACK EDIT ADD START + // DARKPACK EDIT ADD START - LOOC { type: MESSAGE_TYPE_LOOC, name: 'LOOC', diff --git a/tgui/packages/tgui-panel/chat/renderer.tsx b/tgui/packages/tgui-panel/chat/renderer.tsx index 9e2fb95384e7..bee627b36ebb 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 5bc09bb73512..abc47fdd73b9 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/settings/scaling.ts b/tgui/packages/tgui-panel/settings/scaling.ts index bd1b52500128..77cc5f831bae 100644 --- a/tgui/packages/tgui-panel/settings/scaling.ts +++ b/tgui/packages/tgui-panel/settings/scaling.ts @@ -11,6 +11,7 @@ const ELEMENTS_TO_ADJUST = [ 'inputbuttons.saybutton', 'inputbuttons.mebutton', 'inputbuttons.oocbutton', + 'inputbuttons.whisperbutton', 'mapwindow.status_bar', ]; @@ -33,8 +34,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 e94aaf7be3ab..1bfd05800cba 100644 --- a/tgui/packages/tgui-panel/settings/themes.ts +++ b/tgui/packages/tgui-panel/settings/themes.ts @@ -68,6 +68,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 76bfb8a282a1..f5a3e6c61396 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 e85ad03be6dd..2d16613cb990 100644 --- a/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss +++ b/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss @@ -976,6 +976,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 8076e62204f8..7157bf329ea3 100644 --- a/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss +++ b/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss @@ -268,6 +268,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, @@ -980,6 +990,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 524a1c592e74..685c58386b2e 100644 --- a/tgui/packages/tgui-say/ChannelIterator.test.ts +++ b/tgui/packages/tgui-say/ChannelIterator.test.ts @@ -14,8 +14,9 @@ describe('ChannelIterator', () => { expect(channelIterator.next()).toBe('Radio'); expect(channelIterator.next()).toBe('Me'); expect(channelIterator.next()).toBe('Do'); // DARKPACK EDIT ADD - DO_EMOTES - expect(channelIterator.next()).toBe('LOOC'); // DARKPACK EDIT ADD expect(channelIterator.next()).toBe('OOC'); + expect(channelIterator.next()).toBe('LOOC'); // DARKPACK EDIT ADD - LOOC + 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 67d40d9b399f..d0548ce028aa 100644 --- a/tgui/packages/tgui-say/ChannelIterator.ts +++ b/tgui/packages/tgui-say/ChannelIterator.ts @@ -1,4 +1,4 @@ -export type Channel = 'Say' | 'Radio' | 'Me' | 'OOC' | 'Admin' | 'LOOC' | 'Do'; // DARKPACK EDIT CHANGE - ORIGINAL: export type Channel = 'Say' | 'Radio' | 'Me' | 'OOC' | 'Admin'; +export type Channel = 'Say' | 'Radio' | 'Me' | 'Do' | 'OOC' | 'LOOC' | 'Admin' | 'Pray'; // DARKPACK EDIT CHANGE - LOOC,DO_EMOTES /** * ### ChannelIterator @@ -8,9 +8,9 @@ export type Channel = 'Say' | 'Radio' | 'Me' | 'OOC' | 'Admin' | 'LOOC' | 'Do'; */ export class ChannelIterator { private index: number = 0; - private readonly channels: Channel[] = ['Say', 'Radio', 'Me', 'Do', 'LOOC', 'OOC', 'Admin']; // DARKPACK EDIT CHANGE - ORIGINAL: private readonly channels: Channel[] = ['Say', 'Radio', 'Me', 'OOC', 'Admin']; + private readonly channels: Channel[] = ['Say', 'Radio', 'Me', 'Do', 'OOC', 'LOOC', 'Admin', 'Pray']; // DARKPACK EDIT CHANGE - LOOC,DO_EMOTES private readonly blacklist: Channel[] = ['Admin']; - private readonly quiet: Channel[] = ['OOC', 'LOOC', 'Admin']; // DARKPACK EDIT CHANGE - ORIGINAL: private readonly quiet: Channel[] = ['OOC', 'Admin']; + private readonly quiet: Channel[] = ['OOC', 'LOOC', 'Admin', 'Pray']; // DARKPACK EDIT CHANGE - 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 45f81711e6d5..b11aa26b1c8b 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 f952f831ca0b..d1c7cf4caa57 100644 --- a/tgui/packages/tgui-say/styles/colors.scss +++ b/tgui/packages/tgui-say/styles/colors.scss @@ -29,6 +29,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 98a19e308b15..2885340059f4 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 3e45671520fd..622abff07aa1 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 000000000000..3264c9df34e8 --- /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)' + : ''} + + + - {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 241b9ebed866..b907e643f081 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) => {